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 五种帧的关系图

下面这张图是我自己总结的,把五种帧的触发关系和优先级画清楚了。你调试时遇到问题,按这个图排查思路会清晰很多。

CAN总线五种帧关系图 CAN总线五种帧关系图 总线空闲 数据帧 远程帧 错误帧 过载帧 帧间隔 发送数据 请求数据 检测到错误 帧结束后 错误恢复后 过载解除后 间隔结束 说明: 实线表示正常流程,虚线表示异常恢复流程。错误帧和过载帧不需要帧间隔,可以直接插入。

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 实战中的帧分析技巧

最后分享几个我在调试中常用的技巧:

  1. 看ACK位:如果发送端发了数据帧,但ACK场没收到显性位,说明总线上没有节点在接收。这是排查“数据发出去没人理”的最快方法。
  2. 看CRC:CRC错误通常意味着物理层干扰。我遇到过线缆太长导致信号反射,CRC错误率飙升的情况。
  3. 看错误帧频率:如果每秒错误帧超过10个,基本可以判定总线有问题。先查终端电阻,再查共模电压,最后查节点硬件。
  4. 用CAN分析仪抓波形:别只看报文,要结合示波器看物理层波形。有一次我查了三天,最后发现是一个节点的CAN收发器供电纹波太大,导致信号畸变。

嗯,帧结构这块就讲这么多。记住一句话:数据帧和远程帧是“干活”的,错误帧和过载帧是“报错”的,帧间隔是“休息”的。搞清楚了这五种帧,CAN总线调试你就入门了。