2. CAN总线基础
各位好,我是老周。今天咱们来啃CAN总线里最核心的一块——数据帧。说实话,我见过不少测试工程师,拿着CANoe能抓波形,但一问到帧结构里每个bit的含义,就含糊了。这不行。你想想看,连报文长什么样都不清楚,出了问题怎么定位?
这一章,我会把标准帧和扩展帧掰开揉碎了讲。从SOF到EOF,每个场我都结合项目里的实际案例来说。保证你听完之后,再看CAN报文就跟看自己手背一样熟悉。
2.1 标准帧 vs 扩展帧——到底差在哪?
先解决一个最基础的问题:为什么要有两种帧格式?
早期CAN总线设计时,11位ID够用了。后来网络越来越复杂,节点越来越多,11位ID不够分。于是CAN 2.0B规范引入了29位ID的扩展帧。说白了,就是地址空间不够用了,加长它。
| 对比项 | 标准帧(CAN 2.0A) | 扩展帧(CAN 2.0B) |
|---|---|---|
| ID长度 | 11位 | 29位 |
| 仲裁场长度 | 12位(含RTR) | 32位(含SRR、IDE、RTR) |
| 最大节点数 | 约2048个 | 约5.3亿个 |
| 兼容性 | 不能接收扩展帧 | 可兼容标准帧 |
| 总线利用率 | 较高(帧头短) | 较低(帧头长) |
2.2 数据帧结构——一个bit一个bit拆给你看
一个完整的数据帧,由7个场组成。我习惯把它想象成一列火车:车头是SOF,车厢是数据,车尾是EOF。咱们一节一节看。
2.3 逐场深度解析
2.3.1 SOF——帧起始
SOF就是一个显性位(逻辑0)。它告诉总线上所有节点:我要开始发数据了。总线空闲时是隐性电平,SOF这个显性位一出现,所有节点同步。
2.3.2 仲裁场——谁优先级高谁先走
这是CAN总线最巧妙的设计。标准帧的仲裁场包含11位ID和1位RTR。扩展帧则包含11位基本ID、SRR、IDE、18位扩展ID和RTR。
仲裁机制说白了就是:ID值越小,优先级越高。所有节点同时发送时,从高位到低位逐bit比较,谁先发出隐性位而别人发显性位,谁就退出。
2.3.3 控制场——告诉别人我带了多长的数据
控制场包含IDE位、保留位r0和4位DLC。IDE位用来区分标准帧和扩展帧。DLC(Data Length Code)指示数据场有多少个字节。
| DLC值 | 数据字节数 | 常见用途 |
|---|---|---|
| 0 | 0 | 远程帧请求 |
| 1~7 | 1~7 | 短数据报文 |
| 8 | 8 | 最常用,满负载 |
2.3.4 数据场——真正干活的地方
数据场0~8字节,承载着你要传输的实际信息。比如车速信号、发动机转速、电池SOC等。数据场的解析规则由上层协议(如J1939、CANopen)定义。
// 示例:车速报文解析(假设ID=0x123,DLC=8)
// Byte0~Byte1: 车速值,分辨率0.01 km/h,偏移量0
uint16_t raw_speed = (data[1] << 8) | data[0];
float speed_kmh = raw_speed * 0.01f;
// 结果:如果raw_speed=2500,则车速=25.00 km/h
2.3.5 CRC场——数据完整性的守护神
CRC场包含15位CRC序列和1位隐性定界符。CRC计算范围从SOF到数据场结束。生成多项式是:x¹⁵ + x¹⁴ + x¹⁰ + x⁸ + x⁷ + x⁴ + x³ + 1。
接收节点会重新计算CRC,如果和发送的不一致,就丢弃这帧数据并发送错误帧。
2.3.6 ACK场——确认我收到了
ACK场只有2位:ACK Slot和ACK定界符。发送节点在ACK Slot发送隐性位,接收节点如果正确收到,就在这个位置拉一个显性位。如果没有任何节点应答,发送节点就知道没人收到。
2.3.7 EOF——帧结束
EOF是7个连续的隐性位。它告诉所有节点:这帧结束了,总线可以空闲或者开始下一帧。EOF之后,总线至少保持3个隐性位的帧间隔。
2.4 标准帧与扩展帧的仲裁差异
扩展帧的仲裁场比标准帧多了20位。这意味着扩展帧的仲裁过程更长,总线利用率更低。但29位ID带来的地址空间优势,在复杂网络中是不可替代的。
- 标准帧仲裁: 11位ID + RTR,共12位仲裁
- 扩展帧仲裁: 11位基本ID + SRR + IDE + 18位扩展ID + RTR,共32位仲裁
- 混合仲裁: 标准帧IDE=0,扩展帧IDE=1。标准帧的RTR位对应扩展帧的SRR位。标准帧RTR=0(数据帧)时,SRR位是隐性,标准帧赢
2.5 本章小结
数据帧是CAN通信的基础。标准帧和扩展帧各有适用场景,选型时要综合考虑节点数量、实时性要求和协议兼容性。每个场的功能我都结合项目经验讲了一遍,希望能帮你建立起对CAN帧的直观理解。