2. CAN帧结构:数据帧、远程帧、错误帧、过载帧、帧间隔的详细解析
CAN总线上跑的数据,说白了就五种帧。我刚开始接触CAN时,总觉得帧结构很复杂,各种场、各种位,看得头晕。后来在产线上调一个从站设备,死活收不到数据,才逼着自己把帧结构啃透了。今天咱们就把这五种帧掰开揉碎了讲清楚。
核心要点:CAN帧的五个类型——数据帧、远程帧、错误帧、过载帧、帧间隔。其中数据帧和远程帧是“正经”通信用的,错误帧和过载帧是“异常处理”用的,帧间隔是“喘口气”用的。
2.1 数据帧(Data Frame)——最常用的帧
数据帧就是用来发数据的。我习惯把它分成七个段来记:
| 段名称 | 位数 | 作用 |
|---|---|---|
| 帧起始(SOF) | 1 bit | 显性位,告诉总线“我要开始发了” |
| 仲裁场 | 12 或 32 bit | 包含ID和RTR位,决定谁有优先权 |
| 控制场 | 6 bit | 包含IDE、保留位、DLC(数据长度) |
| 数据场 | 0~64 bit | 实际要传的数据,最多8字节 |
| CRC场 | 16 bit | 校验数据完整性 |
| ACK场 | 2 bit | 接收节点回应“我收到了” |
| 帧结束(EOF) | 7 bit | 隐性位,表示帧结束 |
这里有个坑,我踩过。数据场最多8字节,很多人以为能传更多。有一次客户说“我明明发了10个字节,怎么收不全?”——嗯,CAN协议规定死了,数据场就是0~8字节,多了塞不进去。
我的习惯:调试时先看DLC(数据长度码),如果DLC和实际数据长度对不上,八成是发送端配置错了。我曾经花了两小时查一个从站不响应的问题,最后发现是DLC写成了0,数据根本没发出去。
2.2 远程帧(Remote Frame)——请求数据的帧
远程帧说白了就是“问别人要数据”。它的结构和数据帧几乎一样,只有一个关键区别:RTR位是隐性(1),而数据帧的RTR位是显性(0)。
你想想看,如果一个节点发了远程帧,目标节点收到后应该回复一个同ID的数据帧。但这里有个容易搞混的地方:远程帧没有数据场,DLC字段表示的是请求的数据长度。
我曾经踩过的坑:远程帧的DLC必须和对方回复的数据帧DLC一致。有一次我写远程帧时DLC设成了2,但对方回复了8字节,结果接收端直接报错。后来查标准才发现,DLC不匹配会被当作错误处理。
2.3 错误帧(Error Frame)——出问题时的“警报”
错误帧是CAN协议里最“暴力”的机制。一旦某个节点检测到错误,它会立刻发送6个连续的显性位,把当前帧“冲掉”。
错误帧分两部分:
- 错误标志:6个显性位(主动错误)或6个隐性位(被动错误)
- 错误界定符:8个隐性位
我记得有一次在测试现场,总线上一堆错误帧,整个网络几乎瘫痪。后来定位到是一个从站的终端电阻焊短路了,导致电平异常。错误帧本身不是坏事,它是CAN协议的自愈机制——但错误帧太多,说明物理层或协议层有问题。
避坑指南:用示波器抓CAN总线波形时,如果看到连续6个显性位,基本可以断定是错误帧。这时候别急着改软件,先查硬件——终端电阻、共模电压、线缆长度,这些物理层问题最容易引发错误帧风暴。
2.4 过载帧(Overload Frame)——忙不过来的信号
过载帧和错误帧长得有点像,但用途完全不同。过载帧是接收节点告诉总线:“我太忙了,慢点发”。
过载帧的结构:
- 过载标志:6个显性位
- 过载界定符:8个隐性位
说实话,过载帧在实际项目中用得不多。我做了这么多年CAN开发,只在一些老旧的ECU上见过。现在的CAN控制器处理能力都很强,基本不会主动发过载帧。如果你在调试时频繁看到过载帧,先检查一下接收节点的中断处理是不是太慢了。
2.5 帧间隔(Interframe Space)——帧与帧之间的“喘息”
帧间隔不是真正的“帧”,它是帧与帧之间的空闲时间。CAN协议规定,任何帧结束后,必须等3个隐性位才能发下一帧。
帧间隔分两部分:
- 间歇场:3个隐性位
- 总线空闲:任意长度的隐性位
这里有个细节:错误帧和过载帧前面不需要帧间隔。为什么?因为这两种帧是“紧急插入”的,等不了那3个位的时间。
我的经验:调试时如果发现总线利用率很高,可以算一下帧间隔占了多少时间。比如1Mbps的速率,每帧至少3个位的间隔,约3μs。如果一帧数据是8字节,总时长约130μs,帧间隔占了2.3%。这个比例虽然不大,但在高负载场景下,优化帧间隔能挤出一点带宽。
2.6 五种帧的关系图
下面这张图是我自己总结的,把五种帧的触发关系和优先级画清楚了。你调试时遇到问题,按这个图排查思路会清晰很多。
2.7 标准帧 vs 扩展帧
数据帧和远程帧都分两种格式:标准帧(11位ID)和扩展帧(29位ID)。这个区别主要在仲裁场。
| 特性 | 标准帧 | 扩展帧 |
|---|---|---|
| ID长度 | 11 bit | 29 bit |
| 仲裁场长度 | 12 bit | 32 bit |
| IDE位 | 显性(0) | 隐性(1) |
| 兼容性 | 所有控制器都支持 | 需要控制器支持 |
| 优先级 | 相同ID下标准帧优先 | 扩展帧优先级较低 |
我个人习惯,能用标准帧就不用扩展帧。为什么?因为扩展帧的仲裁场更长,总线利用率会低一点。而且很多老设备只支持标准帧,混用容易出问题。
注意:标准帧和扩展帧的ID不能重复。如果总线上同时存在标准帧ID 0x123和扩展帧ID 0x123,标准帧的优先级更高。这个特性在混合网络中容易引发“饿死”现象——扩展帧一直抢不到总线。
2.8 实战中的帧分析技巧
最后分享几个我在调试中常用的技巧:
- 看ACK位:如果发送端发了数据帧,但ACK场没收到显性位,说明总线上没有节点在接收。这是排查“数据发出去没人理”的最快方法。
- 看CRC:CRC错误通常意味着物理层干扰。我遇到过线缆太长导致信号反射,CRC错误率飙升的情况。
- 看错误帧频率:如果每秒错误帧超过10个,基本可以判定总线有问题。先查终端电阻,再查共模电压,最后查节点硬件。
- 用CAN分析仪抓波形:别只看报文,要结合示波器看物理层波形。有一次我查了三天,最后发现是一个节点的CAN收发器供电纹波太大,导致信号畸变。
嗯,帧结构这块就讲这么多。记住一句话:数据帧和远程帧是“干活”的,错误帧和过载帧是“报错”的,帧间隔是“休息”的。搞清楚了这五种帧,CAN总线调试你就入门了。