《基于51单片机的CAN通讯协议C语言程序.docx》由会员分享,可在线阅读,更多相关《基于51单片机的CAN通讯协议C语言程序.docx(24页珍藏版)》请在三一办公上搜索。
1、基于51单片机的CAN通讯协议C语言程序/-函数声明,变量定义- #include <reg52.h> sbit int0 = P32; /-定义寻址的基址- #define base_Adr 0x00 /-定义总线定时寄存器的值- #define SJA_BTR0 0x00 /该值需要用户根据实际需要的波特率进行计算 #define SJA_BTR1 0x16 /具体计算见文章说明 /-设置接收报文类型- /该值需要用户根据实际需要重新配置 #define SJA_ACR 0x00 /验收代码寄存器的值 #define SJA_AMR 0x16 /验收屏蔽寄存器的值 /-设置输出始终
2、类型- /该值需要用户根据实际需要重新配置 #define SJA_OCR 0x00 /输出控制寄存器的值 #define SJA_CDR 0x16 /始终分频寄存器的值 /-设置SJA中断,1为开中断- #define SJA_OIE 0 /溢出中断 #define SJA_EIE 0 /错误中断 #define SJA_TIE 0 /发送中断 #define SJA_RIE 0 /接收中断 /-定义地址指针,指向基址- unsigned char xdata *SJA_base_Adr = base_Adr; /-定义硬件故障标志位- bit bdata connect_OK=0; /co
3、nnect_OK=1设备连接正常 /connect_OK=0设备连接故障 /-定义硬件故障标志位- bit bdata SJA_workmode=1; /SJA_workmode=1SJA工作在工作模式 /SJA_workmode=0工作在复位模式 /-定义SJA1000读写缓冲区的数据结构- struct BASICCAN_BUFstruct unsigned char FrameID_H; unsigned char FrameLENTH ; unsigned char FrameKIND ; unsigned char FrameID_L3 ; unsigned char Frame_D
4、ata8; BASICCAN_FRAME,receive_BUF,send_BUF; /BASICCAN_BUFstruct send_BUF; /- / 函数类别 SJA1000基本操作 / 函数名称 CANREG_write / 入口函数 SJAREG_ADR,setting / 出口函数 无 / 函数功能 写SJA1000的寄存器 /- void CANREG_write(unsigned char SJAREG_ADR, unsigned char setting) *(SJA_base_Adr+SJAREG_ADR)=setting; /- / 函数类别 SJA1000基本操作 /
5、函数名称 CANREG_write / 入口函数 SJAREG_ADR / 出口函数 SJAREG_data / 函数功能 读SJA1000的寄存器 /- unsigned char CANREG_read(unsigned char SJAREG_ADR) unsigned char SJAREG_data; SJAREG_data=*(SJA_base_Adr+SJAREG_ADR); return(SJAREG_data); /- / 函数类别 SJA1000基本操作 / 函数名称 SJAconnect_judge / 入口函数 无 / 出口函数 无 / 全局变量 connect_OK
6、/ 操作寄存器 测试寄存器 / 函数功能 判断SJA1000与控制器连接是否正常 /- void SJAconnect_judge(void) CANREG_write(0x09,0xAA); /写AA到测试寄存器 if(CANREG_read(0x09)=0xAA) connect_OK=1; /连接正常 else connect_OK=0; /连接故障 /- / 函数类别 SJA1000基本操作 / 函数名称 setting_SJA_resetmode / 入口函数 无 / 出口函数 无 / 全局变量 SJA_workmode / 操作寄存器 控制寄存器 / 函数功能 设置SJA工作在复位
7、模式 /- void setting_SJA_resetmode(void) unsigned char CONTROL_REGdata; CONTROL_REGdata=CANREG_read(0x00); CONTROL_REGdata=CONTROL_REGdata|0x01; CANREG_write(0x00,CONTROL_REGdata); if(CANREG_read(0x00)&0x01)=1) SJA_workmode=0; /置复位模式成功 else SJA_workmode=1; /置复位模式失败 /- / 函数类别 SJA1000基本操作 / 函数名称 setting
8、_SJA_resetmode / 入口函数 无 / 出口函数 无 / 全局变量 SJA_workmode / 操作寄存器 控制寄存器 / 函数功能 设置SJA工作在正常工作模式 /- void setting_SJA_workingmode(void) unsigned char CONTROL_REGdata; CONTROL_REGdata=CANREG_read(0x00); CONTROL_REGdata=CONTROL_REGdata&0xFE; CANREG_write(0x00,CONTROL_REGdata); if(CANREG_read(0x00)&0x01)=0) SJA
9、_workmode=1; /置工作模式成功 else SJA_workmode=0; /置工作模式失败 /- / 函数类别 SJA1000基本操作 / 函数名称 setting_SJA_rate / 入口函数 SJA_BTR0,SJA_BTR1 / 出口函数 setting_success / 操作寄存器 总线定时寄存器BTR1和BTR0 / 函数功能 设置SJA波特率 / 特殊要求 只能在复位工作模式下设置 /- bit setting_SJA_rate(void) bit setting_success; while(SJA_workmode) setting_SJA_resetmode;
10、 /设置SJA工作在复位模式 CANREG_write(0x06,SJA_BTR0); CANREG_write(0x07,SJA_BTR1); if(CANREG_read(0x06)=SJA_BTR0)&(CANREG_read(0x07)=SJA_BTR1) setting_success=1; /波特率设置成功 else setting_success=0; /波特率设置失败 return(setting_success); /- / 函数类别 SJA1000基本操作 / 函数名称 setting_SJA_dataselect / 入口函数 SJA_ACR,SJA_AMR / 出口函数
11、 setting_success / 操作寄存器 验收代码寄存器ACR和验收屏蔽寄存器AMR / 函数功能 设置SJA接收数据类型 / 特殊要求 只能在复位工作模式下设置 /- bit setting_SJA_dataselect(void) bit setting_success; while(SJA_workmode) setting_SJA_resetmode; /设置SJA工作在复位模式 CANREG_write(0x04,SJA_ACR); CANREG_write(0x05,SJA_AMR); if(CANREG_read(0x04)=SJA_ACR)&(CANREG_read(0
12、x05)=SJA_AMR) setting_success=1; /滤波器设置成功 else setting_success=0; /滤波器设置失败 return(setting_success); /- / 函数类别 SJA1000基本操作 / 函数名称 setting_SJA_CLK / 入口函数 SJA_OCR,SJA_CDR / 出口函数 setting_success / 操作寄存器 输出控制寄存器OCR和时钟分频寄存器CDR / 函数功能 设置SJA输出始终类型 / 特殊要求 只能在复位工作模式下设置 /- bit setting_SJA_CLK(void) bit setting
13、_success; while(SJA_workmode) setting_SJA_resetmode; /设置SJA工作在复位模式 CANREG_write(0x08,SJA_OCR); CANREG_write(31,SJA_CDR); if(CANREG_read(0x08)=SJA_OCR)&(CANREG_read(31)=SJA_CDR) setting_success=1; /滤波器设置成功 else setting_success=0; /滤波器设置失败 return(setting_success); /- / 函数类别 SJA1000基本操作 / 函数名称 setting_
14、SJA_interrupt / 入口函数 SJA_OIE,SJA_EIE,SJA_TIE,SJA_RIE / 出口函数 setting_success / 操作寄存器 控制寄存器 / 函数功能 设置SJA中断类型和中断状态 / 特殊要求 只能在复位工作模式下设置 /- bit setting_SJA_interrupt(void) bit setting_success; unsigned char CONT_buf,temp=0; while(SJA_workmode) setting_SJA_resetmode; /设置SJA工作在复位模式 CONT_buf=CANREG_read(0x0
15、0); temp=SJA_OIE; temp=temp<<4; temp=temp|SJA_EIE; temp=temp<<3; temp=temp|SJA_TIE; temp=temp<<2; temp=temp|SJA_RIE; temp=temp<<1; CONT_buf=(temp&0x1E)|(CONT_buf&0x01); CANREG_write(0x00,CONT_buf); if(CANREG_read(0x00)=CONT_buf) setting_success=1; /滤波器设置成功 else setting_success=0; /滤波
16、器设置失败 return(setting_success); /- / 函数类别 SJA1000基本操作 / 函数名称 Write_SJAsendBUF / 入口函数 无 / 出口函数 setting_success / 操作寄存器 发送缓存器状态寄存器02 / 函数功能 写发送缓存器 / 特殊要求 只能在工作模式下写 /- bit Write_SJAsendBUF(void) bit setting_success=0; unsigned char i; while(SJA_workmode=0) setting_SJA_workingmode; /设置SJA在工作模式 if(CANREG_
17、read(0x02)&0x10)=0) if(CANREG_read(0x02)&0x04)!=0) CANREG_write(0x10,send_BUF.FrameID_H); CANREG_write(0x11,(send_BUF.FrameLENTH<<4)|(send_BUF.FrameKIND<<3)|(send_BUF.FrameID_L3); if(send_BUF.FrameKIND=0) for(i=0;i<send_BUF.FrameLENTH,i<8;i+) CANREG_write(0x12+i,send_BUF.Frame_Datai); se
18、tting_success=1; /发送寄存器写成功 return(setting_success); /- / 函数类别 SJA1000基本操作 / 函数名称 Write_SJAsendBUF / 入口函数 无 / 出口函数 setting_success / 操作寄存器 接收缓存器状态寄存器02 / 函数功能 写发送缓存器 / 特殊要求 只能在工作模式下写 /- bit read_SJAreceiveBUF(void) bit setting_success=0; unsigned char i; while(SJA_workmode=0) setting_SJA_workingmode;
19、 /设置SJA在工作模式 if(CANREG_read(0x02)&0x01)!=0) if(CANREG_read(0x02)&0x10)=0) receive_BUF.FrameID_H=CANREG_read(0x20); receive_BUF.FrameLENTH=(CANREG_read(0x21)&0xF0)>>4); receive_BUF.FrameKIND=(CANREG_read(0x21)&0x08)>>3); receive_BUF.FrameID_L3=(CANREG_read(0x21)&0x07); if(receive_BUF.FrameKIN
20、D=0) for(i=0;i<receive_BUF.FrameLENTH,i<8;i+) receive_BUF.Frame_Datai=CANREG_read(0x22+i); setting_success=1; /接收寄存器读成功 return(setting_success); /- / 函数类别 供调用子程序 / 函数名称 SJA1000_init / 入口函数 无 / 出口函数 无 / 操作寄存器 1)控制寄存器 / 2)收代码寄存器ACR / 3)验收屏蔽寄存器AMR / 4)总线定时寄存器BTR0 / 5)总线定时寄存器BTR1 / 6)输出控制寄存器OCR / 7)
21、测试寄存器和时钟分频寄存器CDR / 函数功能 SJA1000初始化设置 / 特殊要求 在复位模式进行,初始化结束进入工作状态 /- void SJA1000_init(void) while(connect_OK=0) SJAconnect_judge; /检测设备连接 while(SJA_workmode) setting_SJA_resetmode; /置SJA1000为复位工作模式 while(setting_SJA_rate=0) setting_SJA_rate; /设置总线波特率 while(setting_SJA_dataselect=0) setting_SJA_datase
22、lect; /设置SJA接收数据的格式 while(setting_SJA_CLK=0) setting_SJA_CLK; /设置SJA输出始终的形式 /- / 函数类别 中断处理函数 / 函数名称 send_interrupt / 入口函数 无 / 出口函数 无 / 操作寄存器 / 函数功能 接收中断处理函数 /- send_interrupt /- / 函数类别 发送中断处理函数 / 函数名称 receive_interrupt / 入口函数 / 出口函数 / 操作寄存器 / 函数功能 发送中断处理函数 /- receive_interrupt /- / 函数类别 中断函数 / 函数名称
23、SJA_INTR / 入口函数 无 / 出口函数 无 / 操作寄存器 中断寄存器 / 函数功能 中断分析,判断是什么中断,调用相应的中断处理函数 /- void SJA_INTR interrupt 0 using 1 /CanBus接口芯片产生中断(INTR0) unsigned char sta; unsigned char temp; EX0 = 0; sta = CANREG_read(3); /读中断寄存器 temp = sta & 0x20; if(temp = 0x20) SJA1000_init; temp = sta & 0x04; if(temp = 0x04) SJA1000_init; /消极错误中断,错误报警中断,均导致重启 temp = sta & 0x02; if(temp = 0x02) /发送中断处理 send_interrupt; temp = sta & 0x01; if(temp = 0x01) /接收中断,接收数据 receive_interrupt; EX0 = 1; main 本程序是基于51单片机的CAN(sja1000)通信协议的操作程序,利用51单片机的中断来操作,每个函数都有详细的注释,希望能帮助到初学者,在main函数中没有任何函数调用,自己可以根据需要进行调用。