2. CAN总线帧结构:数据帧、远程帧、错误帧、过载帧、帧间隔
CAN总线上跑的数据,说白了就五种“盒子”。每种盒子干不同的活。我刚开始接触CAN的时候,总觉得帧结构很复杂,各种场、位、CRC……后来在项目里调了几个月,才真正摸透它们的脾气。
今天咱们就把这五种帧掰开揉碎,一个一个看。
2.1 数据帧:最常用的“快递包裹”
数据帧是CAN总线上最常见的帧类型。它的任务就是——把数据从一个节点送到另一个节点。你可以把它想象成一个快递包裹。
一个标准数据帧(CAN 2.0A)长这样:
SOF + 11位ID + RTR + IDE + r0 + DLC + 0~8字节数据 + CRC + ACK + EOF
我习惯把数据帧拆成几个关键部分:
- SOF(帧起始):1个显性位。告诉总线上所有节点:“我要发东西了!”
- 仲裁场(ID + RTR):11位标识符 + 1位远程帧标志。ID越小,优先级越高。RTR=0表示这是数据帧。
- 控制场(IDE + r0 + DLC):IDE表示标准帧还是扩展帧,DLC告诉别人我带了几个字节的数据(0~8)。
- 数据场:0~8字节。这就是真正的“货”。
- CRC场:15位CRC校验 + 1位CRC界定符。检查数据有没有传错。
- ACK场:2位。接收节点如果正确收到,会在ACK槽里拉低电平(显性),告诉发送方:“我收到了!”
- EOF(帧结束):7个隐性位。表示这个帧结束了。
关键点:数据帧最多带8字节数据。为什么是8?因为CAN总线设计之初,认为汽车控制信号(转速、车速、温度等)8个字节足够表达了。后来发现不够用……那是后话。
2.2 远程帧:只问不拿的“查询单”
远程帧长得很像数据帧,但有一个关键区别——它没有数据场。
远程帧的RTR位是1(隐性)。它的作用是:请求其他节点发送数据。
举个例子:
- 节点A发一个远程帧,ID=0x123,DLC=8。
- 节点B如果配置了ID=0x123的数据帧,就会立刻发一个数据帧回来。
我在项目里遇到过一个问题:某个传感器节点一直不发数据,排查了半天,发现是主控发的远程帧DLC写错了,传感器不认。嗯,细节决定成败。
避坑指南:我曾经见过有人用远程帧做周期性请求,结果总线负载率飙升。远程帧适合“按需查询”,不适合“轮询”。你想想看,如果10个节点同时发远程帧,总线会乱成什么样?
2.3 错误帧:总线的“警报器”
错误帧是CAN总线最强大的特性之一。一旦某个节点检测到错误,它会立刻发出错误帧,通知所有节点:“刚才那包数据有问题,别用!”
错误帧由两部分组成:
- 错误标志:6个连续显性位(主动错误)或6个连续隐性位(被动错误)。
- 错误界定符:8个隐性位。
CAN总线有五种错误类型:
| 错误类型 | 触发条件 | 我见过的案例 |
|---|---|---|
| 位错误 | 发送节点监控总线,发现电平与发送的不一致 | 总线短路时最常见 |
| 填充错误 | 连续6个相同电平(违反位填充规则) | 晶振偏差大时偶发 |
| CRC错误 | 接收节点计算的CRC与发送的不一致 | 线束老化、干扰严重时出现 |
| 格式错误 | 固定格式位(如CRC界定符)出现错误电平 | 节点软件bug导致 |
| ACK错误 | 发送节点没收到ACK显性位 | 总线上只有发送节点在线 |
个人经验:我调试过一个项目,总线上疯狂报错误帧。用示波器一看,CAN_H和CAN_L的共模电压不对,原来是某个节点的收发器坏了,把总线电平拉偏了。换了个收发器,问题解决。
2.4 过载帧:总线的“请稍等”
过载帧的作用很简单——告诉发送方:“我还没准备好,你慢点发。”
它由两部分组成:
- 过载标志:6个显性位。
- 过载界定符:8个隐性位。
过载帧在两种情况下触发:
- 接收节点内部条件未准备好(比如缓冲区满了)。
- 帧间隔期间检测到显性位(总线异常)。
说实话,过载帧在实际项目中不太常见。现在的CAN控制器处理能力都很强,很少会因为“来不及处理”而发过载帧。但如果你在总线上看到大量过载帧,那说明某个节点的硬件或软件设计有问题。
2.5 帧间隔:帧与帧之间的“呼吸”
帧间隔不是一种帧,而是帧与帧之间的空闲时间。它让总线上的节点有时间“喘口气”。
帧间隔由三部分组成:
- 间歇场:3个隐性位。
- 总线空闲:任意长度的隐性电平。
- (可选)暂停发送场:8个隐性位(仅被动错误节点需要)。
为什么要有帧间隔?
- 给接收节点时间处理刚收到的数据。
- 让总线从“忙碌”状态切换到“空闲”状态。
- 防止某个节点一直霸占总线。
一句话总结:数据帧是送货的,远程帧是下单的,错误帧是报警的,过载帧是喊停的,帧间隔是休息的。五种帧配合起来,才有了CAN总线的高可靠通信。
2.6 五种帧的关系图
下面这张图展示了五种帧在总线上的逻辑关系:
2.7 实战中的帧分析思路
在项目调试中,我一般按这个顺序分析总线上的帧:
- 看帧类型:是数据帧还是远程帧?如果是远程帧,检查DLC是否匹配。
- 看ID优先级:ID越小优先级越高。如果两个节点同时发数据,ID小的会赢得仲裁。
- 看数据长度:DLC与实际数据长度是否一致?不一致会导致接收节点解析错误。
- 看错误帧频率:如果错误帧占比超过1%,说明总线有问题。
- 看帧间隔:帧与帧之间是否有足够的空闲时间?如果总线一直忙,说明负载率太高。
实用技巧:我习惯用CANalyzer或PCAN-View抓一段总线数据,然后按帧类型过滤。先看错误帧,再看数据帧。错误帧多的地方,就是问题所在。
好了,五种帧的结构和用途就讲到这里。记住一句话:数据帧是主角,远程帧是配角,错误帧和过载帧是保安,帧间隔是休息区。理解了它们,CAN总线通信的底层逻辑你就掌握了八成。