版權(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024-2025學(xué)年高中語文課時分層作業(yè)11廉頗藺相如列傳含解析新人教版必修4
- 光伏項目建設(shè)流程
- 2025酒店與員工的勞動合同
- 2025委托貸款合同范文委托書
- 2025沼氣工程施工合同
- 2025年四川考貨運資格證考試內(nèi)容
- 2025中國人民建設(shè)銀行借款合同范本
- 2025年來賓c1貨運從業(yè)資格證模擬考試題
- 2025租農(nóng)民土地合同范本
- 中國熱水蒸汽軟管接頭項目投資可行性研究報告
- 醫(yī)務(wù)科運用PDCA循環(huán)提高危急值管理合格率品管圈成果匯報
- 構(gòu)美-空間形態(tài)設(shè)計學(xué)習(xí)通課后章節(jié)答案期末考試題庫2023年
- 民法典??荚囶}及答案
- 收款賬戶確認(rèn)書
- IPTV系統(tǒng)的分析研究的開題報告
- 全北師大版英語必修一寫作+范文
- 爭做新時代好少年好隊員主題班會ppt
- 橋梁養(yǎng)護(hù)資金保障制度
- 小學(xué)音樂大概念下的大單元教學(xué)設(shè)計探究 論文
- 中國文化概論智慧樹知到答案章節(jié)測試2023年曲阜師范大學(xué)
- 語文一年級上全冊教案
評論
0/150
提交評論