1. 问题背景:热插拔导致的CAN通讯中断
最近在做一个电机控制项目时,遇到了一个让人头疼的问题。我用的是STM32G473芯片,它自带三路FDCAN接口,用来和多个电机驱动器进行通信。在实际测试中发现,当CAN总线连接正常时,通讯一切顺畅,数据收发都没问题。但是一旦在运行过程中拔掉CAN线再重新插上(也就是热插拔操作),CAN通讯就彻底中断了,再也收不到任何数据。
最奇怪的是,如果用专门的CAN分析仪单独测试电机驱动器,热插拔后通讯能自动恢复。这说明问题出在STM32这边,而不是电机驱动器的问题。经过反复测试,发现只有给STM32重新上电才能恢复通讯,这在实际应用中是完全不可接受的——总不能每次插拔一下CAN线就让整个系统重启吧。
2. FDCAN总线错误管理机制深度解析
2.1 CAN错误状态机制
要理解这个问题,我们得先了解CAN总线的错误管理机制。CAN协议定义了一个相当智能的错误状态管理机制,每个CAN节点都有两个错误计数器:TEC(发送错误计数器)和REC(接收错误计数器)。
当节点正常通信时,这两个计数器都保持低位。但是一旦出现通信问题,比如发送失败或者收到错误帧,相应的计数器就会增加。具体来说,发送失败时TEC加8,接收错误时REC加1。成功发送或接收则会减少计数器值。
这种机制让CAN节点能够根据通信状况自动调整状态。当TEC超过127但低于255时,节点进入"错误被动"状态,仍然能通信但会受到一些限制。而当TEC达到或超过255时,节点就会进入"bus-off"状态,这是最严重的状态,节点会完全停止总线通信。
2.2 bus-off状态的触发条件
在实际调试中,我通过读取FDCAN的寄存器发现,热插拔后FDCAN->IR寄存器的BO位被置1了,这确认了节点确实进入了bus-off状态。
为什么热插拔会触发bus-off呢?想象一下这个场景:当CAN线被拔掉时,STM32还在尝试发送数据,但因为物理链路断开,发送当然会失败。如果使能了自动重发功能,STM32会不断重试发送,每次失败都会增加TEC值。短时间内的大量发送失败会让TEC迅速达到255的阈值,从而触发bu


2438

被折叠的 条评论
为什么被折叠?



