引言
CAN 总线是目前应用十分广泛的现场总线,其仅通过一对差分信号线即可实现网络中各节点之间的互联和信息交互,具有极强的抗干扰能力[1-3]。CAN 总线采用非破坏性仲裁技术和自动重发机制,不仅能有效避免总线冲突,还能确保各节点数据的可靠传输[4-5]。此外,CAN 总线还具有实时性强、可靠性好、标准化程度高等优势[6-7]。基于此,CAN总线被广泛应用于工业控制、汽车制造、仪器仪表、煤矿智能系统等多个领域。
CAN网络中的节点不分主从,因此通信方式灵活,网络扩展性强,受限于CAN总线驱动电路,目前CAN网络组网节点数最大可达110个。对于确定的CAN网络,往往会因为应用需求而向其中引入新的功能节点,为了使新节点能够与网络中原有节点进行可靠通信,必须确保新节点的波特率与CAN总线波特率一致。通常,新节点的程序已固化在存储器中,波特率的修改或配置困难,从而可能导致新节点的波特率无法匹配网络波特率。为解决 CAN 总线波特率的匹配问题,参考文献[8]和[9]通过对设定阈值与产生的错误计数值和接收到的正确报文数进行比较来修改和匹配波特率,该方法存在阈值选取合理性问题,且采用 FPGA 开发,不易推广;参考文献[10]采用波特率轮询法,通过检测 CAN 控制器是否产生错误来调整和匹配波特率,方法简单,易于实现,但在收、发双方波特率较接近时,可能产生误判问题;参考文献[11]通过控制器分类及判断波特率切换次数来实现波特率自适应,该方法未对切换次数达上限时进行处理,存在波特率适配不成功的可能。参考文献[12]结合轮询法和探测法,在 Linux下实现了波特率自适应。为了兼顾算法的可用性及波特率匹配的成功率,本文提出了改进的波特率自适应算法,经实际测试,新增节点能够通过发送测试报文或者接收广播报文,较快地适配网络波特率,可靠性高。
STM32F407IGT6是采用Cortex M4内核的32位高性能单片机,其内部集成两个支持CAN2.0A和2.0B协议的CAN控制器[13],用户只需外扩简单的 CAN 收发器电路即可将其接入到 CAN 网络中,从而实现与网络中各节点间的数据通信。本文基于 STM32F407IGT6 嵌入式开发平台设计了 CAN 波特率自适应算法。
1
硬件设计
STM32F407IGT6 嵌入式开发平台采用 TJA1050 作为CAN 收发器,该收发器完全兼容ISO11898标准,最高速度可达1 Mb/s,此外,还具有电磁辐射低、抗干扰能力强、接口简单等优点。该嵌入式开发平台中STM32F407IGT6与JTA1050之间的连接电路图如图1所示。
图1 STM32F407与TJA1050连接电路图
STM32F407IGT6的PA11、PA12引脚可复用为片内CAN控制器收发数据的通道。由图1可知,PA11和PA12引脚分别连接 TJA1050 的串行数据线 RXD 和 TXD,然后通过收发器内部两个具有差动接收和发送能力的总线终端CANH和CANL连接到总线线路上。实验中CAN 模块均作为终端使用,为了提高网络的抗干扰能力、降低反射能量,在CANH和CANL之间连接了120Ω终端电阻。TJA1050具有两种工作模式:高速模式和静音模式,通过控制线S进行选择。为了使开发平台能够通过CAN总线实现数据收发,将控制线S连接到GND,收发器的工作模式配置为高速模式。Vref为参考电压输出端,悬空即可。
2
软件设计
CAN总线协议中位的同步通过位时序逻辑实现,位时序逻辑监视串行CAN总线,执行采样并调整采样点位置。STM32F407IGT6片内bxCAN模块通过CAN_BTR寄存器实现位时序的设置,位时序图如图2所示。
图2 bxCAN 模块位时序图
在CAN 通信中,一个数据位所持续的时间称为标称位时间。由图2可知,标称位时间由同步段、位段1和位段2三部分构成,每一部分均包含若干个tq (最小时间单位),其中同步段固定为一个tq。波特率计算关系如式(1)~式(5)所示:
式(3)中,tPCLK 为主控制器 APB 总线时钟的时间周期,该值在系统初始化时确定。BRP[9:0]、TS1[3:0]和TS2[2:0]为CAN_BTR 寄存器中对应的位域,其中,BRP[9:0]用于实现CAN 总线波特率预分频,TS1[3:0]和 TS2[2:0]用于确定位段1及位段2所包含的tq个数。此外,为了尽可能消除由于硬件问题带来的波特率误差,提高网络容忍度并保证总线中收发节点采样的准确性,自定义波特率时还会引入SJW(再同步跳转宽度)参数,通常 SJW 取值为1个tq。图2中,采样点位置对应位段1结束位置,通常采样点位于标称位时间75%~87.5%的位置[14-16]。
基于式(1)~(5)及采样点的设置规则,确定实验所用的波特率列表,列表中共包含15个常用波特率,取值分别为:20kb/s、33.33kb/s、40kb/s、50kb/s、66.66kb/s、 80kb/s、100kb/s、125kb/s、200kb/s、250kb/s、400kb/s、 500kb/s、666kb/s、800kb/s和1000kb/s。
CAN 总线上的节点不存在主从关系,当收、发节点波特率一致时,为了保证接收节点能够接收到发送节点的特定报文,接收节点必须结合期望报文包中的ID(消息标识符)正确配置筛选器。CAN2.0协议支持两种数据帧格式,分别是ID为11位的标准帧和ID为29位的扩展帧。本文实验根据ID的取值范围对两种帧格式下的筛选器进行了设置,因此支持对两种帧格式报文的接收。
2.1 发送报文自适应波特率
当新节点作为发送节点加入到未知 CAN 网络中时,若该节点的波特率与 CAN 网络的波特率不一致,则会导致测试报文发送失败,用户通过查询对应的 TXOKx 位,即可获取报文的最终发送状态。若确定当前波特率与网络波特率不匹配,则可通过轮询波特率列表来更改波特率,然后再次发送测试报文,若发送成功,则波特率匹配成功。发送报文实现波特率自适应的软件流程图如图3所示。
图3 发送报文波特率自适应流程图
图3中,设置轮询次数为100次,也可适当减小该值以加快波特率的匹配。在发送测试报文后,通过查询CAN_TSR 寄存器中 TXOKx 位来判断发送状态,这里需要注意的是,在执行查询操作前一定要留足够的等待时间确保硬件能够完成数据的传输。由于波特率列表包含的最小波特率为20 kb/s,即传输一位所需要的时间为50μs,而一帧报文(含填充位)的最大长度不会超过150位,当 APB 总线时钟频率为42 MHz时可计算出查询状态所需的等待时间不会超过7.5 ms。在初次确定波特率正确后,通过重置轮询次数对识别结果进行再次确认,目的是尽可能提高识别的准确性,避免误判。若第二次仍能满足波特率匹配条件,则说明当前波特率与网络波特率确实一致,匹配成功。
2.2 接收报文自适应波特率
通常,原有 CAN 网络的节点都是会通过总线向网络广播报文的,因此,加入网络的新节点也可以根据接收报文的状态来修正波特率,从而达到自适应网络波特率的目的。bxCAN 模块为用户提供了错误状态寄存器 CAN_ ESR,通过查询该寄存器,可以获取总线当前的网络状态及错误信息。采用接收报文匹配波特率时,需要将新节点配置为静默模式,此时节点可以接收数据帧,但不具备发送功能。此外,为了保证新节点能够接收到任意数据包,需要将筛选器配置为标识符掩码模式,并设置掩码为0。然后,定期查询 CAN_ESR 寄存器的状态,若查询到节点产生持续错误,则可认定新节点的波特率与网络波特率不匹配,修正波特率直到查询的状态无误为止。通过接收报文实现新节点波特率自适应的软件流程图如图4所示。
图4 接收报文波特率自适应流程图
错误状态寄存器 CAN_ESR 包含了接收错误计数器 REC、发送错误计数器 REC、上一次错误代码 LEC 等错误信息,并且还能根据收、发错误计数器的值对错误警告标志 EWGF、错误被动标志 EPVF及总线关闭标志 BOFF 进行设置。由于采用接收报文匹配波特率时CAN的模式被设置为静默模式,因此不会产生发送错误,也不会标记 BOFF 位。而错误代码及其他标志的设置,均由 REC 的值决定,当接收期间产生错误时,REC 值会增加,而成功接收数据后该值能够按1 递减,若能连续接收成功,则该值最终会递减到0。因此,为简化波特率匹配条件,图4 中根据 CAN_ESR 是否为0来记录错误次数。
图4中,报文的接收并未开启中断,原因是在波特率不匹配时会因为接收错误而频繁进出中断,一定程度上会增加CPU的开销。在自适应波特率期间,若查询到 FIFO(FirstInFirstOut)中有报文,则应及时从 FIFO 输出邮箱中读取报文并释放邮箱,以保证其他邮箱中的报文能够被正确读取。在确认波特率匹配成功后,CAN 的工作模式需配置为正常模式以实现收、发报文功能,筛选器也需根据接收报文的需求重新进行设置。此外,为了提高报文接收效率,应开启接收中断。
3
测试
为了方便对波特率自适应算法进行测试,这里定义10个消息标识符,其中标准ID和扩展ID各占5个。消息标识符具体定义如下:
uint32_tmsg_id[10]=
{0x111,0x222,0x333,0x444,0x555,0x11111,0x22222, 0x33333,0x44444,0x5555};
此外,设计10条报文,对应的数据部分定义如下:
uint8_tmsg_data[10][8]=
{"one","two","three","four","five","six","seven", "eight","nine","ten"};
3.1 发送报文自适应波特率测试
新节点接入 CAN 网络后,每隔50 ms发送一次测试报文。为了在波特率匹配成功时能够直观地看到接收节点收到的测试报文,这里取测试报文的ID 为0x111(可取 ID 列表中任意值),测试报文的内容取"hello"。匹配成功后,新节点每隔50 ms从 msg_data[10][8]中读取一条报文并广播到网络,接收节点收到报文后通过串口打印出来。通过发送报文实现波特率自适应的测试结果如图5所示。
图5 发送报文自适应波特率的测试结果
图5中,左侧部分为新增节点轮询波特率列表时的输出结果,当波特率切换为100kb/s时,与 CAN 网络的波特率匹配成功并完成了系统初始化。右侧部分为接收节点输出结果,当波特率匹配成功后,接收节点正确地打印了新增节点发送的数据。
3.2 接收报文自适应波特率测试
新增节点接入 CAN 网络后,配置工作模式为静默模式,并监听网络上所有数据包,之后在规定时间内每隔10 ms读取一次接收状态,并根据接收状态修改或匹配波特率。当波特率匹配成功时,新节点将接收到的报文数据通过串口打印出来,以表明正确匹配了网络波特率。通过接收网络报文实现波特率自适应的测试结果如图6所示。
图6 接收报文自适应波特率的测试结果
图6中,左侧部分为原网络中发送节点的输出信息,可知此时网络的波特率为 20kp/s;右侧部分为接收节点的结果,当波特率不匹配时轮询波特率列表,当波特率也是20kp/s时实现波特率匹配,之后将接收到的报文数据通过串口正确地输出。
4
结语
本文通过对 STM32F407IGT6 片内 bxCAN 模块的研究,设计了 CAN 网络新增节点通过发送报文或接收报文实现网络波特率自适应的算法。实验结果表明,本文算法具有识别率高、稳定可靠、速度快、简单易实现等优点,能有效解决 CAN网络波特率未知时新增节点的波特率配置问题,一定程度上提高了 CAN 网络通信的灵活性。