3. CAN帧结构详解
各位工程师朋友,咱们继续聊CAN总线。前两章我们把数据帧和遥控帧的基本概念过了一遍,今天要讲的是两个容易被忽视、但实际项目中坑最多的东西——远程帧和错误帧。
说实话,我刚入行那会儿,觉得远程帧就是个“请求数据”的小工具,错误帧嘛,出错了才用得上。直到有一次在台架上跑测试,总线莫名其妙挂掉,折腾了两天才发现是错误帧风暴导致的。嗯,从那以后我再也不敢小看这两个家伙了。
3.1 远程帧:它到底在干什么?
远程帧,也叫RTR帧(Remote Transmission Request)。说白了,就是一个节点告诉另一个节点:“嘿,把你手上那个ID的数据发给我看看。”
你可能会问:为什么不直接发数据帧?非要搞个远程帧来“请求”?
我个人的理解是:远程帧的核心价值在于“按需索取”。比如一个传感器节点平时不主动发数据,只有仪表盘需要时才请求一次。这样能省不少总线带宽。
3.1.1 远程帧的结构
远程帧的结构和数据帧非常像,但有两个关键区别:
- RTR位:远程帧的RTR位为隐性(1),数据帧为显性(0)
- 数据场:远程帧没有数据场,DLC(数据长度码)虽然存在,但实际不传输数据
来看一个标准格式的远程帧结构:
SOF | 11位ID | RTR(1) | IDE | r0 | 4位DLC | CRC | ACK | EOF
1 11 1 1 1 4 15 2 7
注意看,RTR位是1(隐性),这就是远程帧的“身份证”。
关键点:远程帧的DLC虽然存在,但它只表示请求的数据长度,并不携带数据字节。所以远程帧的总长度比数据帧短很多。
3.1.2 远程帧的工作流程
我画了一张图,帮你理解远程帧的交互过程:
我的经验:在实际项目中,远程帧用得最多的是诊断服务和传感器数据请求。但要注意,如果多个节点同时请求同一个ID的远程帧,可能会引发总线冲突。我曾经在一个项目中遇到过,三个ECU同时请求同一个传感器的数据,结果总线上一片混乱。后来我们加了一个请求仲裁机制才解决。
3.2 错误帧:总线的“警报器”
错误帧是CAN总线自我保护的机制。当任何一个节点检测到总线上的错误时,就会发送错误帧来通知其他节点。
你想想看,如果总线上有节点在乱发数据,其他节点怎么办?总不能一直忍着吧。错误帧就是用来“喊停”的。
3.2.1 错误帧的结构
错误帧由两部分组成:
- 错误标志:6个连续的显性位(主动错误)或6个连续的隐性位(被动错误)
- 错误界定符:8个连续的隐性位
结构图如下:
错误标志(6位) | 错误界定符(8位)
显性/隐性 隐性
这里有个细节:错误标志的6位会破坏当前正在传输的帧的填充位规则,从而让其他节点也检测到错误。
3.2.2 错误帧的触发条件
CAN总线定义了5种错误类型,任何一类都会触发错误帧:
| 错误类型 | 触发条件 | 检测节点 |
|---|---|---|
| 位错误 | 发送节点监控到总线电平与发送电平不一致 | 发送节点 |
| 填充错误 | 连续出现6个相同电平的位(违反位填充规则) | 所有节点 |
| CRC错误 | 接收节点计算的CRC与发送的CRC不匹配 | 接收节点 |
| 格式错误 | 帧格式中的固定位出现错误电平 | 所有节点 |
| ACK错误 | 发送节点在ACK槽未检测到显性位 | 发送节点 |
避坑指南:我曾经在一个项目中遇到“幽灵错误”——总线偶尔出现错误帧,但用示波器抓波形又看不出问题。后来排查了三天,发现是一个节点的晶振精度不够,导致位时序偏差。所以,时钟精度是错误帧排查中容易被忽略的因素。
3.3 错误状态:主动、被动与总线关闭
CAN总线上的每个节点都有一个错误计数器,分为发送错误计数器(TEC)和接收错误计数器(REC)。根据计数器的值,节点会处于三种状态之一。
我习惯用“交通规则”来类比:
- 主动错误:你是正常司机,看到违规可以大声喊停
- 被动错误:你被扣了分,只能小声提醒
- 总线关闭:你的驾照被吊销了,不能上路
3.3.1 三种状态详解
| 状态 | 条件 | 错误标志 | 行为 |
|---|---|---|---|
| 主动错误 | TEC ≤ 127 且 REC ≤ 127 | 6个显性位 | 正常参与通信,检测到错误时主动发送错误帧 |
| 被动错误 | TEC > 127 或 REC > 127 | 6个隐性位 | 只能发送被动错误帧,不能破坏其他节点的帧 |
| 总线关闭 | TEC > 255 | 不发送 | 完全脱离总线,不参与任何通信 |
状态转换流程如下:
3.3.2 错误计数器的增减规则
很多初学者搞不清计数器怎么加减。我总结了一个简化版规则:
- 发送成功:TEC减1(但TEC不会低于0)
- 发送错误:TEC加8
- 接收错误:REC加1
- 被动错误节点发送成功:TEC减1(但不会低于127)
核心逻辑:错误计数器采用“重罚轻奖”策略。发送一次错误加8分,发送成功才减1分。这样设计是为了让频繁出错的节点快速进入被动状态,避免它持续破坏总线。
3.4 实战中的错误帧排查
在实际测试中,错误帧是最常见的“捣乱分子”。我分享几个排查思路:
- 用CAN工具抓错误帧统计:大部分CAN分析仪都能统计错误帧数量和类型
- 观察错误计数器:通过诊断服务读取节点的TEC和REC值
- 检查终端电阻:终端电阻异常会导致信号反射,引发位错误
- 排查时钟精度:位时序偏差是CRC错误的常见原因
- 检查接地:共模电压过高会导致隐性电平无法正常识别
我曾经踩过的坑:有一次测试中,总线偶尔出现错误帧,但频率不高。我们用CAN工具抓了半小时才抓到一次。后来发现是一个节点的CAN收发器供电滤波电容虚焊,导致电源纹波过大,偶尔触发位错误。所以,硬件可靠性也是错误帧排查的重要方向。
3.5 本章小结
远程帧和错误帧是CAN总线协议中容易被忽视、但实际影响巨大的部分。远程帧实现了“按需索取”的数据请求机制,而错误帧则是总线自我修复的核心手段。
理解错误状态的转换逻辑,掌握错误计数器的增减规则,能帮你快速定位总线故障。记住:总线关闭不是终点,而是节点自我保护的最后一道防线。