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 帧结构知识体系

下面这张图帮你理清五种帧的关系和帧格式的差异:

CAN帧结构知识体系 CAN帧 数据帧 远程帧 错误帧 过载帧 帧格式 7个段:SOF~EOF 数据场0~8字节 RTR位=隐性 无数据场 错误标志+界定符 5种触发条件 过载标志+界定符 接收端忙时触发 标准帧:11位ID 扩展帧:29位ID 标准帧和扩展帧可在同一条总线共存,标准帧优先级更高 标准帧 vs 扩展帧 核心差异 对比项 标准帧 扩展帧 ID长度 11位 29位 实时性 高 较低

2.7 实战要点总结

搞CAN帧结构,记住这几条就够了:

  1. 数据帧是主角,远程帧是配角,错误帧和过载帧是应急机制。
  2. 标准帧和扩展帧的IDE位决定了帧格式,接收节点的掩码设置必须匹配。
  3. 错误帧不是坏事,它是CAN总线自愈能力的体现。但频繁出现错误帧,说明物理层或协议层有问题。
  4. 过载帧很少见,一旦出现,先检查接收节点的处理能力。

重要提醒:我曾经在一个项目中,错误帧和过载帧同时出现,总线几乎瘫痪。最后发现是某个节点的晶振频率偏差太大,导致位时序错乱。所以,帧结构只是表象,底层硬件和时序才是根本。