3、CAN协议基础:CAN帧的种类与帧格式
大家好,我是你们的CAN总线讲师。今天我们来聊聊CAN协议里最核心的东西——帧。
说实话,我刚接触CAN的时候,被这几种帧搞得有点晕。数据帧、远程帧、错误帧、过载帧……名字都差不多。但干过几个项目后,我发现其实没那么复杂。今天我就带你捋一遍。
3.1 CAN帧的四种类型
CAN总线上跑的数据,说白了就是这四种帧。我习惯把它们分成两类:正常通信用的和异常处理用的。
3.1.1 数据帧
这是最常用的帧。你想发数据?就用它。数据帧负责把信息从一个节点传到另一个节点。
数据帧的结构是这样的:
帧起始 + 仲裁场 + 控制场 + 数据场 + CRC场 + 应答场 + 帧结束
其中数据场最多可以放8个字节。为什么是8个?我猜是当年设计者觉得够用了。确实,大部分传感器信号、控制指令,8个字节绰绰有余。
3.1.2 远程帧
远程帧有点意思。它不传数据,只传一个请求。说白了就是:“喂,谁有某某数据?发给我!”
我记得有一次调试一个电机控制器,发现总线上老是出现远程帧。查了半天,原来是一个传感器节点没收到数据,一直在发请求。嗯,这里要注意:远程帧的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 我的建议
好了,总结一下我的个人经验:
- 先搞清楚你的网络规模。节点少、ID少,用标准帧就够了。节点多、ID多,老老实实用扩展帧。
- 不要混用标准帧和扩展帧。虽然技术上可以,但容易出问题。我见过一个项目,标准帧和扩展帧混用,结果仲裁优先级搞乱了,调试了三天。
- 错误帧和过载帧要监控。它们虽然不传数据,但能反映总线健康状况。我习惯在测试工具里设置一个计数器,专门统计错误帧和过载帧的数量。
最后说一句:CAN帧的种类和格式,是理解CAN协议的基础。你把这些搞清楚了,后面读报文、分析数据就轻松多了。下一章我们聊聊CAN的仲裁机制,那个更有意思。
今天就到这里。有什么问题,欢迎交流。