2、CAN帧结构:数据帧、远程帧、错误帧、过载帧、帧间隔
好,咱们今天聊聊CAN总线的帧结构。说实话,这五个家伙——数据帧、远程帧、错误帧、过载帧、帧间隔——就是CAN总线通信的“五虎上将”。你搞懂了它们,基本就摸清了CAN的脾气。
我个人习惯把帧结构比作快递包裹。每个包裹有发件人、收件人、货物内容和验货单。CAN帧也一样,每个部分都有明确分工。咱们一个一个来看。
2.1 数据帧:最常用的“主力选手”
数据帧,说白了就是用来装数据的。一个节点发,其他节点收。我在项目中遇到过不少新手,上来就问“数据帧怎么发”?其实你只要搞清楚它的结构,剩下的就是填表。
数据帧由7个段组成:
- 帧起始:一个显性位,告诉总线“我要开始说话了”。
- 仲裁段:包含ID和RTR位。ID决定优先级,数字越小优先级越高。
- 控制段:包含IDE位、保留位和DLC(数据长度码)。DLC告诉你后面跟了多少字节数据。
- 数据段:0~8字节,你要传的真正内容。
- CRC段:15位CRC校验码+1位CRC界定符。用来检查数据有没有传错。
- ACK段:2位。发送节点发隐性位,接收节点如果收到正确,就拉成显性位——这就是“我收到了”的信号。
- 帧结束:7个隐性位,表示帧结束了。
重点提醒:标准帧ID是11位,扩展帧ID是29位。两者不兼容,混用会出问题。我建议你统一用一种,别给自己找麻烦。
2.2 远程帧:只问不拿的“侦察兵”
远程帧很有意思。它没有数据段,只有一个ID和RTR位(隐性)。它的作用就是问别人:“嘿,你有ID为XXX的数据吗?发给我看看。”
你想想看,这就像你打电话问朋友“你吃饭了吗”?你并不需要给他送饭,只是想知道答案。远程帧就是干这个的。
我曾经踩过一个坑:远程帧的DLC必须和对应数据帧的DLC一致。否则接收节点可能不理你。嗯,这里要注意,DLC不是随便填的。
实战技巧:远程帧常用于请求传感器数据。比如ECU发一个远程帧,传感器收到后立刻回复数据帧。这样能减少总线上的无效数据。
2.3 错误帧:总线的“交警”
错误帧是CAN总线自己维护秩序的工具。任何节点发现错误,都会立刻发送错误帧。它由两部分组成:
- 错误标志:6个连续相同位(显性或隐性)。
- 错误界定符:8个隐性位。
错误帧分两种:主动错误帧和被动错误帧。主动错误帧是“强势”节点发的,6个显性位;被动错误帧是“弱势”节点发的,6个隐性位。
我记得有一次调试,总线一直报错。查了半天,发现是一个节点的时钟漂移太大,导致位同步失败。它不停地发错误帧,把整个总线都拖垮了。这就是典型的“一颗老鼠屎坏了一锅粥”。
避坑指南:我曾经见过一个项目,错误帧太多导致总线利用率降到10%以下。解决办法是:先隔离节点,逐个排查。别一上来就改软件,先看硬件。
2.4 过载帧:总线的“缓冲器”
过载帧的作用很简单:告诉总线“我忙不过来,慢点发”。它和错误帧长得有点像,但用途完全不同。
过载帧由过载标志(6个显性位)和过载界定符(8个隐性位)组成。它只在两种情况下出现:
- 接收节点还没准备好接收下一帧。
- 帧间隔期间检测到显性位(这属于异常情况)。
说白了,过载帧就是节点在说“等等,我还没消化完”。我在项目中很少见到过载帧,因为现在的MCU处理速度都很快。但如果你用老旧的8位单片机,可能就会遇到。
2.5 帧间隔:总线的“休息时间”
帧间隔不是帧,而是帧与帧之间的空闲时间。它由3个隐性位组成(总线空闲时也是隐性位)。
为什么需要帧间隔?因为节点需要时间处理上一帧的数据。如果没有间隔,节点可能来不及响应。
你想想看,如果两个人连续不停地说话,谁受得了?总线上也一样,需要喘口气。
关键点:帧间隔期间,任何节点都可以开始发送。但如果有节点发送了错误帧或过载帧,帧间隔会延长。这就是CAN总线的“公平竞争”机制。
2.6 五种帧的对比
为了方便你记忆,我整理了一个表格:
| 帧类型 | 主要作用 | 数据段 | 触发条件 |
|---|---|---|---|
| 数据帧 | 传输数据 | 有(0~8字节) | 节点主动发送 |
| 远程帧 | 请求数据 | 无 | 节点主动发送 |
| 错误帧 | 报告错误 | 无 | 检测到错误 |
| 过载帧 | 请求延迟 | 无 | 接收节点忙 |
| 帧间隔 | 帧间分隔 | 无 | 每帧结束后 |
这个表格我建议你存下来。调试的时候对照着看,能省不少时间。
2.7 实战中的帧结构问题
最后,我分享几个实战中常见的坑:
- ID冲突:两个节点用同一个ID发送数据帧,会导致仲裁失败。我建议你提前规划好ID分配表。
- DLC不匹配:远程帧的DLC和数据帧的DLC不一致,接收节点可能忽略请求。我曾经因为这个查了三天。
- 错误帧风暴:一个节点频繁发错误帧,会导致整个总线瘫痪。解决办法是:先断开可疑节点,再逐个恢复。
- 帧间隔过短:有些MCU处理速度慢,需要更长的帧间隔。你可以通过调整波特率或增加软件延时来解决。
好了,帧结构就讲到这里。下一章咱们聊聊CAN的位时序和同步,那才是真正考验功底的地方。记住,搞懂帧结构只是入门,能解决实际问题才是高手。