您好,欢迎访问三七文档
//------------------------------------------------------//CAN==UART的协议转换器////程序名称:CAN---UART协议转换程序透明方式////作者:王猛//创建:2007-10-09////说明://1,单片机使用P89C61X2BA//--晶振11.0592MHZ//--CAN总线中断使用单片机的中断0,外部有上拉电阻,波特率可以设定//2,CAN总线发送采用查询方式,接收采用中断方式//3,看门狗复位时间1.2S//4,SJA1000晶振8MHZ,Peil模式//5,串口中断接收,查询发送,波特率可设置//6,×××当串口收到数据后,每8个数一组打包,通过CAN总线发送出去////-----10.16日,重新修改程序完成以下功能-----//----此功能已经改为,每收到一帧数据,启动一次CAN传输,传输字节数等于串口收到的数据//----串行帧的帧间界定通过当前波特率下传输5个字节为时间间隔,具体为当顺序接收到的任//意两个数据,它们之间的时间间隔大于5个字节传送时间,认为这两个数据分属于两个不//同的帧////7,当CAN总线每接收一帧信息后,通过串口发送出去//-----10.15日,改为可以识别CAN的报文字节长度,即串口只发送CAN报文长度个字节//8,看门狗芯片MAX1232CPA,硬件溢出时间1.2S////-------------------------------------------------------#include#include#include#includeCANCOM.h//unsignedcharUART_TX_Data[8]={0,1,2,3,4,5,6,7};//unsignedcharCAN_TX_Data[8]={0,1,2,3,4,5,6,7};unsignedcharxdataUART_RX_Data[255];//串口接收到的串行帧unsignedcharxdataCAN_TX_Data[255];//待发送的数据缓冲区unsignedcharcodeACR_ID[4]={0,0,0,0};//CAN初始设置验收滤波值unsignedcharcodeAMR_ID[4]={0xff,0xff,0xff,0xff};unsignedcharCAN_TX_ID[4]={0,0,0,0};//待发送的目标的IDunsignedcharCAN_RX_ID[4]={0,0,0,0};//接收到的信息来自何IDunsignedcharCAN_RX_Data[8]={7,6,5,4,3,2,1,0};//接受到的数据缓冲unsignedcharcodeCAN_BTR0[10]={0xdf,0xcf,0xc7,0xc3,0x43,0xc1,0xc1,0xc0,0xc0,0x80};unsignedcharcodeCAN_BTR1[10]={0x7f,0x7f,0x7f,0x7f,0x2f,0x7f,0x4d,0x3e,0x3a,0x23};//5K10K20K40K50K80K100K200K250K500KunsignedcharcodeUART_BTR[4]={0xe8,0xf4,0xfa};//1.2K,2.4K,4.8KunsignedcharCAN_flag;//CAN发送标志位unsignedcharUART_flag;//unsignedcharCAN_ERROR_flag=NOT;//unsignedcharCAN_DataLength=8;//CAN信息的报文长度unsignedcharUART_DataLength=0;//串口接收时的当前指示unsignedcharUART_Length=0;//串口接收区的长度指示//sbitAAA=P1^4;voidmain(void){EA=0;System_init();//系统初始化Timer_init();//定时器初始化Interrupt_init();//中断UART_ini();CAN_init();Delay(1);W_WDT();EA=1;//Delay(1);//UART_Length=8;//CAN_Transmit(0);//UART_Transmit();while(1){W_WDT();if(CAN_flag==YES){CAN_flag=NOT;CAN_Transmit(0);LED1=!LED1;}else{CAN_flag=NOT;}/*if(UART_flag==YES){UART_flag=NOT;//Delay(50);UART_Transmit();//Clear_Buffer(CAN_RX_Data,8);//LED3=!LED3;}else{UART_flag=NOT;}*/if((CAN_ERROR_flag==YES)){CAN_ERROR_flag=NOT;CAN_init();}else{CAN_ERROR_flag=NOT;}}}//---------------------------//功能:系统设置//--外部数据存储区访问使能//--LED指示灯关(1=on,0=off)//--流程控制标志置为无效NOT//--清空串口,CAN的相关数据缓冲区//---------------------------voidSystem_init(void){CKCON=0x00;//Foscdevide12AUXR=0x00;//0x02;//EXMenableLED1=0;//LED0-3off指示灯,共阴接法,1时亮LED2=0;LED3=0;LED4=0;WDT=1;//WDTiniCAN_DataLength=8;UART_DataLength=0;UART_Length=0;CAN_flag=NOT;CAN_ERROR_flag=NOT;//UART_flag=NOT;Clear_Buffer(UART_RX_Data,255);Clear_Buffer(CAN_TX_Data,255);Clear_Buffer(CAN_TX_ID,4);Clear_Buffer(CAN_RX_ID,4);Clear_Buffer(CAN_RX_Data,8);/*CAN_flag=YES;UART_flag=YES;*/}//-----------------------------////软件延时(非精确)//----内置清看门狗定时器子函数//防止多次调用延时过长导致//看门狗复位////-----------------------------voidDelay(unsignedchartime){unsignedchari;unsignedintj;for(i=0;itime;i++){W_WDT();for(j=0;j30000;j++){}}}//---------------------------------//串行口初始化设置//方式1,8数据位,一个停止位,无奇偶校验//串口中断允许//------------------------------------voidUART_ini(void){SCON=0x50;//方式1,波特率可变,8bits,接受允许PCON&=0x7F;//SMOD=0TMOD|=0x20;//timer1mode2TL1=UART_BTR[2];//|f//|波特率=----------------------TH1=UART_BTR[2];//|32*2^smod*12*(256-TL1)TCON|=0x40;//startTI=0;}//-----------------------------------------------////看门狗“喂狗”程序,WDT的一个下降沿触发一次////-----------------------------------------------voidW_WDT(void)//triggleWDT{unsignedchari;WDT=1;for(i=0;i10;i++){}WDT=0;}//---------------------------------------------------////中断初始化////----外部中断0有效,下降沿触发,用于SJA1000产生CAN事件中断//----定时器中断,用于判定串口接收的顺序两个字节是否分属两帧//----串口中断,RX使用中断,TX未使用//----中断优先级暂时未设定////---------------------------------------------------voidInterrupt_init(void){//IP=0x00;IT0=0x01;//外部0中断沿触发ET0=1;//定时器0中断使能EX0=1;//外部中断使能ES=1;//串行中断使能}//---------------------------------------------------////定时中断程序////一旦中断,说明一帧的接收已经结束,开始启动CAN发送程序//把串口接收到的数据准备好给CAN总线发送//RX_buffer===CAN_TX_buffer////---------------------------------------------------voidTimer0_ISR(void)interrupt1using2{staticunsignedchari;//unsignedcharcounter;//TH0=temp_TH0;//TL0=temp_TL0;/*counter+=1;if(counter==20)//到1S了么?{//UART_flag=YES;}if(counter==40)//到2S了么?{//CAN_flag=YES;counter=0;}*///AAA=!AAA;TR0=0;//定时器关,开始次CAN信息传送for(i=0;i{CAN_TX_Data[i]=UART_RX_Data[i];}UART_Length=UART_DataLength;UART_DataLength=0;CAN_flag=YES;}//---------------------------------------------------------------////串口中断服务程序////----只有接收使用//----每收一个数重新初始化定时器////----------------------------------------------------------------voidRX_INT(void)interrupt4using3{staticunsignedcharn;if(RI==1){do{RI=0;}while(RI!=0);//UART_RX_Data[UART_DataLength++]=SBUF;n=SBUF;UART_Send_Byte(n);TH0=temp_TH0;TL0=temp_TL0;TR0=1;//启动数据间隔定时,判断是否分属两帧}else{//TX}}//---------------------------------------------------------------////串口发送单字节程序////----------------------------------------------------------------voidUART_Send_Byte(unsignedcharData){SBUF=Data;while(TI==0)//等待发送完毕{}TI=0;}//---------------------------------------------------------------////初始化定时器程序////----定时器0方式1,
本文标题:CAN总线通信程序
链接地址:https://www.777doc.com/doc-5073768 .html