CAN FD帧结构详解:标准帧与扩展帧

做CAN FD开发,第一件事就是搞懂帧结构。别看帧结构图密密麻麻都是位,其实核心就几个关键点。我个人习惯把这章内容分成三部分:标准帧和扩展帧的区别、新加入的特殊位、还有帧格式对比。你把这些记住了,后面看任何报文都不会迷糊。

标准帧 vs 扩展帧:别让IDE位骗了你

CAN FD继承了CAN 2.0的两种帧格式。标准帧用11位标识符,扩展帧用29位。区分它们的是IDE位——IDE=0是标准帧,IDE=1是扩展帧。嗯,这里要注意,扩展帧在标准帧的RTR位之后多了一个SRR位,用来替代原RTR的位置。说白了,扩展帧就是把ID空间扩大了,但代价是多占了几个位。

小技巧:我刚开始调试时,用示波器抓波形,看到ID后面跟着个'1'就以为是扩展帧。其实不对——标准帧的RTR如果为1也会让总线看起来像'1'。你得看之后有没有SRR位。后来我改用自己的解码脚本,才彻底搞清楚。

在CAN FD里,标准帧和扩展帧的帧头结构基本一致。不同的是,CAN FD在控制场里新增了EDL位,用来区分是经典CAN还是CAN FD帧。EDL=0是经典CAN,EDL=1是CAN FD。

CAN FD新加的位:BRS、ESI、DFF

这几个位,我建议你作为一个整体来记。它们都出现在CAN FD帧的控制场和CRC场之间。

BRS(Bit Rate Switch)——波特率切换

BRS位就是告诉接收器:后面的数据段要用高速率来采样。我做过一个项目,ECU之间通信用500k的仲裁段,数据段切换到2M。如果BRS=1,发送器会在BRS位之后立刻切换位时间。接收器必须同步,否则就丢帧。

避坑指南:我曾经遇到过一台设备,它的BRS位总是设为0,明明支持CAN FD就是不肯切速率。后来发现是配置时把BRS使能位搞反了。你检查代码时,记得看CAN控制器寄存器里的“BRS Enable”是不是置了位。

ESI(Error State Indicator)——错误状态指示

ESI位由发送节点设置。如果发送节点处于“被动错误”或“总线关闭”状态,ESI=1;否则ESI=0。你想想看,接收器拿到帧后看一下ESI位,就能知道对方是不是快挂了。这在冗余系统里挺有用——如果连续收到ESI=1,就可以提前切换备份链路。

DFF(Data Field Length)——数据场长度

这里说的DFF,其实就是DLC字段编码后的数据场实际字节数。CAN FD允许数据场长度超过8字节,最大64字节。DLC编码规则跟经典CAN不一样:经典CAN的DLC是0-8直接对应字节数;CAN FD里DLC=9对应12字节,10对应16,11对应20,12对应24,13对应32,14对应48,15对应64。我建议你把这个映射表记在调试笔记上,现场看报文时一翻就知。

核心要点:CAN FD帧的数据场长度不是一字节对应一个DLC值,而是分段映射。工程师最容易犯的错误是把DLC=9当作9字节,结果解析出来的数据全是乱的。

帧格式对比表

下面这张表对比了经典CAN和CAN FD的帧结构。我特意把标准帧和扩展帧分两行写,方便你对照。

帧类型 字段序列(头部到CRC前) 数据场最大长度 CRC方法
经典CAN标准帧 SOF + 11位ID + RTR + IDE(r1) + r0 + DLC 8字节 15位CRC
经典CAN扩展帧 SOF + 11位ID + SRR + IDE + 18位ID + RTR + r1 + r0 + DLC 8字节 15位CRC
CAN FD标准帧 SOF + 11位ID + RTR + IDE + EDL + r0 + BRS + ESI + DLC 64字节 17位或21位CRC
CAN FD扩展帧 SOF + 11位ID + SRR + IDE + 18位ID + RTR + r1 + EDL + BRS + ESI + DLC 64字节 17位或21位CRC

你一眼就能看出,CAN FD帧在控制场里多了EDL、BRS、ESI。另外,CAN FD的CRC是分段校验的——数据场长度≤8字节用17位CRC,大于8字节用21位CRC。这也是为了应对大数据场时的误码率问题。

一张图看懂CAN FD帧结构

下面这张SVG图展示了CAN FD扩展帧的完整位排列,我把关键位用不同颜色标出来了。你可以把图存下来当速查卡用。

CAN FD扩展帧结构图 SOF 11位ID SRR IDE 18位扩展ID RTR r1 EDL BRS ESI DLC Data(0-64B) CRC(17/21) ACK 说明 • 蓝色节点:标识符和DLC,负责寻址和长度 • 红色节点:控制位(SRR/RTR/ACK),决定帧类型和应答 • 绿色节点:EDL和Data段,EDL=1表示CAN FD帧,数据场可达64字节 • 紫色节点:BRS,切换数据段波特率;橙色节点:ESI,指示发送器错误状态

实际工程中,你接收一帧CAN FD报文,解析器会先看IDE位判断是否扩展帧,再看EDL位判断是经典CAN还是CAN FD。如果EDL=1,继续看BRS位确定波特率切换点。ESI位我一般用在故障诊断日志里,记录哪些节点经常处于错误状态。

实战中的位解析技巧

你在用示波器或CAN分析仪看波形时,我推荐按下面步骤来:

  1. 找SOF — 显性位下降沿就是帧开始
  2. 判断帧格式 — 在标识符之后看IDE位:如果IDE是隐性(1),后面跟18位扩展ID;如果IDE是显性(0),后面就是控制位
  3. 确认是否CAN FD — 在r1之后找EDL位,隐性(1)就是CAN FD帧
  4. 读BRS和ESI — 接着EDL后面的两个位就是它们,别忘了扫一眼
  5. 解析DLC — 根据DLC值查表得到数据场长度,然后解码数据

我曾经在一个车载网关项目里,用这方法排查出一次CRC校验失败的问题。原因就是BRS位设置成了1,但接收器没切换到高速率,导致数据段采样错位。嗯,这个坑你们在仿真阶段就得多测测。

一句话总结:CAN FD帧结构就是在经典CAN的壳子里,塞进EDL、BRS、ESI三颗新螺丝,再把数据场和CRC都做大了。理解这几个比特位,你就能驾驭所有CAN FD报文。