⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 can_mcu.c

📁 单片机在CAN总线中的应用源代码
💻 C
字号:
/************关节五****************/
#include	<reg51.h>
#include	<absacc.h>

#define uchar unsigned char
#define uint unsigned int

#define	CANMOD	XBYTE[0x2000]/*	方式寄存器*/
#define	CANCMR	XBYTE[0x2001]/*	命令寄存器*/
#define	CANSR	XBYTE[0x2002]/*	状态寄存器*/
#define	CANIER	XBYTE[0x2003]/*	中断允许寄存器*/
#define	CANACR	XBYTE[0x2004]/*	接受代码寄存器*/
#define	CANAMR	XBYTE[0x2005]/*	接受屏蔽寄存器*/
#define	CANBTR0	XBYTE[0x2006]/*	BTR0,总线定时寄存器0*/
#define	CANBTR1	XBYTE[0x2007]/*	BTR1,总线定时寄存器1*/
#define	CANOCR	XBYTE[0x2008]/*	OCR,输出控制寄存器*/
#define	CANCDR	XBYTE[0x201F]/*	时钟分频*/

#define	CANSEN0	XBYTE[0x200A]/*	发送寄存器*/
#define	CANSEN1	XBYTE[0x200B]/*	发送寄存器*/
#define	CANSEN2	XBYTE[0x200C]/*	发送寄存器*/
#define	CANSEN3	XBYTE[0x200D]/*	发送寄存器*/
#define	CANSEN4	XBYTE[0x200E]/*	发送寄存器*/
#define	CANSEN5	XBYTE[0x200F]/*	发送寄存器*/
#define	CANSEN6	XBYTE[0x2010]/*	发送寄存器*/
#define	CANSEN7	XBYTE[0x2011]/*	发送寄存器*/
#define	CANSEN8	XBYTE[0x2012]/*	发送寄存器*/
#define	CANSEN9	XBYTE[0x2013]/*	发送寄存器*/

#define	CANREC0	XBYTE[0x2014]/*	接受寄存器0*/
#define	CANREC1	XBYTE[0x2015]/*	接受寄存器1*/
#define	CANREC2	XBYTE[0x2016]/*	接受寄存器2*/
#define	CANREC3	XBYTE[0x2017]/*	接受寄存器3*/
#define	CANREC4	XBYTE[0x2018]/*	接受寄存器4*/
#define	CANREC5	XBYTE[0x2019]/*	接受寄存器5*/
#define	CANREC6	XBYTE[0x201A]/*	接受寄存器6*/
#define	CANREC7	XBYTE[0x201B]/*	接受寄存器7*/
#define	CANREC8	XBYTE[0x201C]/*	接受寄存器8*/
#define	CANREC9	XBYTE[0x201D]/*	接受寄存器9*/

#define	ADSTART	    XBYTE[0x8000]
#define	ADCH		XBYTE[0x8000]
#define	ADCL		XBYTE[0x8001]

#define	DACH		XBYTE[0x4001]
#define	DACL		XBYTE[0x4000]
#define	DACSEND	    XBYTE[0x6000]

sbit	P1_1=P1^1;	/*SJA1000片选信号*/
bit		flag=0;	    /*设置标志位*/	

/*-----------------延时程序25us(24MHz)-------------------------*/
void DelayTime(unsigned int times)	
{
	unsigned int i=0;
	while(times--)
		{
		for(i=0;i<25;i++)	{;}	
		}
}
/*-----------------CAN初试化-------------------------*/
void CanIni()
{
	P1_1=0;			    /*片选信号,选择SJA1000芯片*/
	DelayTime(30);		/*复位延时*/
	P1_1=1;
	CANMOD=0x1;			/*进入复位模式,对SJA000进行初始化,接收中断和复位请求*/
	CANMOD=0x3;
	CANCDR=0x8;			/*选择BasicCAN模式,关闭时钟输出*/
	CANAMR=0xef;		/*11101111,接受屏蔽寄存器*/
	CANACR=0x10;		/*00010000,接受代码寄存器*/
	CANBTR0=0x03;		/*BTR0,总线定时寄存器0*/
	CANBTR1=0x1c;		/*BTR1,总线定时寄存器1*/
	CANOCR=0xaa;		/*OCR,输出控制寄存器*/
	CANMOD=0x02;		/*设置单滤波器接受方式,并返回工作状态*/
	CANCMR=0x0e;	
}


/*----------------外部中断0---------------------*/
void int0() interrupt 0 using 1
{	
	
		flag=(bit)(CANSR&0x01);
		
}

void main()
{	
	bit 		recsuc=0;/*接收成功标志*/
	bit 		shijiao=0;
	char 		states=4;/*工作状态:4--等待,1--复位,2---正常工作,3---示教*/
	uchar 	fankuiH,fankuiL,sendH,sendL;
	uint 		i,output,fankui; 
	char 		angel1,angel2,fankuiv1,fankuiv2;
	float  	middata,backdata,angel,fankuiv;

	IP=0x01;		/*置INT0为高优先级中断*/
	IE=0x81;		/*1000,0001,允许外部0中断*/
	CanIni();
	angel=0.0;
	angel1=1;
	angel2=5;
	recsuc=1;

	for(;;)
	{
		if(flag==1){
		EA=0;/*cpu关中断*/		
		do{;}while(CANSR&0x10);/*若正在接收数据则循环等待*/
		angel1=CANREC2;/*整数部分*/
		angel2=CANREC3;/*小数部分后两位*/
		states=CANREC4;		
		CANCMR=4;/*释放接受缓冲器*/
		flag=0;
		if(states==1)
			{	angel=0.0;
				angel1=1;
				angel2=1;
				recsuc=1;
				shijiao=0;
				EX0=0;
			 }
		if(states==2)
			{
				angel=(float)angel1+(float)angel2/100;/*将接受的数据赋给变量angel*/
				recsuc=1;
				shijiao=0;
				EX0=0;
			}
		if(states==3)
			{	shijiao=1;	
				angel1=1;
				angel2=1;
				recsuc=1;
				EX0=0;	
			}
		if(states==4)
			{
				recsuc=0;
				shijiao=0;
				EA=1;
				EX0=1;
				
			}				
		
		}/*if*/

		if(recsuc==1){
			EA=0;

			ADSTART=0;		
			DelayTime(40);
			 
			fankuiH=ADCH;/*高四位*/
			fankuiL=ADCL;/*低八位*/
			fankui=ADCH*0x100+ADCL;/*采集电位计的12位数据*/
			
			fankuiv=((float)(fankui))/19.5-(float)105.0;/*转换为角度值*/

			fankuiv1=(char)fankuiv;
			fankuiv2=(char)(((int)(fankuiv*100))%100);
		
			if(!shijiao){
			middata=angel-fankuiv;
			backdata=middata*0.2;/*调用pid算法*/
			if(backdata>=1)
				backdata=2;
			else
				if(backdata<=-1)
					backdata=-2;
			output=(int)((backdata+5)*409.6);/*由0~10v电压转换为12位16进制数*/
			if(output>=4095)
				output=4095;
		
			sendL=output&0xf;/*取低4位*/
			sendL=sendL*0x10;/*低四位左移四位*/
			sendH=output>>4;/*取高八位*/
			/****************DA输出*****************/
			DACH=sendH;	
			DACL=sendL;
			DACSEND=0;
			}/***	if(!shijiao)***/
		
			
			/****************发送数据到上位机******************/

			CANSEN0=0x01;/*id=8*/		
			CANSEN1=0xa8;/*length=8*/
			CANSEN2=angel1;/*从上位机接收的角度值整数部分,对应smsg.data[0],rmsg.data[0]*/	
			CANSEN3=angel2;/*小数部分*/
			CANSEN4=fankuiv1;/*电位计角度值整数部分*/	
			CANSEN5=fankuiv2;/*小数部分两位*/
			CANSEN6=fankuiH;/*电位计高四位*/
			CANSEN7=fankuiL;/*电位计低八位*/	
			CANSEN8=(char)middata;	
			CANSEN9=(char)states;

			CANCMR=1;
			if((middata>=-6)&(middata<=6)){EA=1;EX0=1;}

		}/*if(recsuc==1)*/

	}/*for*/

}/*main*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -