2. CAN帧结构:数据帧、远程帧、错误帧、过载帧、帧格式(标准帧与扩展帧)
CAN总线上的通信,说白了就是靠五种不同类型的帧来完成的。我刚开始接触CAN协议时,总觉得帧结构很复杂,各种场、位、间隔,看得眼花缭乱。但干久了你会发现,搞懂这五种帧,你就掌握了CAN通信的命脉。
咱们一个一个来拆解。我个人习惯把帧结构比作一封信——有信封(帧起始、仲裁场、控制场)、有正文(数据场)、还有签名(CRC场、应答场、帧结束)。
2.1 数据帧:最常用的帧
数据帧负责把数据从发送节点传到接收节点。你想想看,总线上跑得最多的就是它。
数据帧由7个段组成:
- 帧起始(SOF):1个显性位,告诉总线“我要开始发了”。
- 仲裁场:包含11位(标准帧)或29位(扩展帧)标识符,外加RTR位。
- 控制场:6位,包含IDE位、保留位和DLC(数据长度码)。
- 数据场:0~8字节,真正要传的数据。
- CRC场:15位CRC校验码+1位CRC界定符。
- 应答场(ACK):2位,发送方发隐性位,接收方拉显性表示收到。
- 帧结束(EOF):7个隐性位。
关键点:数据帧的DLC字段只表示数据字节数(0~8),不是数据本身。我曾经遇到一个同事把DLC当数据用,结果调试了整整两天才发现问题。
2.2 远程帧:请求数据的“问路者”
远程帧说白了就是“我想要数据”。它和数据帧结构几乎一样,唯一的区别是RTR位为隐性(1),而且没有数据场。
我举个例子:假设节点A需要温度传感器节点B的数据,A就发一个远程帧,标识符和B的数据帧一致。B收到后,自动发送对应的数据帧。
实战经验:远程帧的DLC必须和对应数据帧的DLC一致,否则接收节点不会响应。我踩过这个坑——DLC写错了,节点死活不回数据。
2.3 错误帧:总线的“警报器”
错误帧是CAN总线自我纠错的核心机制。一旦任何节点检测到错误,就会立即发送错误帧,通知所有节点“刚才那帧作废”。
错误帧由两部分组成:
- 错误标志:6个相同极性的位(主动错误节点发6个显性位,被动错误节点发6个隐性位)。
- 错误界定符:8个隐性位。
错误帧的触发条件有五种:位错误、填充错误、CRC错误、形式错误、应答错误。嗯,这里要注意——错误帧一旦发出,当前传输的数据帧就被破坏了,发送节点会自动重发。
避坑指南:我曾经在一个项目中,总线频繁出现错误帧,查了三天才发现是终端电阻虚焊导致的信号反射。错误帧本身不是问题根源,它只是告诉你“出事了”。
2.4 过载帧:总线的“慢下来”信号
过载帧用得不多,但关键时刻能救命。它表示接收节点“我处理不过来了,你慢点发”。
过载帧的结构和错误帧很像:
- 过载标志:6个显性位。
- 过载界定符:8个隐性位。
触发条件有两个:一是接收节点内部条件未准备好(比如缓冲区满了),二是帧间隔的间歇场检测到显性位(这属于总线错误,但用过载帧处理)。
2.5 帧格式:标准帧 vs 扩展帧
标准帧和扩展帧的区别,说白了就是标识符的长度不同。
| 对比项 | 标准帧 | 扩展帧 |
|---|---|---|
| 标识符长度 | 11位 | 29位 |
| 最大节点数 | 约2032个 | 约5.36亿个 |
| IDE位 | 显性(0) | 隐性(1) |
| 帧长度 | 较短,实时性好 | 较长,灵活性高 |
| 应用场景 | 汽车动力、底盘等实时控制 | 车载诊断、信息娱乐等复杂系统 |
我个人习惯:能用标准帧就别用扩展帧。为什么?因为标准帧短,总线利用率高,实时性好。但如果你需要大量节点或者复杂的标识符分配,扩展帧是唯一选择。
小技巧:标准帧和扩展帧可以在同一条总线上共存,但它们的优先级比较规则不同。标准帧的11位标识符和扩展帧的前11位标识符比较时,标准帧的RTR位是显性,扩展帧的SRR位是隐性,所以标准帧永远比相同前11位ID的扩展帧优先级高。
2.6 帧结构知识体系
下面这张图帮你理清五种帧的关系和帧格式的差异:
2.7 实战要点总结
搞CAN帧结构,记住这几条就够了:
- 数据帧是主角,远程帧是配角,错误帧和过载帧是应急机制。
- 标准帧和扩展帧的IDE位决定了帧格式,接收节点的掩码设置必须匹配。
- 错误帧不是坏事,它是CAN总线自愈能力的体现。但频繁出现错误帧,说明物理层或协议层有问题。
- 过载帧很少见,一旦出现,先检查接收节点的处理能力。
重要提醒:我曾经在一个项目中,错误帧和过载帧同时出现,总线几乎瘫痪。最后发现是某个节点的晶振频率偏差太大,导致位时序错乱。所以,帧结构只是表象,底层硬件和时序才是根本。