完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
在调试中遇到了这样的问题:在用CAN总线分析仪接收调试板发出的数据时,接收不到数据。但是程序拿到另外一块类似板中一切正常。
原因分析 在程序没问题的基础上,想到是硬件的问题,如是开始了以下问题检查
报文变为一位显性,25位隐性电平,这个电平形式我始终不知道是什么。 软件问题 既然硬件没有问题那就从软件着手。 /*************************************************************/ /* CAN发送 */ /*************************************************************/ Bool MSCANSendMsg(struct can_msg msg) { unsigned char send_buf, sp; unsigned char num; if(msg.len > 8) // 检查数据长度 return(FALSE); //返回true和false所以要用bool型,在以后 if(fucn(x,y))//可以用来作if语句的判断,while(fucn(x,y))//也可以做循环条件的判断 // 检查总线时钟是否同步 if(CANCTL0_SYNCH==0) return(FALSE); send_buf = 0; do { CANTBSEL=CANTFLG; // 寻找空闲的缓冲器 send_buf=CANTBSEL;//等待该寄存器有值,即等待相关报文缓冲器为空 num++; if(num>10) break; } while(!send_buf); // 写入标识符 CANTIDR0 = (unsigned char)(msg.id>>3);//id为8位 CANTIDR1 = (unsigned char)(msg.id<<5); if(msg.RTR) //Remote Transmission Request 远程传输请求 // RTR = 阴性 CANTIDR1 |= 0x10; // 写入数据 for(sp = 0; sp < msg.len; sp++) *((&CANTDSR0)+sp) = msg.data[sp];//数据段寄存器,包含将要发送的数据 // 写入数据长度 CANTDLR = msg.len; // 写入优先级 CANTTBPR = msg.prty; //ransmit Buffer Priority Register (TBPR) // 清 TXx 标志 (缓冲器准备发送) CANTFLG = send_buf; return(TRUE); } 在调试时程序总是进到寻找空闲的缓冲器这个do while循环里,跳不出来,所以定义了个num变量让它自加到10跳出循环;但是还是不通,于是想从 CAN初始化程序 入手: /*************************************************************/ /* 初始化CAN */ /*************************************************************/ void INIT_CAN(void) //按照dz60寄存器改编的程序 { if(CANCTL0_INITRQ==0) // 查询是否进入初始化状态 CANCTL0_INITRQ =1; // 进入初始化状态 while (CANCTL1_INITAK==0); //等待进入初始化状态,初始化模式确认 CANBTR0_SJW = 3; //设置同步跳转宽度,总线计时寄存器,现在设为4 CANBTR0_BRP = 3 ; //设置波特率预分频器-prescaler value , CANBTR1_TSEG_10 = 6; CANBTR1_TSEG_20 = 7; //设置时段1-7个和时段2-8个的Tq个数 ,总线频率为125kb/s,1/125K=bit time=(prescaler value)*(1+tseg1+tseg2)/Fcanclk=4*(7+8+1)/8M // 关闭滤波器 CANIDMR0 = 0xFF;//不比较 CANIDMR1 = 0xFF; CANIDMR2 = 0xFF; CANIDMR3 = 0xFF; CANIDMR4 = 0xFF; CANIDMR5 = 0xFF; CANIDMR6 = 0xFF; CANIDMR7 = 0xFF; CANCTL1 = CANCTL1_CLKSRC_MASK | CANCTL1_CANE_MASK; //使能MSCAN模块,设置为一般运行模式、使用总线时钟源 环回自测禁止 CANCTL0 = 0x00; //返回一般模式运行 while(CANCTL1_INITAK); //等待回到一般运行模式 while(!CANCTL0_SYNCH); //等待总线时钟同步 CANRIER_RXFIE = 0; //禁止接收中断 } 改了两个位置 第一个位置改了同步跳转宽度 CANBTR0_SJW = 3; //设置同步跳转宽度,总线计时寄存器,现在设为4 同步跳转宽度是CAN总线机制中为了寻找同步而在缓冲段增加或减少时间的上限值。总线中能通信的基础是各个节点的波特率一致,然而各个节点的波特率又不能达到百分百相同,所以CAN总线允许各节点波特率有微小偏差,而对位时间的微调就能微调波特率,使该节点与总线波特率一致,所以同步跳转宽度越大,波特率的波动范围就越大,容错率提高,也就是说这个值越大,对总线中个节点的波特率的要求就越松。 第二个位置改变了缓冲段一与缓冲段二的时长 CANBTR1_TSEG_10 = 6; CANBTR1_TSEG_20 = 7; 将缓冲段一设置为7个Tq时长,将缓冲段二设置为8个Tq时长,这样采样点就在该位的中间位置,利于采样 再进行调试时能够很好地接收到数据:
|
|
|
|
只有小组成员才能发言,加入小组>>
3310 浏览 9 评论
2991 浏览 16 评论
3492 浏览 1 评论
9057 浏览 16 评论
4086 浏览 18 评论
1175浏览 3评论
603浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
596浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2333浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1894浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 14:19 , Processed in 1.244051 second(s), Total 79, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号