can總線通信程序_第1頁
can總線通信程序_第2頁
can總線通信程序_第3頁
can總線通信程序_第4頁
can總線通信程序_第5頁
已閱讀5頁,還剩16頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、CAN總線通信程序/  CAN <=> UART的協(xié)議轉(zhuǎn)換器/  說明:/  1,單片機使用P89C61X2BA /   -晶振11.0592MHZ                            &#

2、160;                                                  &

3、#160; /   -CAN總線中斷使用單片機的中斷0,外部有上拉電阻,波特率可以設(shè)定/  2,CAN總線發(fā)送采用查詢方式,接收采用中斷方式/  3,看門狗復位時間1.2S/  4,SJA1000晶振8MHZ,Peil模式/  5,串口中斷接收,查詢發(fā)送,波特率可設(shè)置/  6,×××當串口收到數(shù)據(jù)后,每8個數(shù)一組打包,通過CAN總線發(fā)送出去/   -10.16日,重新修改程序完成以下功能-

4、0;  /    -此功能已經(jīng)改為,每收到一幀數(shù)據(jù),啟動一次CAN傳輸,傳輸字節(jié)數(shù)等于串口收到的數(shù)據(jù)/    -串行幀的幀間界定通過當前波特率下傳輸5個字節(jié)為時間間隔,具體為當順序接收到的任意兩個數(shù)據(jù),它們之間的時間間隔大于5個字節(jié)傳送時間,認為這兩個數(shù)據(jù)分屬于兩個不 同的幀/  7,當CAN總線每接收一幀信息后,通過串口發(fā)送出去/ 改為可以識別CAN的報文字節(jié)長度,即串口只發(fā)送CAN報文長度個字節(jié)/  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;        /待發(fā)送的數(shù)據(jù)緩沖區(qū)unsigned char code ACR_ID4 = 0,0,0,0;       /CAN初始設(shè)置驗收濾波值unsigned char code AMR_ID4 = 0xff,0xff,0xff,0xff;unsigned char CAN_TX_ID4 = 0,0,0,0;   

7、     /待發(fā)送的目標的IDunsigned char CAN_RX_ID4 = 0,0,0,0;        /接收到的信息來自何IDunsigned char CAN_RX_Data8 = 7,6,5,4,3,2,1,0;     /接受到的數(shù)據(jù)緩沖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發(fā)送標志位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;    /串口接收區(qū)的長度指示/sbit AAA = P14;void main(void) EA = 0;      System_init();   /系統(tǒng)初始化 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;   /-/ 功能:系統(tǒng)設(shè)置/   -外部數(shù)據(jù)存儲區(qū)訪問使能/   -LED指示燈關(guān)(1on,0off)/   -流程控制標志置為無效NOT/   -清空串口,CAN的相關(guān)數(shù)據(jù)緩沖區(qū)/-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; */-/  軟件延時(非精確)/   -內(nèi)置清看門狗定時器子函數(shù)/    防止多次調(diào)用延時過長導致/    看門狗復位/-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+)     /-/ 串行口初始化設(shè)置/ 方式1,8數(shù)據(jù)位,一個停止位,無奇偶校驗/ 串口中斷允許/-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的一個下降沿觸發(fā)一次/-void W_WDT(void)   /triggle WDT unsigned char i; WDT = 1; for (i=0;i<10;i+)   WDT = 0;/-/ 中斷初始化/  /  -外部中斷0有效,下降沿觸發(fā),用于SJA1000產(chǎn)生CAN事件中斷/  -定時器中斷,用于判定串口接收的順序兩個字節(jié)是否

26、分屬兩幀/  -串口中斷,RX使用中斷,TX未使用/  -中斷優(yōu)先級暫時未設(shè)定/-void Interrupt_init(void) /IP = 0x00;      IT0 = 0x01;      /外部0中斷沿觸發(fā)  ET0 = 1;      /定時器0中斷使能 EX0 = 1;     &

27、#160;/外部中斷使能 ES = 1;                /串行中斷使能/-/ 定時中斷程序 /  /  一旦中斷,說明一幀的接收已經(jīng)結(jié)束,開始啟動CAN發(fā)送程序/  把串口接收到的數(shù)據(jù)準備好給CAN總線發(fā)送/  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;      /定時器關(guān),開始次CAN信息傳送 for (i=0;i   CAN_TX_Datai = UART_RX_Datai;  UART_Length = UART_DataLength; UART_DataLength = 0; CAN_flag = YES;/-/&

30、#160; 串口中斷服務(wù)程序/  -只有接收使用   /  -每收一個數(shù)重新初始化定時器/-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;       /啟動數(shù)據(jù)間隔定時,判斷是否分屬兩幀  else   /TX /-/  串口

32、發(fā)送單字節(jié)程序/-void UART_Send_Byte(unsigned char Data)     SBUF = Data;  while (TI = 0)     /等待發(fā)送完畢   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關(guān)閉 IER_CAN1 = 0x01;     /允許發(fā)送中斷,其他中斷禁能 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;/-/  串口發(fā)送一幀接受到的CAN數(shù)據(jù)/   /   -長度18,根據(jù)接收到的CAN信

37、息來確定/-void UART_Transmit(void) /using 0 unsigned char i;  LED3 = !LED3; for (i=0;i   UART_Send_Byte(CAN_RX_Datai); /-/  CAN發(fā)送接受到的一幀串口數(shù)據(jù)/   /   -最大長度255,根據(jù)接收到的串口信息的/    個數(shù)來確定/   -按每依次8個數(shù)

38、據(jù)作為一個CAN幀的報文部分/    不足8個或超過8的倍數(shù)的部分按實際個數(shù)作/    為CAN報文/   -FarmeType = 1為擴展幀,F(xiàn)armeType = 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         /發(fā)送緩沖區(qū)空么?      &#

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          /發(fā)送緩沖區(qū)空么?       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         /發(fā)送緩沖區(qū)空么?                       

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         /發(fā)送緩沖區(qū)空么?       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接收中斷服務(wù)程序/   /   -判斷是否是RX中斷,如果是/    把接受到的CAN信息通過串行口發(fā)送出去/   -其他的中斷說明CAN總線出現(xiàn)錯誤或脫離/    /-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接收數(shù)據(jù)函數(shù)/

57、60;  /   -根據(jù)接受到的幀信息,按不同的長度存儲/    報文數(shù)據(jù)/    /-            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緩沖區(qū)/   /   -pointer,指向待清0 的緩沖區(qū)首地址/   -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. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論