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

下载本文档

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

文档简介

1、can 总线通信程序/ can uart 的协议转换器/ 说明:/ 1,单片机使用p89c61x2ba / -晶振 11.0592mhz / -can总线中断使用单片机的中断0,外部有上拉电阻,波特率可以设定/ 2,can 总线发送采用查询方式,接收采用中断方式/ 3,看门狗复位时间1.2s / 4,sja1000晶振 8mhz,peil模式/ 5,串口中断接收,查询发送,波特率可设置/ 6,当串口收到数据后,每8 个数一组打包,通过can 总线发送出去/ / -10.16日,重新修改程序完成以下功能- / -此功能已经改为,每收到一帧数据,启动一次can 传输,传输字节数等于串口收到的数据/

2、 -串行帧的帧间界定通过当前波特率下传输5 个字节为时间间隔,具体为当顺序接收到的任意两个数据,它们之间的时间间隔大于5 个字节传送时间,认为这两个数据分属于两个不 同的帧/ 7,当 can 总线每接收一帧信息后,通过串口发送出去/ 改为可以识别can 的报文字节长度,即串口只发送can 报文长度个字节/ 8,看门狗芯片max1232cpa,硬件溢出时间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

3、_data8 = 0,1,2,3,4,5,6,7; unsigned char xdata uart_rx_data255; /串口接收到的串行帧unsigned char xdata can_tx_data255; /待发送的数据缓冲区unsigned char code acr_id4 = 0,0,0,0; /can初始设置验收滤波值unsigned char code amr_id4 = 0 xff,0 xff,0 xff,0 xff; unsigned char can_tx_id4 = 0,0,0,0; /待发送的目标的id unsigned char can_rx_id4 = 0,

4、0,0,0; /接收到的信息来自何id unsigned char can_rx_data8 = 7,6,5,4,3,2,1,0; /接受到的数据缓冲unsigned char code can_btr010 =0 xdf,0 xcf,0 xc7,0 xc3,0 x43,0 xc1,0 xc1,0 xc0,0 xc0,0 x80; unsigned char code can_btr110 = 0 x7f,0 x7f,0 x7f,0 x7f,0 x2f,0 x7f,0 x4d,0 x3e,0 x3a,0 x23; / 5k 10k 20k 40k 50k 80k 100k 200k 250k

5、500k unsigned char code uart_btr4 = 0 xe8,0 xf4,0 xfa; / 1.2k,2.4k,4.8k unsigned char can_flag; /can发送标志位unsigned char uart_flag; / unsigned char can_error_flag = not; / unsigned char can_datalength = 8; /can信息的报文长度unsigned char uart_datalength = 0; /串口接收时的当前指示unsigned char uart_length = 0; /串口接收区的长

6、度指示/sbit aaa = p14; void main(void) ea = 0; system_init(); /系统初始化 timer_init(); /定时器初始化 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) can_flag = not; can_transmit(0); le

7、d1 = !led1; else can_flag = not; /* if (uart_flag = yes) uart_flag = not; /delay(50); uart_transmit(); /clear_buffer(can_rx_data,8); /led3 = !led3; else uart_flag = not; */ if (can_error_flag = yes) can_error_flag = not; can_init(); else can_error_flag = not; /- / 功能:系统设置/ -外部数据存储区访问使能/ -led指示灯关( 1

8、on ,0off )/ -流程控制标志置为无效not / -清空串口, can 的相关数据缓冲区/- void system_init(void) ckcon = 0 x00; /fosc devide 12 auxr = 0 x00;/0 x02; /exm enable led1 = 0; /led0-3 off 指示灯,共阴接法,1 时亮 led2 = 0; led3 = 0; led4 = 0; wdt = 1; /wdt ini can_datalength = 8; uart_datalength = 0; uart_length = 0; can_flag = not; can_

9、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(can_rx_data,8); /* can_flag = yes; uart_flag = yes; */ /- / / 软件延时(非精确)/ -内置清看门狗定时器子函数/ 防止多次调用延时过长导致/ 看门狗复位/ /- void delay(unsigned ch

10、ar time) unsigned char i; unsigned int j; for (i = 0;i time;i+) w_wdt(); for (j=0;j30000;j+) /- / 串行口初始化设置/ 方式 1,8 数据位,一个停止位,无奇偶校验/ 串口中断允许/- void uart_ini(void) scon = 0 x50; /方式 1,波特率可变,8bits ,接受允许 pcon&= 0 x7f; /smod = 0 tmod |= 0 x20; /timer1 mode 2 tl1 = uart_btr2; /| f /| 波特率 - th1 = uart_b

11、tr2; /| 32*2smod*12*(256-tl1) tcon |= 0 x40; /start ti = 0; /- / / 看门狗 “ 喂狗 ” 程序, wdt 的一个下降沿触发一次/ /- void w_wdt(void) /triggle wdt unsigned char i; wdt = 1; for (i=0;i can_tx_buffer / /- void timer0_isr(void) interrupt 1 using 2 static unsigned char i; /unsigned char counter; /th0 = temp_th0; /tl0 =

12、 temp_tl0; /*counter += 1; if (counter = 20) /到 1s 了么? /uart_flag = yes; if (counter = 40) /到 2s 了么? /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; /- / / 串口中断服务程序

13、/ / -只有接收使用/ -每收一个数重新初始化定时器/ /- void rx_int(void) interrupt 4 using 3 static unsigned char n; if (ri=1) do ri = 0; while (ri != 0); /uart_rx_datauart_datalength+ = sbuf; n = sbuf; uart_send_byte(n); th0 = temp_th0; tl0 = temp_tl0; tr0 = 1; /启动数据间隔定时,判断是否分属两帧 else /tx /- / / 串口发送单字节程序/ /- void uart_s

14、end_byte(unsigned char data) sbuf = data; while (ti = 0) /等待发送完毕 ti = 0; /- / / 初始化定时器程序/ / -定时器 0 方式 1,定时器1 方式 2 留给串口/ /- void timer_init(void) tmod |= 0 x01; /使用定时器0方式 1 th0 = temp_th0; tl0 = temp_tl0; /tr0 = 1; /这里不打开定时器 void can_init(void) ea = 0; mod_can1 |= 0 x08; /单滤波方式 do mod_can1 |= 0 x01;

15、/request to reset mode while (mod_can1&0 x01) != 0 x01); cdr_can1 = 0 xc8; /选择 pelican模式,使用输入比较器,clk_out关闭 ier_can1 = 0 x01; /允许发送中断,其他中断禁能 acr0_can1 = 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

16、 = amr_id3; /ecc_can1 = 0; /txerr_can1 = 0; /rbsa_can1 = 0; btr0_can1 = can_btr00; btr1_can1 = can_btr10; ocr_can1 = 0 xaa; /normal output w_wdt(); do mod_can1 &= 0 xfe; while (mod_can1&0 x01) != 0 x00); ea = 1; /- / / 串口发送一帧接受到的can 数据/ / -长度 18,根据接收到的can 信息来确定/ /- void uart_transmit(void) /

17、using 0 unsigned char i; led3 = !led3; for (i=0;i uart_send_byte(can_rx_datai); /- / / can发送接受到的一帧串口数据/ / -最大长度 255 ,根据接收到的串口信息的/ 个数来确定/ -按每依次 8 个数据作为一个can 帧的报文部分/ 不足 8 个或超过8 的倍数的部分按实际个数作/ 为 can 报文/ -farmetype = 1 为扩展帧, farmetype = 0 为/ 标准帧/- void can_transmit(bit farmetype) unsigned char i; unsigne

18、d char m; unsigned char can_status; unsigned char xdata *pointer; if (farmetype = 0) /标准帧 for (m=0;m(uart_length/8);m+) w_wdt(); do /发送缓冲区空么? can_status = sr_can1; while (can_status&0 x04) != 0 x04); txframeinfo1 = 0 x00 + 0 x08; pointer = &txid1; for (i=0;i2;i+) *(pointer+) = can_tx_idi; po

19、inter = &txid3; for (i=0;i8;i+) *(pointer+) = can_tx_datai+8*m; cmr_can1 = request_tx; w_wdt(); if (uart_length%8) != 0) w_wdt(); do / 发送缓冲区空么? can_status = sr_can1; while (can_status&0 x04) != 0 x04); txframeinfo1 = 0 x00 + uart_length%8; pointer = &txid1; for (i=0;i2;i+) *(pointer+) =

20、can_tx_idi; pointer = &txid3; for (i=0;i(uart_length%8);i+) *(pointer+) = can_tx_datai+8*(uart_length/8); cmr_can1 = request_tx; w_wdt(); else else /扩展帧 for (m=0;m(uart_length/8);m+) w_wdt(); do /发送缓冲区空么? can_status = sr_can1; while (can_status&0 x04) != 0 x04); txframeinfo1 = 0 x80 + 0 x08;

21、 pointer = &txid1; for (i=0;i4;i+) *(pointer+) = can_tx_idi; pointer = &txdata1; for (i=0;i8;i+) *(pointer+) = can_tx_datai+8*m; cmr_can1 = request_tx; w_wdt(); if (uart_length%8) != 0) w_wdt(); do /发送缓冲区空么? can_status = sr_can1; while (can_status&0 x04) != 0 x04); txframeinfo1 = 0 x80 +

22、 uart_length%8; pointer = &txid1; for (i=0;i4;i+) *(pointer+) = can_tx_idi; pointer = &txdata1; for (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; /- / / can接收中断服务程序/ / -判断是否是rx 中断,如果是/ 把接受到的can 信息通过串行口发送出去/ -其他的中

23、断说明can 总线出现错误或脱离/ /- void can_isr(void) interrupt 0 using 1 unsigned char can_int; ea = 0; can_int = ir_can1; if (can_int&0 x01) = 0 x01) /接收中断 can_receive(); cmr_can1 |= releaserxbuf; else can_error_flag = yes; /其他中断,暂时未用 /uart_flag = yes; /can_flag = yes; uart_transmit(); ea = 1; /- / / can接收数

24、据函数/ / -根据接受到的帧信息,按不同的长度存储/ 报文数据/ /- void can_receive(void) using 1 unsigned char i; unsigned char xdata *pointer; unsigned char info; info = rxframeinfo1; if (info&0 x80) = 0) /standard frame /can_rx_id0 = rxid1; /can_rx_id1 = rxid2; can_datalength = info&0 x0f; pointer = &rxid3; for (i

25、=0;i can_rx_datai = *(pointer+); for (;i8;i+) can_rx_datai = 0 x00; else /ex frame /can_rx_id0 = rxid1; /can_rx_id1 = rxid2; /can_rx_id2 = rxid3; /can_rx_id3 = rxid4; can_datalength = info&0 x0f; pointer = &rxdata1; for (i=0;i can_rx_datai = *(pointer+); /pointer += 1; for (;i p2.7,low level

26、 active #define mod_can1 xbytecs1_sja1000+0 /peli #define cmr_can1 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 xbytecs1_sja1000+6 /bus timing0 #define

27、 btr1_can1 xbytecs1_sja1000+7 /bus timing1 #define ocr_can1 xbytecs1_sja1000+8 #define test_can1 xbytecs1_sja1000+9 #define ecc_can1 xbytecs1_sja1000+12 /error catch #define ewlr_can1 xbytecs1_sja1000+13 /error warning limit #define rxerr_can1 xbytecs1_sja1000+14 / #define txerr_can1 xbytecs1_sja100

28、0+15 #define acr0_can1 xbytecs1_sja1000+16 #define acr1_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_sj

29、a1000+23 #define rbsa_can1 xbytecs1_sja1000+30 /beginning of receive #define cdr_can1 xbytecs1_sja1000+31 /clock devide #define txframeinfo1 xbytecs1_sja1000+16 #define txid1 xbytecs1_sja1000+17 #define txid2 xbytecs1_sja1000+18 #define txid3 xbytecs1_sja1000+19 #define txid4 xbytecs1_sja1000+20 #de

30、fine txdata1 xbytecs1_sja1000+21 #define txdata2 xbytecs1_sja1000+22 #define txdata3 xbytecs1_sja1000+23 #define txdata4 xbytecs1_sja1000+24 #define txdata5 xbytecs1_sja1000+25 #define txdata6 xbytecs1_sja1000+26 #define txdata7 xbytecs1_sja1000+27 #define txdata8 xbytecs1_sja1000+28 #define rxframeinfo1 xbytecs1_sja1000+16 #define rxid1 xbytecs1_sja1000+17 #define rxid2 xbytecs1_sja1000+18 #define rxid3 xbytecs1_sja1000+19 #define rxid4 xbyt

温馨提示

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

评论

0/150

提交评论