查看: 7586|回复: 0

[分享] 基于NXP1778的CAN自动波特率检测

[复制链接]
  • TA的每日心情
    奋斗
    2021-5-28 10:51
  • 签到天数: 62 天

    连续签到: 1 天

    [LV.6]常住居民II

    3

    主题

    233

    帖子

    0

    高级会员

    Rank: 4

    积分
    739
    最后登录
    2025-1-12
    发表于 2021-5-21 16:52:45 | 显示全部楼层 |阅读模式
    一、概念
          NXP LPC1778芯片内部自带一个CAN控制器。CAN模块由两部分组成:控制器和验收滤波器。所有的寄存器和RAM都以32位字宽度来访问。
          CAN自动波特率检测主要用于以一种CAN的转换的产品中。产品中CAN部分的波特率以前都是通过网页中修改然后配置下去的,依据实际情况的考虑,如果CAN部分的波特率能够根据客户设备的改变而自动改变,将会增加其灵活性。
    二、原理
          根据CAN控制器的特点,理论上有两种实现的方式。一是,通过在接收端处理波特率协商,另外是通过在发送时处理。理论上这两种方式都可以实现,因为当双方波特率不匹配时,当出现被动错误时就说明数据发送失败,然后根据波特率表切换到下一个波特率继续检测,看是否出现被动错误。
    三、流程
           根据原理,最开始使用的是在接收端时处理,由于CAN模块的数据接收是以中断控制的,所以波特率协商只能在中断中实现;由于CAN控制器对于没有发送成功的数据会进行重发,所以导致CAN的接收中断触发的时间极短,而在其中处理波特率检测和切换时间开销很大,所以这种方式测试的结果是波特率协商出错;基于这种情况,后面又改进了这种处理方式,就是在定时器中断中处理波特率切换,只在CAN的接收中断中设置标志判断波特率是否正确,经过测试这种方式明显要比改进之前的要好,但由于都是在中断中处理,对于时间的把握不是很好,在某些波特率下还是不能切换。总之,在中断中处理始终不是很好,因为对于时间的把握始终不是很好,所以最终放弃了这种方式。后面一种方式是在发送端处理,即采用在循环中轮询发送数据以及判断总线是否出错需要波特率的切换。具体的方式是在发送一个数据之后就等待出现被动错误,如果到达一定时间还没有出现就确定发送成功。根据这一原理进行了实现并测试,发现在波特率为80K的情况下出现不能切换的问题,在这一问题上进行了多次调试,发现其实在出现被动错误的时候CAN控制器会重发还多次才能达到,但当波特率设置为80K时,重发过程中都不会引发被动错误,所以根据测试结果,认为判断条件有时候需要提前结束,而不必等到达到错误被动。最后,根据情况在进行切换的条件的总线错误中添加了总线错误中断的判断。
    四、部分代码
    1. //判断是否进行波特率切换和超时退出
    2. void set_change_state_erred(uint8 canid)
    3. {
    4. LPC_CAN_TypeDef* pCan;
    5.     pCan = CAN_GetPointer(canid);
    6.     //主动错误或者总线上检测到错误时,表示数据发送失败
    7.     //"主动错误"应定义为:CANxGSR中的ES位为1,并且发送出错计数器>=128
    8. //总线错误定义为:CANxICR中的BEI位为1,即是检测到总线错误中断被置位
    9.    if(((pCan->GSR & CAN_GSR_ES)&&((pCan->GSR & 0xff000000) >=128))|| (pCan->ICR & CAN_ICR_BEI))
    10.     {
    11.         //遍历一次波特率表,如果没有协商到说明没有波特率与之匹配
    12.         //强制设置波特率为最大值1000K
    13.         //同时立即退出波特率协商,不必等待超时
    14. if(try_num[canid] == 16)
    15. {
    16.     try_num[canid]  = 0;
    17.     CAN_setting[canid].baudrate = set_baudrate[try_num[canid]];
    18.     auto_csd_start(canid);
    19.     baudrate_change_state[canid] = 0;
    20.     return ;
    21. }

    22.   //波特率相同不必重复检测
    23.         if(CAN_setting[canid].baudrate ==set_baudrate[try_num[canid]])
    24. {
    25.      try_num[canid]++;
    26. }

    27.          //切换到位速率表中下一个
    28.   CAN_setting[canid].baudrate = set_baudrate[try_num[canid]];
    29.   auto_csd_start(canid);
    30.   send_data_state[canid] = 0;
    31.   try_num[canid]++;
    复制代码
    五、测试情况
          目前通过ZLG的CAN-TEST软件和自己的设备测试,都能进行切换。最大支持16个波特率的切换,并且可以实现两路同时自动协商。

    转载自:https://blog.csdn.net/chen441107/article/details/8632552?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162158644316780274127815%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=162158644316780274127815&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_v2~rank_v29-26-8632552.nonecase&utm_term=nxp+lpc1788

    哎...今天够累的,签到来了~
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-9-12 22:18 , Processed in 0.078457 second(s), 19 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表