4、CAN协议基础:CAN总线仲裁机制、位填充机制、错误处理机制
好,咱们今天聊点硬核的。CAN总线这东西,搞汽车电子的没人能绕开。我当年刚入行时,总觉得CAN就是个串口升级版,结果第一次调试多节点通信就被教做人了——总线莫名其妙锁死,报文发不出去。后来才明白,仲裁、位填充、错误处理这三个机制,才是CAN协议的灵魂。
说白了,CAN总线能成为汽车行业的事实标准,靠的就是这三板斧。咱们一个一个拆开讲。
4.1 CAN总线仲裁机制:谁先说话谁有理
先问个问题:多个ECU同时往总线上发数据,会不会打架?
会,但CAN有办法解决。它用的不是“谁先抢到谁发”,而是“谁优先级高谁发”。这个机制叫非破坏性逐位仲裁。
怎么实现的?靠的是显性位(0)和隐性位(1)。总线上,显性位能覆盖隐性位。你想想看,如果两个节点同时发,一个发0,一个发1,那总线上的电平就是0——发1的那个节点一看,咦,我发的和总线上的不一样,说明有人比我优先级高,那我主动退让。
仲裁发生在标识符(ID)段。ID越小,优先级越高。我见过不少新手问:“那ID能不能重复?” 答案是绝对不能。重复ID会导致仲裁失败,两个节点都以为自己赢了,最后数据全乱套。
- 仲裁是逐位进行的,从ID的最高位开始比
- 显性位(逻辑0)优先级高于隐性位(逻辑1)
- 仲裁失败的节点自动转为接收模式,不破坏总线
- ID越小,优先级越高(0x000优先级最高)
我在项目中遇到过一个问题:某个ECU的ID设成了0x7FF,结果每次和别的节点抢总线都抢不过,导致关键报文总是延迟。后来我把ID改小了一档,问题就解决了。嗯,这里要注意,ID分配不是随便来的,得按报文紧急程度排。
4.2 位填充机制:保证时钟同步的“小聪明”
位填充,说白了就是防止总线“冷场”。
CAN总线用的是NRZ编码,不归零。如果连续发5个以上的相同电平,接收端的时钟就容易跑偏。你想想看,没有跳变沿,怎么同步?
所以协议规定:连续发送5个相同位后,必须插入一个相反位。这就是位填充。
举个例子:
原始数据:11111 00000 11111
填充后: 111110 000001 111110
看到没?每5个相同位后面,硬塞一个相反的。接收端收到后,会自动把这个填充位去掉,还原原始数据。
位填充覆盖的范围是:从SOF(帧起始)到CRC(循环冗余校验)段。ACK段和EOF段不参与填充。为什么?因为ACK段只有2位,没必要;EOF段是7个隐性位,用来标识帧结束,填充了反而坏事。
我曾经踩过一个坑:自己写CAN驱动时,忘了在发送端做位填充,结果接收端CRC校验一直报错。查了两天才发现,原来是填充位没加,导致CRC计算对不上。从那以后,我再也不敢手撸位填充逻辑了,老老实实用硬件模块。
4.3 错误处理机制:CAN的“自我修复”能力
CAN总线的错误处理,是我见过最完善的之一。它不光是检测错误,还能自动重发、自动隔离故障节点。
错误类型分五种:
| 错误类型 | 检测位置 | 说明 |
|---|---|---|
| 位错误 | 发送节点 | 发送的位与总线电平不一致(仲裁时除外) |
| 填充错误 | 所有节点 | 检测到连续6个相同位 |
| CRC错误 | 接收节点 | CRC校验和与本地计算不一致 |
| 格式错误 | 所有节点 | 帧格式不符合规范(如EOF段不是隐性位) |
| ACK错误 | 发送节点 | 发送后未收到ACK应答 |
检测到错误后,节点会发送错误帧。错误帧由6个显性位(错误标志)和8个隐性位(错误界定符)组成。这6个显性位会破坏当前帧,让所有节点都知道出错了。
然后呢?发送节点自动重发。重发次数不限,直到成功或被总线关闭。
- 错误主动(Error Active):TEC < 127,正常参与通信
- 错误被动(Error Passive):128 ≤ TEC ≤ 255,只能发被动错误帧
- 总线关闭(Bus Off):TEC > 255,完全断开总线
我遇到过最头疼的问题:某个ECU的CAN收发器坏了,导致它不停地发错误帧,把整个总线都拖垮了。其他节点全都在重发,总线利用率直接飙到100%。后来查出来是收发器的共模电压出了问题。嗯,这里要提醒一句:CAN总线出问题,别光看软件,硬件也得查。
4.4 三个机制的协同工作
仲裁、位填充、错误处理,这三个机制不是孤立的。它们共同保证了CAN总线的可靠性。
举个例子:假设节点A和节点B同时发数据,A的ID小,赢了仲裁。但A在发送过程中,因为干扰导致位错误。这时候:
- A检测到位错误,立即发错误帧
- 所有节点收到错误帧,丢弃当前数据
- A自动重发,再次参与仲裁
- 如果A的ID还是最小,它继续发;否则让给优先级更高的节点
整个过程对应用层是透明的。你想想看,如果没有仲裁机制,重发时可能又冲突;没有位填充,时钟可能失步;没有错误处理,一个坏节点就能搞死整个网络。这三个机制,缺一个都不行。
好了,CAN协议的三个核心机制就讲到这里。下节课咱们聊CAN帧结构,到时候你会看到,这些机制是怎么嵌入到每一帧里的。