can总线通信程序_第1页
can总线通信程序_第2页
can总线通信程序_第3页
can总线通信程序_第4页
can总线通信程序_第5页
已阅读5页,还剩16页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、CAN总线通信程序/  CAN <=> UART的协议转换器/  说明:/  1,单片机使用P89C61X2BA /   -晶振11.0592MHZ                            &#

2、160;                                                  &

3、#160; /   -CAN总线中断使用单片机的中断0,外部有上拉电阻,波特率可以设定/  2,CAN总线发送采用查询方式,接收采用中断方式/  3,看门狗复位时间1.2S/  4,SJA1000晶振8MHZ,Peil模式/  5,串口中断接收,查询发送,波特率可设置/  6,×××当串口收到数据后,每8个数一组打包,通过CAN总线发送出去/   -10.16日,重新修改程序完成以下功能-

4、0;  /    -此功能已经改为,每收到一帧数据,启动一次CAN传输,传输字节数等于串口收到的数据/    -串行帧的帧间界定通过当前波特率下传输5个字节为时间间隔,具体为当顺序接收到的任意两个数据,它们之间的时间间隔大于5个字节传送时间,认为这两个数据分属于两个不 同的帧/  7,当CAN总线每接收一帧信息后,通过串口发送出去/ 改为可以识别CAN的报文字节长度,即串口只发送CAN报文长度个字节/  8,看门狗芯片MAX1232CP

5、A,硬件溢出时间1.2S/  /-#include #include #include #include "CANCOM.h"unsigned char UART_TX_Data8 = 0,1,2,3,4,5,6,7;unsigned char CAN_TX_Data8 = 0,1,2,3,4,5,6,7;     unsigned char xdata UART_RX_Data255;       

6、60;/串口接收到的串行帧unsigned char xdata CAN_TX_Data255;        /待发送的数据缓冲区unsigned char code ACR_ID4 = 0,0,0,0;       /CAN初始设置验收滤波值unsigned char code AMR_ID4 = 0xff,0xff,0xff,0xff;unsigned char CAN_TX_ID4 = 0,0,0,0;   

7、     /待发送的目标的IDunsigned char CAN_RX_ID4 = 0,0,0,0;        /接收到的信息来自何IDunsigned char CAN_RX_Data8 = 7,6,5,4,3,2,1,0;     /接受到的数据缓冲unsigned char code CAN_BTR010 =0xdf,0xcf,0xc7,0xc3,0x43,0xc1,0xc1,0xc0,0xc0,0x80;

8、  unsigned char code CAN_BTR110 = 0x7f,0x7f,0x7f,0x7f,0x2f,0x7f,0x4d,0x3e,0x3a,0x23;/         5K  10K  20K  40K  50K  80K  100K 200K 250K 500Kunsigned char code UART_BTR4 = 0xe8,0xf4,0xfa;   / &#

9、160;        1.2K,2.4K,4.8Kunsigned char CAN_flag;      /CAN发送标志位unsigned char UART_flag;     /unsigned char CAN_ERROR_flag = NOT;   /unsigned char CAN_DataLength = 8;    /CAN信

10、息的报文长度unsigned char UART_DataLength = 0;   /串口接收时的当前指示  unsigned char UART_Length = 0;    /串口接收区的长度指示/sbit AAA = P14;void main(void) EA = 0;      System_init();   /系统初始化 Timer_init();   

11、;/定时器初始化 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)   

12、60; CAN_flag = NOT;   CAN_Transmit(0);   LED1 = !LED1;    else     CAN_flag = NOT;  /*  if (UART_flag = YES)     UART_flag = NOT;   /Delay(50);   

13、;UART_Transmit();   /Clear_Buffer(CAN_RX_Data,8);   /LED3 = !LED3;    else     UART_flag = NOT;   */  if (CAN_ERROR_flag = YES)     CAN_ERROR_flag = NOT;   CAN_

14、init();    else     CAN_ERROR_flag = NOT;   /-/ 功能:系统设置/   -外部数据存储区访问使能/   -LED指示灯关(1on,0off)/   -流程控制标志置为无效NOT/   -清空串口,CAN的相关数据缓冲区/-void System_init(void) CKCON = 0x00;

15、   /Fosc devide 12 AUXR  = 0x00;/0x02;   /EXM enable LED1 = 0;    /LED0-3 off  指示灯,共阴接法,1时亮 LED2 = 0; LED3 = 0; LED4 = 0; WDT = 1;    /WDT ini  CAN_DataLength = 8;  

16、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(C

17、AN_RX_Data,8);  /* CAN_flag = YES; UART_flag = YES; */-/  软件延时(非精确)/   -内置清看门狗定时器子函数/    防止多次调用延时过长导致/    看门狗复位/-void Delay(unsigned char time) unsigned char i; unsigned int j;  for (i = 0;i

18、 < time;i+)   W_WDT();  for (j=0;j<30000;j+)     /-/ 串行口初始化设置/ 方式1,8数据位,一个停止位,无奇偶校验/ 串口中断允许/-void UART_ini(void) SCON = 0x50;  /方式1,波特率可变,8bits,接受允许  PCON&= 0x7F;  /SMOD = 0   

19、;                         TMOD |= 0x20;  /timer1 mode 2                  &#

20、160;     TL1 = UART_BTR2; /|     f                     /| 波特率-     TH1 = UART_BTR2; /|   3

21、2*2smod*12*(256-TL1)    TCON |= 0x40;  /start                                     

22、60;                                                 

23、60;                                                 

24、60;      TI = 0;                                          &#

25、160;   /-/ 看门狗“喂狗”程序,WDT的一个下降沿触发一次/-void W_WDT(void)   /triggle WDT unsigned char i; WDT = 1; for (i=0;i<10;i+)   WDT = 0;/-/ 中断初始化/  /  -外部中断0有效,下降沿触发,用于SJA1000产生CAN事件中断/  -定时器中断,用于判定串口接收的顺序两个字节是否

26、分属两帧/  -串口中断,RX使用中断,TX未使用/  -中断优先级暂时未设定/-void Interrupt_init(void) /IP = 0x00;      IT0 = 0x01;      /外部0中断沿触发  ET0 = 1;      /定时器0中断使能 EX0 = 1;     &

27、#160;/外部中断使能 ES = 1;                /串行中断使能/-/ 定时中断程序 /  /  一旦中断,说明一帧的接收已经结束,开始启动CAN发送程序/  把串口接收到的数据准备好给CAN总线发送/  RX_buffer => CAN_TX_buffer/-void Timer0_ISR(void) int

28、errupt 1 using 2 static unsigned char i; /unsigned char counter; /TH0 = temp_TH0; /TL0 = temp_TL0; /*counter += 1; if (counter = 20)    /到1S了么?   /UART_flag = YES;  if (counter = 40)    /到2S了么?  

29、 /CAN_flag = YES;  counter = 0; */ /AAA = !AAA; TR0  = 0;      /定时器关,开始次CAN信息传送 for (i=0;i   CAN_TX_Datai = UART_RX_Datai;  UART_Length = UART_DataLength; UART_DataLength = 0; CAN_flag = YES;/-/&

30、#160; 串口中断服务程序/  -只有接收使用   /  -每收一个数重新初始化定时器/-void RX_INT(void) interrupt 4 using 3 static unsigned char  n;  if (RI=1)   do     RI = 0;    while (RI != 0);  /UART_RX_Dat

31、aUART_DataLength+ = SBUF;  n = SBUF;  UART_Send_Byte(n);    TH0 = temp_TH0;    TL0 = temp_TL0;  TR0  = 1;       /启动数据间隔定时,判断是否分属两帧  else   /TX /-/  串口

32、发送单字节程序/-void UART_Send_Byte(unsigned char Data)     SBUF = Data;  while (TI = 0)     /等待发送完毕   TI = 0; /-/  初始化定时器程序/  -定时器0方式1,定时器1方式2留给串口/-void Timer_init(void) TMOD |= 0x01;   

33、  /使用定时器0方式1  TH0 = temp_TH0; TL0 = temp_TL0; /TR0  = 1;      /这里不打开定时器void CAN_init(void)  EA = 0; MOD_CAN1 |= 0x08;     /单滤波方式 do   MOD_CAN1 |= 0x01;    

34、           /request to reset mode  while (MOD_CAN1&0x01) != 0x01);  CDR_CAN1 = 0xc8;     /选择PeliCAN模式,使用输入比较器,clk_out关闭 IER_CAN1 = 0x01;     /允许发送中断,其他中断禁能 ACR0_CAN1

35、= ACR_ID0; ACR1_CAN1 = ACR_ID1; ACR2_CAN1 = ACR_ID2; ACR3_CAN1 = ACR_ID3; AMR0_CAN1 = AMR_ID0; AMR1_CAN1 = AMR_ID1; AMR2_CAN1 = AMR_ID2; AMR3_CAN1 = AMR_ID3; /ECC_CAN1 = 0; /TXERR_CAN1 = 0; /RBSA_CAN1 = 0; BTR0_CAN1 = CAN_BTR00;   

36、; BTR1_CAN1 = CAN_BTR10; OCR_CAN1 = 0xaa;     /normal output W_WDT(); do   MOD_CAN1 &= 0xfe;  while (MOD_CAN1&0x01) != 0x00); EA = 1;/-/  串口发送一帧接受到的CAN数据/   /   -长度18,根据接收到的CAN信

37、息来确定/-void UART_Transmit(void) /using 0 unsigned char i;  LED3 = !LED3; for (i=0;i   UART_Send_Byte(CAN_RX_Datai); /-/  CAN发送接受到的一帧串口数据/   /   -最大长度255,根据接收到的串口信息的/    个数来确定/   -按每依次8个数

38、据作为一个CAN帧的报文部分/    不足8个或超过8的倍数的部分按实际个数作/    为CAN报文/   -FarmeType = 1为扩展帧,FarmeType = 0为/    标准帧/-void CAN_Transmit(bit FarmeType) unsigned char i; unsigned char m; unsigned char can_status; unsigned char x

39、data *pointer;      if (FarmeType = 0)   /标准帧   for (m=0;m<(UART_Length/8);m+)     W_WDT();   do         /发送缓冲区空么?      &#

40、160;can_status = SR_CAN1;      while (can_status&0x04) != 0x04);      TXFrameInfo1 = 0x00 + 0x08;   pointer = &TXID1;   for (i=0;i<2;i+)       *(pointer+) = CAN_TX_

41、IDi;      pointer = &TXID3;    for (i=0;i<8;i+)       *(pointer+) = CAN_TX_Datai+8*m;      CMR_CAN1 = Request_TX;   W_WDT();      if

42、(UART_Length%8) != 0)     W_WDT();   do          /发送缓冲区空么?       can_status = SR_CAN1;      while (can_status&0x04) != 0x04);   TXF

43、rameInfo1 = 0x00 + UART_Length%8;   pointer = &TXID1;   for (i=0;i<2;i+)       *(pointer+) = CAN_TX_IDi;      pointer = &TXID3;    for (i=0;i<(UART_Length%8);i+) 

44、0;     *(pointer+) = CAN_TX_Datai+8*(UART_Length/8);      CMR_CAN1 = Request_TX;   W_WDT();    else      else        /扩展帧   &

45、#160;for (m=0;m<(UART_Length/8);m+)     W_WDT();                                     &#

46、160;               do         /发送缓冲区空么?                       

47、60;                                            can_status = SR_CAN1;  

48、                                                  

49、                                            while (can_status&0x04) != 0x04)

50、;                          TXFrameInfo1 = 0x80 + 0x08;   pointer = &TXID1;   for (i=0;i<4;i+)      

51、0;*(pointer+) = CAN_TX_IDi;      pointer = &TXDATA1;     for (i=0;i<8;i+)       *(pointer+) = CAN_TX_Datai+8*m;      CMR_CAN1 = Request_TX;   W_WDT(); &#

52、160;    if (UART_Length%8) != 0)     W_WDT();   do         /发送缓冲区空么?       can_status = SR_CAN1;      while (can_status&0x04)

53、!= 0x04);   TXFrameInfo1 = 0x80 + UART_Length%8;   pointer = &TXID1;   for (i=0;i<4;i+)       *(pointer+) = CAN_TX_IDi;      pointer = &TXDATA1;     for (

54、i=0;i<(UART_Length%8);i+)       *(pointer+) = CAN_TX_Datai+8*(UART_Length/8);      CMR_CAN1 = Request_TX;   W_WDT();    else       UART_Length = 0;/-/  

55、CAN接收中断服务程序/   /   -判断是否是RX中断,如果是/    把接受到的CAN信息通过串行口发送出去/   -其他的中断说明CAN总线出现错误或脱离/    /-void CAN_ISR(void) interrupt 0 using 1 unsigned char can_int; EA = 0; can_int = IR_CAN1; if (can_int&0x

56、01) = 0x01)   /接收中断   CAN_Receive();  CMR_CAN1 |= ReleaseRXBuf;  else   CAN_ERROR_flag = YES;   /其他中断,暂时未用  /UART_flag = YES; /CAN_flag = YES; UART_Transmit(); EA = 1;/-/  CAN接收数据函数/

57、60;  /   -根据接受到的帧信息,按不同的长度存储/    报文数据/    /-            void CAN_Receive(void) using 1 unsigned char i; unsigned char xdata *pointer; unsigned char Info; I

58、nfo = RXFrameInfo1; if (Info&0x80) = 0)   /standard Frame   /CAN_RX_ID0 = RXID1;    /CAN_RX_ID1 = RXID2;  CAN_DataLength = Info&0x0f;  pointer = &RXID3;  for (i=0;i     CAN_RX_Da

59、tai = *(pointer+);    for (;i<8;i+)     CAN_RX_Datai = 0x00;     else       /Ex  Frame   /CAN_RX_ID0 = RXID1;    /CAN_RX_ID1 = RXID2;  /CAN_RX

60、_ID2 = RXID3;    /CAN_RX_ID3 = RXID4;  CAN_DataLength = Info&0x0f;  pointer = &RXDATA1;  for (i=0;i     CAN_RX_Datai = *(pointer+);   /pointer += 1;    for (;i<8;i+)  &#

61、160;  CAN_RX_Datai = 0x00;     /-/  清0缓冲区/   /   -pointer,指向待清0 的缓冲区首地址/   -length 清0 的长度   /-void Clear_Buffer(unsigned char *pointer,unsigned char length) unsigned char i; for (i=0;i&

62、#160;  *(pointer+) = 0x00; 另外头文件为:#ifndef _CANCOM_H#define _CANCOM_H#define CS1_SJA1000  0x7f00       /SJA1000 Pin /CS -> P2.7,low level active   #define MOD_CAN1  XBYTECS1_SJA1000+0   /Peli#define CMR_CAN1&

63、#160; XBYTECS1_SJA1000+1  /command#define SR_CAN1   XBYTECS1_SJA1000+2   /state#define IR_CAN1   XBYTECS1_SJA1000+3   /interrupt#define IER_CAN1  XBYTECS1_SJA1000+4  /interrupt enable  /Peli#define BTR0_CAN1

64、60; XBYTECS1_SJA1000+6        /bus timing0#define BTR1_CAN1  XBYTECS1_SJA1000+7        /bus timing1#define OCR_CAN1  XBYTECS1_SJA1000+8#define TEST_CAN1  XBYTECS1_SJA1000+9#define ECC_CAN1 &

65、#160;XBYTECS1_SJA1000+12  /error catch#define EWLR_CAN1  XBYTECS1_SJA1000+13  /error warning limit#define RXERR_CAN1  XBYTECS1_SJA1000+14  /#define TXERR_CAN1  XBYTECS1_SJA1000+15#define ACR0_CAN1  XBYTECS1_SJA1000+16#define ACR1_

66、CAN1  XBYTECS1_SJA1000+17#define ACR2_CAN1  XBYTECS1_SJA1000+18#define ACR3_CAN1  XBYTECS1_SJA1000+19#define AMR0_CAN1  XBYTECS1_SJA1000+20#define AMR1_CAN1  XBYTECS1_SJA1000+21#define AMR2_CAN1  XBYTECS1_SJA1000+22#define AMR3_CAN1  XBYTECS1_SJA1000+23#define RBSA_CAN1  XBYTECS1_SJA1000+30  /beginning of receive#define CDR_CAN1  XBYTECS1_SJA1000+31  /clock de

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论