版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
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. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年消防给水系统工程保险合同3篇
- 2025年消防安装劳务分包施工合同(含消防检测)3篇
- 2025年保密协议保密责任
- 2025年度龙门吊拆除项目安全风险评估与应急预案合同4篇
- 2025年励志类书籍发行协议
- 2025年仓库租金递增约定协议
- 2025年仓储仓库保全合同
- 2025年人才匹配与协议书范本
- 二零二五年货车租赁及货运信息处理服务合同3篇
- 2025年消防工程劳务分包及消防安全评估合同3篇
- 2024版智慧电力解决方案(智能电网解决方案)
- 公司SWOT分析表模板
- 小学预防流行性感冒应急预案
- 肺癌术后出血的观察及护理
- 生物医药大数据分析平台建设-第1篇
- 基于Android的天气预报系统的设计与实现
- 冲锋舟驾驶培训课件
- 美术家协会会员申请表
- 聚合收款服务流程
- 中石化浙江石油分公司中石化温州灵昆油库及配套工程项目环境影响报告书
- 搞笑朗诵我爱上班台词
评论
0/150
提交评论