4. CAN总线错误处理:错误类型、错误计数器、错误状态机、故障界定
大家好,我是老张。今天我们来聊聊CAN总线里一个特别重要的机制——错误处理。说实话,我刚入行那会儿,总觉得错误处理是“出了问题才需要看的东西”。后来在项目里吃过亏,才明白:不懂错误处理,你连CAN总线为什么“罢工”都查不出来。
这一章,我会把错误类型、计数器、状态机、故障界定这四块内容串起来讲。你想想看,CAN总线为什么能在恶劣的工业环境里活得好好的?靠的就是这套自我诊断和恢复的机制。
4.1 错误类型:CAN节点会犯哪些“错”?
CAN协议定义了5种错误。我习惯把它们分成两类:“发错了”和“收错了”。
| 错误类型 | 英文名 | 触发条件 | 属于哪类 |
|---|---|---|---|
| 位错误 | Bit Error | 发送节点监控总线,发现发送的电平与监控到的电平不一致 | 发错了 |
| 填充错误 | Stuff Error | 连续6个相同电平出现,违反位填充规则 | 收错了 |
| CRC错误 | CRC Error | 接收节点计算的CRC与发送的CRC不匹配 | 收错了 |
| 格式错误 | Form Error | 检测到固定格式位(如CRC界定符、ACK界定符)的电平错误 | 收错了 |
| 应答错误 | ACK Error | 发送节点在ACK槽位没有检测到显性电平(即无人应答) | 发错了 |
重点记忆:位错误和应答错误是“发送节点”自己报的错。其他三种是“接收节点”报的错。这个区分很重要,后面讲状态机时会用到。
我记得有一次,客户反馈说某款ECU偶尔会丢帧。我抓了CANlog一看,全是CRC错误。排查了半天,发现是晶振精度超标了。嗯,硬件上的小偏差,在高速CAN下就会被放大。
4.2 错误计数器:两个“记分牌”
每个CAN节点内部都有两个计数器:发送错误计数器(TEC)和接收错误计数器(REC)。说白了,就是给节点自己记分。
- TEC(Transmit Error Counter):发送节点出错时增加,成功发送时减少。
- REC(Receive Error Counter):接收节点出错时增加,成功接收时减少。
具体怎么加减?我列个表,你一看就明白:
| 事件 | TEC变化 | REC变化 |
|---|---|---|
| 发送节点检测到位错误或ACK错误 | +8 | — |
| 接收节点检测到CRC、填充、格式错误 | — | +1 |
| 节点作为接收者,检测到显性错误标志 | — | +1 |
| 节点作为发送者,检测到显性错误标志 | +8 | — |
| 成功发送一帧 | -1(最小到0) | — |
| 成功接收一帧 | — | -1(最小到0) |
我的小技巧:调试时,我习惯用CAN工具同时监控TEC和REC。如果REC持续增长,说明总线干扰大,大家都在收错。如果TEC猛涨,那多半是这个节点自身有问题,比如发送电路故障。
4.3 错误状态机:节点的“三级警戒”
根据TEC和REC的值,节点会处于三种状态之一。我管它叫“三级警戒”:
- 错误主动(Error Active):TEC < 127 且 REC < 127。正常状态,节点可以正常收发,出错时发送“主动错误标志”(6个显性位)。
- 错误被动(Error Passive):TEC > 127 或 REC > 127。节点还能收发,但出错时只能发送“被动错误标志”(6个隐性位)。说白了,就是“我错了,但我小声说”。
- 总线关闭(Bus Off):TEC > 255。节点彻底闭嘴,不再参与任何总线通信。
注意:总线关闭状态只能通过硬件复位或软件请求才能恢复。我曾经见过一个项目,节点频繁进入Bus Off,结果发现是CAN收发器的共模电压出了问题。嗯,硬件设计上的坑,往往在错误状态机里最先暴露。
为什么会这样设计?你想想看,如果一个节点老是发错,它会不断干扰总线。让它“闭嘴”反而是保护了其他节点。这就是CAN的“容错”哲学——牺牲个体,保全整体。
4.4 故障界定:谁才是“坏节点”?
故障界定,说白了就是CAN协议如何判断“这个节点是不是坏了”。它不靠外部诊断,全靠内部计数器的逻辑。
我总结了一个简单的判断逻辑:
- 如果TEC涨得比REC快:说明这个节点发送有问题,可能是发送电路、晶振、或者软件发送逻辑有bug。
- 如果REC涨得比TEC快:说明总线环境有问题,或者这个节点的接收电路灵敏度不够。
- 如果TEC和REC一起涨:嗯,那可能是总线物理层出了大问题,比如终端电阻丢失、短路等。
实战经验:我曾经处理过一个案例,某节点在高温下频繁进入Error Passive。我抓了TEC/REC曲线,发现REC在高温下从0涨到150,TEC几乎不变。判断是接收器高温性能下降。换了颗车规级的收发器,问题解决。你看,计数器数据就是最好的诊断线索。
4.5 避坑指南:我踩过的三个坑
最后,分享几个我亲身经历过的教训:
- 别忽视“隐性错误”:Error Passive状态下,节点虽然还能工作,但它的被动错误标志可能会被其他节点忽略。我曾经遇到一个系统,某个节点长期处于Error Passive,导致总线偶尔出现“无主”状态。查了三天才发现。
- Bus Off恢复策略要谨慎:有些工程师喜欢让节点自动恢复,但频繁的恢复-关闭-恢复会严重干扰总线。我建议:至少等待100ms以上再尝试恢复,并且限制恢复次数。
- 计数器不是万能的:TEC和REC只能反映“错误次数”,不能告诉你“错误原因”。所以,一定要结合CANscope或CANlog的波形分析,才能定位根因。
好了,这一章的内容就到这里。错误处理是CAN总线的“免疫系统”,理解了它,你就能在项目里少走很多弯路。下一章,我们会聊CAN的位时序与同步,那是理解CAN速率和采样点的关键。咱们下期见。