3、CAN协议基础:CAN帧的种类与帧格式

大家好,我是你们的CAN总线讲师。今天我们来聊聊CAN协议里最核心的东西——帧。

说实话,我刚接触CAN的时候,被这几种帧搞得有点晕。数据帧、远程帧、错误帧、过载帧……名字都差不多。但干过几个项目后,我发现其实没那么复杂。今天我就带你捋一遍。

3.1 CAN帧的四种类型

CAN总线上跑的数据,说白了就是这四种帧。我习惯把它们分成两类:正常通信用的异常处理用的

3.1.1 数据帧

这是最常用的帧。你想发数据?就用它。数据帧负责把信息从一个节点传到另一个节点。

数据帧的结构是这样的:

帧起始 + 仲裁场 + 控制场 + 数据场 + CRC场 + 应答场 + 帧结束

其中数据场最多可以放8个字节。为什么是8个?我猜是当年设计者觉得够用了。确实,大部分传感器信号、控制指令,8个字节绰绰有余。

我的经验:实际项目中,我很少把8个字节全用满。一般用4-6个字节就够了。留点余量,方便以后扩展。

3.1.2 远程帧

远程帧有点意思。它不传数据,只传一个请求。说白了就是:“喂,谁有某某数据?发给我!”

我记得有一次调试一个电机控制器,发现总线上老是出现远程帧。查了半天,原来是一个传感器节点没收到数据,一直在发请求。嗯,这里要注意:远程帧的ID必须和数据帧的ID一致,否则对方收不到。

避坑指南:我曾经在一个项目中,远程帧和数据帧的ID没对齐,结果总线上一片混乱。后来我养成了习惯:每次设计通信矩阵时,都把远程帧的ID和数据帧的ID放在一起核对。

3.1.3 错误帧

错误帧是CAN总线的“报警器”。当某个节点检测到错误,就会主动发送错误帧。错误帧由两部分组成:错误标志错误界定符

错误帧一旦出现,总线上的所有节点都会收到通知。然后大家会一起重发刚才的数据。这就是CAN总线的高可靠性所在——出错就重来

你想想看,如果总线上错误帧太多,说明什么?说明通信质量有问题。我曾经在一个工厂现场遇到过,总线错误帧比例高达5%。后来发现是屏蔽层接地没做好。

3.1.4 过载帧

过载帧比较少见。它表示:“我太忙了,慢点发!”

过载帧的结构和错误帧很像,但触发条件不同。过载帧是节点主动发出的,表示自己处理不过来。错误帧是被动检测到的。

说实话,我做了这么多年CAN开发,过载帧只遇到过两次。一次是某个老旧的ECU处理速度太慢,另一次是总线负载率超过了90%。

3.2 帧格式:标准帧与扩展帧

帧格式这块,说白了就是ID长度的区别。

3.2.1 标准帧

标准帧的ID是11位。范围从0x000到0x7FF,一共2048个ID。够用吗?早期CAN网络节点少,够用。现在嘛……

标准帧的格式:

帧起始(1位) + ID(11位) + RTR(1位) + IDE(1位) + r0(1位) + DLC(4位) + 数据场(0-8字节) + CRC(15位) + 应答(2位) + 帧结束(7位)

3.2.2 扩展帧

扩展帧的ID是29位。范围大得多,可以到0x1FFFFFFF。现在的新车基本都是扩展帧了。

扩展帧的格式:

帧起始(1位) + ID(11位) + SRR(1位) + IDE(1位) + ID扩展(18位) + RTR(1位) + r1,r0(2位) + DLC(4位) + 数据场(0-8字节) + CRC(15位) + 应答(2位) + 帧结束(7位)

我个人的习惯是:能用标准帧就用标准帧。为什么?因为标准帧的仲裁优先级更高,而且传输效率也高一点。但如果你需要很多ID,那就只能用扩展帧了。

关键区别:
  • 标准帧:11位ID,优先级高,适合简单网络
  • 扩展帧:29位ID,ID数量多,适合复杂网络
  • 两者可以共存于同一总线,但标准帧优先级更高

3.3 帧格式对比表

特性 标准帧 扩展帧
ID长度 11位 29位
ID范围 0x000 - 0x7FF 0x00000000 - 0x1FFFFFFF
仲裁优先级
传输效率 略低
适用场景 简单网络 复杂网络

3.4 我的建议

好了,总结一下我的个人经验:

  1. 先搞清楚你的网络规模。节点少、ID少,用标准帧就够了。节点多、ID多,老老实实用扩展帧。
  2. 不要混用标准帧和扩展帧。虽然技术上可以,但容易出问题。我见过一个项目,标准帧和扩展帧混用,结果仲裁优先级搞乱了,调试了三天。
  3. 错误帧和过载帧要监控。它们虽然不传数据,但能反映总线健康状况。我习惯在测试工具里设置一个计数器,专门统计错误帧和过载帧的数量。

最后说一句:CAN帧的种类和格式,是理解CAN协议的基础。你把这些搞清楚了,后面读报文、分析数据就轻松多了。下一章我们聊聊CAN的仲裁机制,那个更有意思。

今天就到这里。有什么问题,欢迎交流。