3、CAN数据链路层协议:CAN帧结构

各位工程师朋友,咱们今天聊聊CAN数据链路层的核心——帧结构。说实话,搞懂帧结构,你就掌握了CAN通讯的“语法”。我刚开始接触CAN时,对着协议文档看了三天,脑子里还是一团浆糊。后来自己动手抓了几次波形,才真正明白每一比特的意义。

CAN总线上的数据,是以“帧”为单位传输的。就像我们说话,一句一句地说。每一帧都有固定的格式,包含多个场(Field)。咱们一个一个拆开看。

3.1 标准帧结构:SOF到EOF

一个完整的CAN数据帧,由7个部分组成。我习惯把它想象成一封挂号信:

  • SOF(帧起始):1个显性位。相当于信封上的“开始”标记。总线空闲时,谁先拉低电平,谁就抢到了发言权。
  • 仲裁场:包含11位标识符(ID)和1位RTR位。这是帧的“地址”,决定了优先级。
  • 控制场:6位。包含IDE位、保留位r0、以及4位DLC(数据长度码)。DLC告诉你数据场有多少字节。
  • 数据场:0~8字节。这就是你要发送的实际数据。比如转向角度、车速信号。
  • CRC场:15位CRC序列 + 1位CRC界定符。这是校验码,确保数据没被干扰。
  • ACK场:2位。接收节点如果正确收到,会在ACK槽位发送显性位,告诉发送方“我收到了”。
  • EOF(帧结束):7个隐性位。表示这帧结束了。

核心要点:SOF和EOF是帧的“边界”。仲裁场决定了谁能说话。CRC是数据完整性的最后防线。

嗯,这里要注意:EOF必须是7个连续的隐性位。如果少于7个,总线会认为帧不完整,触发错误帧。我在调试一个EPS(电动助力转向)项目时,就遇到过因为电磁干扰导致EOF被拉低,整条总线疯狂报错的情况。

3.2 标准帧 vs 扩展帧

为什么要有两种帧?说白了,就是地址不够用了。标准帧的ID只有11位,最多2048个不同的ID。对于早期的简单系统,够用了。但现在的汽车,一个网关要管理几十个ECU,11位ID根本不够分。

扩展帧把ID扩展到了29位。怎么做到的?它把控制场里的IDE位利用起来了:

特性 标准帧 扩展帧
ID长度 11位 29位
仲裁场结构 11位ID + RTR 11位基础ID + SRR + IDE + 18位扩展ID + RTR
控制场IDE位 显性(0) 隐性(1)
帧长度 较短 较长
兼容性 所有节点都支持 需要节点支持扩展帧

我个人习惯:在转向系统中,如果节点不多(比如只有方向盘转角传感器、EPS控制器、ESC),用标准帧就够了。但如果要跟ADAS(高级驾驶辅助)系统交互,建议用扩展帧,因为ADAS的ID分配往往很复杂。

避坑指南:我曾经在一个项目中,混合使用了标准帧和扩展帧。结果发现,标准帧的优先级总是高于扩展帧。为什么?因为标准帧的IDE位是显性(0),而扩展帧的IDE位是隐性(1)。在仲裁时,显性位胜出。所以,如果你希望某个消息优先发送,用标准帧。

3.3 远程帧与错误帧

这两种帧比较特殊,不是用来传数据的。

远程帧:说白了,就是“请求帧”。一个节点发送远程帧,告诉另一个节点:“请把你那个ID的数据发给我”。远程帧没有数据场,但DLC字段必须与请求的数据长度一致。你想想看,这就像你给同事发了个空信封,上面写着“请把报告放进来”。

远程帧的结构和数据帧几乎一样,唯一的区别是RTR位为隐性(1)。数据帧的RTR是显性(0)。

错误帧:这是CAN总线的“自我修复”机制。当任何节点检测到总线错误(比如位错误、填充错误、CRC错误、格式错误、ACK错误),它会立即发送错误帧。错误帧由6个连续的显性位(错误标志)和8个隐性位(错误界定符)组成。

错误帧的作用是:强制中断当前传输,通知所有节点“刚才那帧有问题,别用了”。然后发送节点会自动重发。这就是CAN总线可靠性高的原因之一。

重要提醒:错误帧不是用来“纠正”错误的,而是用来“通知”错误的。如果总线错误率太高,节点会进入“错误被动”甚至“总线关闭”状态。我在调试一个转向柱锁模块时,就遇到过因为线束接触不良,导致节点频繁发送错误帧,最后把自己“关”出总线的情况。

3.4 知识体系图:CAN帧结构全景

下面这张图,是我自己总结的CAN帧结构全景图。你可以把它当作一个“速查手册”。

CAN数据帧结构全景图 SOF 1位 仲裁场 12/32位 控制场 6位 数据场 0~64位 CRC场 16位 ACK场 2位 EOF 7位 标准帧 (11位ID) • ID范围: 0x000 ~ 0x7FF • 仲裁场: 11位ID + RTR • IDE位: 显性 (0) • 帧长度: 最短 • 适用: 简单系统, 高优先级消息 扩展帧 (29位ID) • ID范围: 0x00000000 ~ 0x1FFFFFFF • 仲裁场: 11位基础ID + SRR + IDE + 18位扩展ID + RTR • IDE位: 隐性 (1) • 帧长度: 较长 • 适用: 复杂系统, 多节点网络 远程帧 • 作用: 请求其他节点发送数据 • 特点: 无数据场, RTR位为隐性 • DLC: 必须与请求的数据长度一致 • 应用: 轮询传感器数据 错误帧 • 作用: 通知总线发生错误 • 结构: 6位错误标志 + 8位错误界定符 • 触发条件: 位错误, 填充错误, CRC错误等 • 后果: 发送节点自动重发

这张图把标准帧、扩展帧、远程帧、错误帧都放在了一起。你可以看到,它们共享相同的SOF、控制场、CRC、ACK、EOF结构,区别主要在仲裁场和数据场。我个人建议你把这张图打印出来,贴在工位上,调试时一眼就能找到问题。

好了,关于CAN帧结构,咱们就聊到这里。记住:SOF是开始,EOF是结束,仲裁场决定谁说话,CRC保证数据没错,ACK告诉发送方“我收到了”。远程帧是“请求”,错误帧是“报警”。搞懂这些,你就能读懂CAN总线上跑的任何一帧数据了。


公众号:蓝海资料掘金营,微信deep3321