2、错误帧分类与定义:主动错误帧、被动错误帧、错误帧的构成
好,咱们接着聊错误帧。上一节我讲了错误帧是干啥的——说白了就是总线上的“报警器”。这一节咱们深入看看,这个报警器到底长什么样,分几种,每种又有什么脾气。
我个人习惯把错误帧比作交通警察的哨子。你违规了,哨子就响了。但哨子也分两种:一种是交警吹的,声音大、有威慑力;另一种是协管员吹的,声音小点,提醒你注意。嗯,CAN总线里的错误帧,就是这么回事。
2.1 主动错误帧 vs 被动错误帧
先看分类。CAN协议里,错误帧分两种:主动错误帧和被动错误帧。区别在哪?说白了就是“犯错的人”当前是什么状态。
每个CAN节点内部都有两个计数器:发送错误计数器(TEC)和接收错误计数器(REC)。根据这两个计数器的值,节点会处于三种状态之一:
- 主动错误状态:TEC < 127 且 REC < 127。这是正常状态,节点可以主动发送错误帧。
- 被动错误状态:TEC > 127 或 REC > 127。节点被“警告”了,只能发送被动错误帧。
- 总线关闭状态:TEC > 255。节点彻底“闭嘴”,不再参与任何总线通信。
我在项目中遇到过一种情况:某个节点因为硬件干扰,TEC一路飙升到200多。它明明还在发数据,但发出来的全是被动错误帧。其他节点一看,这哥们儿不行了,纷纷给它发主动错误帧。结果整个总线乱成一锅粥。你想想看,一个“病号”拖着全车人一起遭殃。
核心区别一句话总结:
- 主动错误帧:由主动错误状态的节点发出。它发送6个连续的显性位(主动错误标志),强势打断当前总线通信。
- 被动错误帧:由被动错误状态的节点发出。它发送6个连续的隐性位(被动错误标志),只能“小声提醒”,无法强制打断。
2.2 错误帧的构成:错误标志 + 错误界定符
不管主动还是被动,错误帧的结构都一样——由两部分组成:错误标志和错误界定符。咱们拆开看。
2.2.1 错误标志(Error Flag)
错误标志是错误帧的“核心内容”。它占6个位。但主动和被动在这6个位上表现完全不同:
| 类型 | 位值 | 效果 |
|---|---|---|
| 主动错误标志 | 6个显性位(000000) | 强制覆盖总线上的任何信号,所有节点都能检测到 |
| 被动错误标志 | 6个隐性位(111111) | 如果总线空闲,其他节点可能忽略它 |
这里有个关键点:主动错误标志的6个显性位,会违反CAN协议的“位填充规则”。CAN规定,连续5个相同位之后必须插入一个相反位。但错误标志故意连续发6个显性位,这就是在“故意违规”,让所有节点都意识到出事了。
我曾经调试过一个项目,发现总线上一会儿出现主动错误帧,一会儿又没了。查了半天,原来是一个节点在主动错误和被动错误之间反复横跳。它的TEC刚好卡在127附近,稍微有点干扰就过线。嗯,这种“临界状态”最坑人。
2.2.2 错误界定符(Error Delimiter)
错误标志发完之后,紧接着是错误界定符。它占8个位,全部是隐性位(11111111)。
为什么要加这个界定符?说白了就是给总线一个“冷静期”。错误标志把总线搅乱了,界定符让所有节点有时间同步回来,准备重新开始通信。
我建议你记住这个结构:
错误帧 = 错误标志(6位) + 错误界定符(8位)
主动错误标志:6位显性
被动错误标志:6位隐性
界定符:8位隐性(两者相同)
避坑指南:
我曾经犯过一个低级错误:以为错误界定符是7位。结果在写CAN控制器驱动时,时序总是差一位。查了两天手册才发现,界定符是8位,不是7位。你设计硬件或写驱动时,一定把这点刻在脑子里。
2.3 错误帧的发送时机
错误帧不是随便发的。它只在特定条件下触发:
- 位错误:节点发送位时,监控到的总线位值与发送值不一致。
- 填充错误:接收节点检测到连续6个相同位(违反位填充规则)。
- CRC错误:接收节点计算的CRC与发送节点的不匹配。
- 格式错误:帧格式中的固定位(如CRC界定符、ACK界定符)出现错误值。
- ACK错误:发送节点在ACK槽位没有检测到显性位(没人确认收到)。
你想想看,这五种错误里,填充错误和格式错误是最容易在硬件设计中被忽略的。我见过一个案例:某款MCU的CAN控制器在接收帧时,对CRC界定符的采样点设置偏了,导致偶尔把正确的帧误判为格式错误,然后疯狂发错误帧。最后整个网络瘫痪。
警告:
被动错误帧的6个隐性位,在总线空闲时可能被其他节点的显性位覆盖。这意味着被动错误帧的“威慑力”很弱。如果你的节点频繁进入被动错误状态,它基本就是在“喊救命”,但没人听得见。这时候,赶紧查硬件或软件问题,别指望它能自己恢复。
2.4 一个小例子:主动错误帧的波形
假设总线上正在传输一个数据帧,突然某个节点检测到位错误。它会立刻:
- 在当前位之后,立即发送6个显性位(主动错误标志)。
- 其他节点检测到这6个显性位(违反填充规则),也会同步发送自己的错误标志。
- 所有节点发送完错误标志后,一起发送8个隐性位(错误界定符)。
- 总线进入3位隐性位的“帧间空间”,然后重新开始仲裁。
整个过程,从错误发生到总线恢复,只需要大约十几个位时间。在500kbps的速率下,也就是几十微秒的事。这就是CAN协议健壮性的体现——快速检测、快速恢复。
我个人习惯在调试时用示波器抓一下错误帧的波形。主动错误帧那6个显性位,在波形上就是一条长长的低电平,非常显眼。如果你看到波形上频繁出现这种“长低电平”,那基本可以断定总线出问题了。
2.5 总结一下
这一节咱们把错误帧的“家底”都翻出来了:
- 错误帧分主动和被动两种,取决于节点当前的状态。
- 结构固定:6位错误标志 + 8位错误界定符。
- 主动错误标志是显性,被动是隐性——一个能“砸场子”,一个只能“小声嘀咕”。
- 触发条件有五种,其中填充错误和格式错误是硬件设计的常见坑。
下一节咱们聊聊错误帧对网络健壮性的影响,以及怎么在设计层面避免“错误风暴”。到时候我会分享一个我亲手踩过的坑——一个电容选型错误导致全车CAN网络崩溃的故事。嗯,那真是血的教训。