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

下載本文檔

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

文檔簡介

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

2、160;                                                  &

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

4、0;  /    -此功能已經(jīng)改為,每收到一幀數(shù)據(jù),啟動一次CAN傳輸,傳輸字節(jié)數(shù)等于串口收到的數(shù)據(jù)/    -串行幀的幀間界定通過當(dāng)前波特率下傳輸5個字節(jié)為時間間隔,具體為當(dāng)順序接收到的任意兩個數(shù)據(jù),它們之間的時間間隔大于5個字節(jié)傳送時間,認(rèn)為這兩個數(shù)據(jù)分屬于兩個不 同的幀/  7,當(dāng)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ā)送的目標(biāo)的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ā)送標(biāo)志位unsigned char UART_flag;     /unsigned char CAN_ERROR_flag = NOT;   /unsigned char CAN_DataLength = 8;    /CAN信

10、息的報文長度unsigned char UART_DataLength = 0;   /串口接收時的當(dāng)前指示  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)/   -流程控制標(biāo)志置為無效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)用延時過長導(dǎo)致/    看門狗復(fù)位/-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ù)準(zhǔn)備好給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為擴(kuò)展幀,F(xiàn)armeType = 0為/    標(biāo)準(zhǔn)幀/-void CAN_Transmit(bit FarmeType) unsigned char i; unsigned char m; unsigned char can_status; unsigned char x

39、data *pointer;      if (FarmeType = 0)   /標(biāo)準(zhǔn)幀   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        /擴(kuò)展幀   &

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)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論