4. CAN帧结构(上):数据帧格式
各位同学,今天我们来啃CAN协议里最核心的一块——数据帧。说白了,CAN总线上跑的最多的就是这玩意儿。你想想看,ECU之间交换传感器数据、发送控制指令,全得靠它。
我刚开始接触CAN的时候,看着那一堆ID、控制位、CRC,头都大了。后来自己动手抓了几次波形,才真正搞明白每一bit是干嘛用的。今天我就把这点经验分享给你们。
4.1 标准帧 vs 扩展帧:到底差在哪?
CAN 2.0规范定义了两种数据帧格式:标准帧和扩展帧。它们最大的区别,就是ID的长度不一样。
| 对比项 | 标准帧 (Base Frame) | 扩展帧 (Extended Frame) |
|---|---|---|
| ID长度 | 11位 | 29位 |
| IDE位 | 显性 (0) | 隐性 (1) |
| 可用的ID范围 | 0x000 ~ 0x7FF | 0x00000000 ~ 0x1FFFFFFF |
| 帧头开销 | 较小 | 较大(多出17位) |
| 应用场景 | 节点少、实时性高的系统 | 节点多、需要大量ID的系统 |
4.2 ID仲裁域:谁说了算?
仲裁域是CAN帧里最精彩的部分。它决定了当两个节点同时发数据时,谁先发、谁退让。
标准帧的仲裁域包含:11位ID + RTR位。扩展帧则是:11位基础ID + SRR位 + IDE位 + 18位扩展ID + RTR位。
仲裁的规则很简单:ID值越小,优先级越高。为什么?因为CAN总线是“线与”逻辑,显性位(逻辑0)会覆盖隐性位(逻辑1)。
举个例子:
- 节点A发ID = 0x100(二进制:001 0000 0000)
- 节点B发ID = 0x200(二进制:010 0000 0000)
从最高位开始比。第1位都是0,没问题。第2位,A是0(显性),B是1(隐性)。总线被A拉成显性,B检测到总线电平跟自己发的不一样,立刻退出。A胜出,继续发后面的数据。
4.3 控制域:告诉接收方怎么读
控制域紧跟在仲裁域后面。它告诉接收方:这个帧里有多少数据?是数据帧还是远程帧?
标准帧的控制域是6位:
- IDE位:标准帧里是显性(0),表示后面没有扩展ID
- 保留位r0:显性(0),留给未来用
- DLC(4位):数据长度码,范围0~8
扩展帧的控制域也是6位,但结构不同:
- 保留位r1、r0:都是显性(0)
- DLC(4位):同上
4.4 数据域:真正干活的地方
数据域就是帧里装“货”的地方。最多8个字节,最少0个字节。
为什么是8字节?这是CAN协议设计时的权衡。8字节对于大多数控制信号(转速、温度、位置)来说足够了。如果数据量更大,可以拆成多帧发送,或者用CAN FD(后面章节会讲)。
数据域的排列顺序是MSB优先(最高有效字节在前)。比如你要发送一个32位的转速值0x12345678:
字节0: 0x12
字节1: 0x34
字节2: 0x56
字节3: 0x78
字节4~7: 未使用(通常填0)
4.5 CRC校验域:数据完整性最后一道防线
CAN总线上环境很恶劣,电磁干扰、电压波动都可能让数据出错。CRC就是用来检测这些错误的。
CAN数据帧使用15位CRC,生成多项式是:
x^15 + x^14 + x^10 + x^8 + x^7 + x^4 + x^3 + 1
计算范围包括:帧起始 + 仲裁域 + 控制域 + 数据域。发送方算好CRC值,放在CRC域里。接收方用同样的多项式重新算一遍,如果结果不一致,就说明数据被破坏了。
CRC域后面还有1位CRC分隔符(隐性位),用来把CRC和ACK域隔开。
4.6 一张图看懂数据帧全貌
说了这么多,不如直接看一张完整的结构图。下面这张SVG图,把标准数据帧从头到尾的每个域都画出来了。
4.7 避坑指南:我踩过的几个坑
讲完理论,来点实战经验。这些坑我当年都踩过,你们注意绕开。
我曾经在一个项目里,把高优先级信号(比如刹车)的ID设成了0x700,低优先级信号(比如车窗)设成了0x001。结果刹车信号经常被延迟。后来才反应过来,ID越小优先级越高。正确的做法是:关键信号用小编号ID,非关键信号用大编号ID。
有一次调试,发送方DLC设成8,但实际只填了4个字节的数据。接收方把后面4个随机值当成有效数据,导致系统误动作。从那以后,我要求团队必须保证DLC和实际数据长度严格一致。
有些工程师觉得CRC出错概率低,就不处理。我在一个项目里遇到过,总线上一根线接触不良,CRC错误帧暴增。幸好我们做了错误统计和报警,及时发现了问题。记住:CRC出错不是“不可能”,而是“什么时候发生”的问题。
4.8 小结
这一章我们拆解了CAN数据帧的每个域。从SOF到EOF,每一bit都有它的使命。标准帧和扩展帧的选择,取决于你的系统规模。仲裁域决定了谁先说话,控制域告诉你怎么读,数据域装的是真正的信息,CRC域守护着数据的完整性。