4. CAN FD 错误检测机制:位错误、填充错误、CRC 错误、格式错误、ACK 错误

在实际抓波形之前,咱们得先把 CAN FD 的错误检测机制理清楚。我之前带过不少新人,上来就对着逻辑分析仪乱戳,结果波形出来了,一看全是红色标记,根本不知道错在哪。其实说白了,CAN FD 的错误检测就五类,每一类都有明确的触发条件。搞懂了这些,你再看错误帧,心里就有底了。

4.1 位错误(Bit Error)

位错误是最基础的,也最常见。规则很简单:发送节点往总线送一个显性位(逻辑 0),结果回读时却读到了隐性位(逻辑 1),或者反过来——我想送隐性,读到显性,那立刻报错。

个人习惯:我调试时遇到位错误,第一反应不是查 CRC,而是先看终端电阻和电压。很多所谓“器件烧了”的故障,其实就是某个节点把电平拉反了,或者线缆太长导致回读延迟。

这里有个关键点:仲裁期间不会触发位错误。为什么?因为仲裁本身就是多个节点同时发显性位抢总线,这时候读到的电平不一致是正常的。只有在仲裁结束后,才能用位错误来判断总线竞争是否正常结束。

4.2 填充错误(Stuff Error)

CAN 协议规定:连续发送 5 个相同电平后,必须插入一个相反的电平。这叫“位填充”。如果接收方发现连续 6 个相同电平,那就判定为填充错误。CAN FD 的数据场采用了更灵活的填充规则,但原理是一样的——防止时钟同步丢失。

避坑:我曾经在测试台上发现 CAN FD 一直报填充错误,查了半天,结果是逻辑分析仪的采样率不够,把本该是填充位的边沿给漏了。所以抓 CAN FD 时,采样率至少设到 80 MHz,最好 100 MHz 以上。

位填充的另一个作用是保持时钟同步。每个上升沿或下降沿都能让接收节点重新同步采样点。我记得第一次做 CAN FD 通信时,数据段速率到了 5 Mbps,填充规则一旦被破坏,整个网络就像多米诺骨牌一样连续报错。

4.3 CRC 错误

CRC 错误是数据完整性检查的最后一道防线。发送节点会根据报文内容计算出一个 17 位或 21 位的 CRC 校验和(CAN FD 的 CRC 比经典 CAN 长),接收节点用同样的算法重新算一遍,如果结果不匹配,就报 CRC 错误。

我在项目里遇到过一种情况:总线终端匹配不良导致信号反射,反射波叠加到正确的电平上,使得某些位被误判。CRC 能检查出这种“看起来像合法数据但实际上已经变形”的情况。所以当你看到连续多个 CRC 错误时,别急着怀疑芯片,先检查一下物理层。

错误类型 检测方 触发条件
位错误 发送方 发送电平与回读电平不一致(仲裁期间除外)
填充错误 接收方 连续 6 个相同电平
CRC 错误 接收方 本地 CRC 计算结果与接收到的 CRC 段不匹配
格式错误 接收方 固定隐性电平的场段被读成显性
ACK 错误 发送方 在 ACK 槽内未读到显性位(无节点确认)

4.4 格式错误(Form Error)

CAN FD 的帧格式里有一些**固定电平**的段——比如 CRC 分隔符、ACK 分隔符、EOF(帧结束)。这些段必须保持隐性。如果接收方在这些段上读到了显性位,那就触发格式错误。嗯,这个东西很刁钻。

我记得有一次,客户的 CAN FD 节点在高温环境下频繁报格式错误。后来发现是 RXD 引脚上的噪声毛刺被误判成显性位。解决办法很简单:在 RXD 上串一个 1 kΩ 电阻,或者调整 CAN 控制器的数字滤波参数。格式错误的定位往往比位错误更难,因为它的触发点很窄(就几个 bit 时间),逻辑分析仪一定要把时基调小才能看清。

4.5 ACK 错误(Acknowledgment Error)

发送节点在 ACK 槽期间(紧跟着 CRC 分隔符之后)会释放总线,如果此时没有其他节点主动拉低总线(即发送显性位来确认),发送节点就会读到隐性,于是报 ACK 错误。这说明你的报文发出来了,但没有节点收到并正确通过 CRC 校验。

实战套路:当逻辑分析仪上出现 ACK 错误时,我通常按以下顺序排查:
1. 检查总线终端电阻(缺一个就没法把显性位拉到底)
2. 检查接收节点的 CAN 控制器是否处于 BusOff 状态
3. 检查接收节点的验收滤波是否把该报文过滤掉了
4. 如果以上都正常,用差分探头量一下 CAN_H 和 CAN_L 之间的压差,看看显性位是否真的能达到 1.5 V 以上。

ACK 错误还有个特殊场景:CAN FD 的采样点兼容性问题。不同厂家的 CAN FD 控制器采样点位置可能不同(比如有的设在 75%,有的设在 80%),如果采样点误差太大,接收方可能在 ACK 槽上采样失败。我个人习惯在设计阶段就统一所有节点的采样点,避免这种隐形坑。

4.6 五种错误的地图式归纳

下面这张 SVG 图把这五种错误检测机制的关系画出来了。你拿到逻辑分析仪波形后,先看错误帧的类型,再对照这张图找到可能的根因,排查效率能提升不少。

CAN FD 错误检测体系 错误活动(Error Active) 位错误 发送电平回读不一致 填充错误 连续6个相同电平 CRC 错误 校验和失配 格式错误 固定隐性被读成显性 ACK 错误 无节点确认应答 💡 排查路径建议 位错误/ACK错误 → 查物理层(终端电阻、电平、线缆) 填充错误/CRC错误/格式错误 → 查控制器配置(采样点、位时序、滤波)

4.7 错误状态机与恢复

说了这么多错误检测,最后补一句状态机。CAN 控制器内部有三个状态:错误活动(Error Active)、错误被动(Error Passive)、总线关断(Bus Off)。每个节点内部有发送错误计数器和接收错误计数器,累计到一定阈值就会切换状态。错误活动状态下的节点在检测到错误后会发送主动错误标志(6 个显性位);错误被动状态下的节点只能发送被动错误标志(6 个隐性位);一旦进入 Bus Off,节点完全退出总线,不再参与任何通信。

实战小技巧:如果逻辑分析仪上看到大量连续错误,但没有任何显性标志位出现,那很可能是有节点处于 Error Passive 状态,只能发隐性错误标志,其他节点收不到,导致错误帧畸形。这时候需要用 CAN 工具读一下错误计数器,看哪个节点数值异常。