2. CAN帧类型:数据帧、远程帧、错误帧、过载帧
CAN总线上跑的报文,说白了就四种:数据帧、远程帧、错误帧、过载帧。虽然名字好记,但很多工程师干了好几年,也未必能把它们之间的细节说清楚。我刚开始接触CAN的时候,就吃过“帧类型搞混”的亏,总线莫名其妙挂掉,查了半天才发现是远程帧的ID设置错了。今天咱们把这四种帧彻底梳理一遍。
2.1 数据帧(Data Frame)
数据帧是用来发送数据的,最常用,没有之一。你想想看,传感器采集到的温度、转速、压力,最后都是通过数据帧发出去的。数据帧的结构分成七段:帧起始、仲裁段、控制段、数据段、CRC段、ACK段、帧结束。
⚠️ 重要提醒:标准帧ID是11位,扩展帧ID是29位。虽然扩展帧能用的ID更多,但仲裁时优先级并不更高——总线仲裁只看ID的数值,跟帧格式无关。
我个人的习惯是:只要项目节点数不超过10个,尽量用标准帧。为什么呢?因为标准帧的报文长度更短,总线利用率更高。遇到复杂的多节点项目,比如车载网关,那才上扩展帧。
数据帧的数据段最多能放8个字节。很多新手问我:“能不能多发几个字节?”答案是不能。要是你的数据超过了8字节,就得拆成两帧发。我在一个电机控制项目里遇到过这种情况:一个编码器位置是32位浮点,再加上电流、温度,8个字节刚刚好。后来客户要加个诊断信息,只好拆成两帧。
2.2 远程帧(Remote Frame)
远程帧很特殊,它不带数据。它的作用就是“请求数据”。打个比方:节点A发一个远程帧,节点B收到后,会发一个对应ID的数据帧回来。
远程帧的结构跟数据帧几乎一样,区别在于:
- 控制段里的RTR位(远程发送请求位),数据帧是显性0,远程帧是隐性1
- 远程帧没有数据段
⚠️ 避坑指南:我曾经吃过一次亏——项目中用远程帧请求传感器数据,结果传感器节点同时收到了远程帧和另一个节点发的数据帧,两个报文ID冲突,总线直接出错误帧。后来我改成了“数据帧主动上报”的模式,远程帧只在诊断模式下启用。
说实话,远程帧在实际项目中用得并不多。我个人建议:除非你有明确的多主从请求机制,否则远程帧能不用就不用。用定时发送数据帧来替代请求响应,总线可靠性更高。
2.3 错误帧(Error Frame)
错误帧是这次课程的核心。它是CAN节点发现总线出错时自动发出的。错误帧的结构很简单:6个连续的显性位(主动错误标志)+ 8个隐性位的错误界定符。
错误帧一旦出现,总线上的所有节点都会收到,然后每个节点都会更新自己的错误计数器。如果错误计数超过255,节点就会进入“总线关闭”状态,彻底退出通信。我在现场调试时遇到过这种情况——一个节点的CAN收发器坏了,疯狂发错误帧,整个生产线停了半个小时。
| 错误类型 | 触发条件 | 常见场景 |
|---|---|---|
| 位错误 | 发送节点监控到总线电平跟发送的不一致 | 两个节点同时发相同位但电平不同 |
| 填充错误 | 连续检测到6个相同位(违反位填充规则) | 时钟偏差大、信号干扰 |
| CRC错误 | 接收节点计算的CRC与发送的不一致 | 总线噪声、终端电阻配置错误 |
| 形式错误 | 帧的固定格式字段值不对 | CAN控制器配置错误 |
| ACK错误 | 发送节点没收到ACK显性位 | 只有一个节点在总线上 |
嗯,这里要注意:错误帧一旦出现,说明总线上有问题。但并不是所有错误帧都致命。比如偶发的CRC错误,可能是线束松动引起的;但如果持续出现错误帧,那就得定位节点了。判断哪个节点有问题,我的方法是:用CAN分析仪抓取错误帧前后的报文ID,哪个节点的ID最近出现,那个节点出问题的概率最大。
2.4 过载帧(Overload Frame)
过载帧是节点告诉总线“我忙不过来,等一等”。它的结构跟错误帧很像:6个显性位 + 8个隐性的过载界定符。区别在于:错误帧是出错自动发,过载帧是节点主动发的。
过载帧在实际项目中出现的频率不高。我见过一种情况:一个CAN节点用的是低性能的MCU,CPU处理不过来数据,就大量发过载帧来延后接收。后来我们把那个节点的CAN接收中断优先级调高了,过载帧就消失了。
💡 一个小技巧:如果你在抓包工具里看到连续的过载帧,先别急着怀疑总线硬件。看看是不是某个节点的中断响应延迟太大,或者接收缓冲区太小导致数据溢出。软件问题比硬件问题更容易修。
过载帧还有一个特点:它只影响接收流程,不影响发送。所以过载帧不会导致总线关闭,但它会拖慢整个CAN网络的吞吐量。要是在你调试的时候发现通信速率异常,记得看看过载帧的数量。
2.5 四种帧的关系梳理
说到这儿,你可能觉得结构挺多。我画了一张图,把这四种帧的层次关系串起来。这张图是我自己做项目时习惯用的思维模型,能帮你快速定位当前总线上跑的是哪种帧。
从图上你能看到:CAN总线帧分成两大类——合法帧和错误帧。合法帧里又分数据帧、远程帧、过载帧。我建议你把这张图存下来,下次用CAN分析仪抓包的时候,对照着看,帧类型一目了然。
2.6 帧类型识别小技巧
在实际调试中,你怎么快速识别帧类型?有个简单方法:看报文ID后面的标识位。
- 数据帧:RTR=0, 有数据段
- 远程帧:RTR=1, 没有数据段
- 错误帧:没有标准ID, 显示为ERR或Error Frame
- 过载帧:显示为Overload Frame, 紧跟在要延迟的报文后面
你想想看,大部分CAN分析工具都会自动标识帧类型。但如果你用的是自己写的监控工具(我有个项目就自己写了个简易抓包软件),那你就得手动解析RTR位和数据长度码了。