2、CAN FD帧格式与差异归纳总结

CAN FD 的帧格式,说白了就是经典 CAN 帧的「升级版」。你想想看,经典 CAN 跑了好几十年,数据场才 8 字节,带宽也越来越不够用。所以 CAN FD 在帧结构上做了几处关键改动——不改动的话,也没办法兼容老控制器了。

我刚开始接触 CAN FD 时,最头疼的就是控制场里那几个新加的位:EDL、BRS、ESI。搞混它们,调试时能折腾你一整天。下面我把帧格式从头到尾捋一遍,同时把和经典 CAN 的差异标出来,你对照着看会清晰很多。

CAN FD 数据帧格式

一个完整的 CAN FD 数据帧,由以下几个段组成(以标准帧为例):

  1. SOF(起始帧):1 个显性位,和经典 CAN 完全一样。
  2. 仲裁场:11 位标识符 + RTR(远程发送请求)位。注意:CAN FD 的 RTR 位必须为显性(0),因为 CAN FD 不推荐使用远程帧。
  3. 控制场:这里变化最大。经典 CAN 是 IDE + 保留位 + DLC(4 位);CAN FD 改成了:IDE + EDL + BRS + ESI + DLC。
  4. 数据场:0~64 字节,经典 CAN 最多 8 字节。
  5. CRC 场:17 位或 21 位 CRC,取决于数据长度;经典 CAN 是 15 位。
  6. ACK 场、EOF、ITM:与经典 CAN 基本一致。
我的习惯:在设计驱动时,我会把控制场单独拎出来做位掩码解析。因为 EDL、BRS 这几个位一旦被误判,整个帧就会报格式错误。你可以用 0x0F 遮掉高 4 位来读 DLC,再用 (data[1] & 0x80) 判断 EDL。

控制场中的关键标志位

位名位置功能我踩过的坑
EDL控制场 bit71 表示 CAN FD 帧,0 表示经典 CAN 帧有些老设备会把 EDL=1 误判为错误帧,导致总线关闭
BRS控制场 bit61 启用更高位速率(数据段加速)如果收发器不支持变速,BRS=1 会导致采样错位
ESI控制场 bit5发送节点错误状态标识常用在诊断中判断节点健康,我一般把它映射到状态机

经典 CAN 与 CAN FD 差异对照

直接上表,你看着会更直观。这张表我调了好几次才把关键差异列全,项目中对比着用很方便。

对比项经典 CANCAN FD
最大数据长度8 字节64 字节
位速率(数据段)最高 1 Mbps最高 8 Mbps(取决于收发器)
位速率(仲裁段)与数据段相同可不同,通过 BRS 切换
CRC 长度15 位17 位(≤16 字节)或 21 位(>16 字节)
CRC 计算覆盖SOF~数据场SOF~数据场 + 填充位计数
远程帧支持不推荐(CIA 规范建议禁用)
填充位规则固定每 5 个相同位插 1 个反相位数据段可取消填充,由 CRC 奇偶校验替代
错误状态响应无 ESI 位ESI 位指示发送节点是否处于被动错误
一句总结:CAN FD 的核心改进就是「变帧速 + 变长数据」。你只要把控制场解析对,其他段的处理跟经典 CAN 差别不大。

帧结构对比图

下面这张 SVG 把经典 CAN 和 CAN FD 的帧结构放在一起对比。左边是经典 CAN 数据帧,右边是 CAN FD 数据帧,差异字段用红色标出。你一眼就能看出控制场和数据场的变化。

经典 CAN 与 CAN FD 数据帧结构对比 经典 CAN 数据帧 SOF 11位 ID RTR IDE r0 DLC 数据 (0~8B) CRC 15 ACK EOF CAN FD 数据帧 SOF 11位 ID RTR (0) IDE EDL BRS ESI DLC 数据 (0~64B) 可变速 CRC 17 或 21 ACK EOF 经典段 CAN FD 新增/改动 数据场扩展 ⚠ 注意 EDL=1 时才是 CAN FD 帧;BRS=1 时 数据段才切换到高速率;CRC 长度由 DLC 决定(≤16B 用 17 位,>16B 用 21 位)。

避坑指南

我曾经在一个项目中,把 CAN FD 节点的 BRS 位置了 1,但收发器是普通的 CAN 收发器,结果总线直接报错。后来我查了 datasheet 才发现,必须用支持 CAN FD 变速的收发器(比如 TJA1044GT)才能让 BRS 生效。

强烈建议:如果老设备不支持 CAN FD,不要让它参与同一个 CAN FD 网络。即使 EDL=0 的经典帧能正常发,一旦有节点发了 CAN FD 帧,老设备会立刻检测到格式错误并拉低总线。我建议你在设计阶段就做好「帧类型白名单」。

说到填充位,CAN FD 在数据段可以取消填充。为什么?因为 CRC 覆盖了填充位计数(stuff-bit count),用奇偶校验替代了传统填充。这会减少数据段长度,但同时也要求 CAN 控制器加上填充位计数逻辑。嗯,这里要注意:如果你的 MCU 的 CAN FD 外设不支持这种 CRC 模式,记得把它关掉,否则会 CRC 错误。

我个人习惯在调试 CAN FD 通信时,先用示波器抓一下总线波形。重点看控制场里 EDL 和 BRS 的电平切换是否干净。如果边沿不陡,很可能是收发器速率切换太慢,这时候调一下收发器的 slew rate 参数能解决。