3、CAN远程帧与错误帧:远程帧作用、错误帧类型、总线仲裁机制、位填充规则

各位同学,今天我们来啃一块硬骨头——CAN总线里的远程帧和错误帧。说实话,我刚入行那会儿,总觉得远程帧是个可有可无的东西,直到有一次在ECU刷写项目中,被一个远程帧引发的总线堵塞折腾了三天三夜……嗯,从那以后我再也不敢小看它了。

3.1 远程帧:它到底有什么用?

远程帧,说白了就是一个「请求帧」。它本身不携带数据,只负责向某个节点要数据。你想想看,如果A节点想知道B节点的某个传感器值,传统做法是B节点定时往外发,但这样浪费带宽。远程帧就是让A节点喊一声:「B,把你的数据给我!」然后B节点收到后,乖乖发一个数据帧回来。

我个人习惯把远程帧理解成「点名机制」。它的帧结构跟数据帧几乎一样,区别在于:

  • RTR位(Remote Transmission Request):数据帧里RTR=0,远程帧里RTR=1
  • 数据长度码(DLC):远程帧的DLC表示请求的数据字节数,但实际数据场为空
  • 没有数据场:远程帧的CRC校验只计算控制场,不包含数据

重要提醒:远程帧的仲裁场ID必须与目标数据帧的ID一致。否则,节点根本不知道你在叫谁。

我在项目中遇到过一个问题:某个传感器节点同时收到了多个远程帧请求,结果它连续发送数据帧,把总线占得死死的。后来我加了一个「请求队列」机制,每个节点每秒最多响应10次远程帧请求,问题就解决了。

3.2 错误帧:总线上的「警报器」

错误帧是CAN总线自我保护的机制。当任何节点检测到总线错误时,就会主动发送错误帧,通知所有节点:「刚才那帧数据有问题,大家别用了!」

错误帧分为两种:

错误帧类型 触发条件 结构
主动错误帧 节点处于主动错误状态 6个显性位(主动错误标志)+ 8个隐性位(错误界定符)
被动错误帧 节点处于被动错误状态 6个隐性位(被动错误标志)+ 8个隐性位(错误界定符)

这里有个关键点:主动错误帧的6个显性位会覆盖总线上的任何数据,强制中断当前传输。而被动错误帧的6个隐性位,只有在总线空闲时才能被识别——说白了,被动节点已经「没资格」干扰正常通信了。

避坑指南:我曾经调试过一个项目,发现总线频繁出现错误帧,但始终找不到原因。后来用示波器一看,原来是某个节点的CAN收发器供电电压偏低,导致隐性位无法正常拉高。记住:错误帧不一定代表协议问题,硬件故障才是最常见的元凶。

3.3 总线仲裁机制:谁说了算?

CAN总线是「多主」架构,任何节点都可以随时发送。但如果两个节点同时发,谁先发?答案就是:ID越小,优先级越高

仲裁过程是这样的:

  1. 所有发送节点同时往总线上发送仲裁场的ID位
  2. 每个节点在发送位的同时,监听总线电平
  3. 如果发送的是隐性位(1),但监听到显性位(0),说明有更高优先级的节点在发,自己立即退出发送
  4. 胜出的节点继续发送剩余帧内容

你想想看,这个机制有多巧妙——不需要中央调度器,完全靠硬件自动完成。我刚开始学的时候,总觉得这玩意儿不靠谱,直到用Wireshark抓了一次总线数据,亲眼看到两个节点同时发,低ID的帧完整通过,高ID的帧自动重发……嗯,服了。

个人经验:设计CAN网络时,把关键控制消息的ID设小一点(比如0x001~0x010),把诊断、配置类的消息ID设大一点(比如0x700以上)。这样紧急消息永远优先通过。

3.4 位填充规则:保证时钟同步的「小把戏」

CAN总线没有单独的时钟线,所有节点靠总线上的电平跳变来同步时钟。但如果连续发送5个相同的位(比如00000),总线电平就不跳变了,节点时钟就会漂移。

解决办法很简单:每发送5个相同位,自动插入一个相反位。这就是位填充规则。

  • 发送方:检测到连续5个相同位,在第5位后插入一个相反位
  • 接收方:检测到连续5个相同位,自动删除第5位后的那个位
  • 填充位范围:从SOF到CRC场(ACK场、EOF、IFS不填充)

举个例子:

原始数据:11111 00000 11111
填充后:  11111 0 00000 1 11111 0
(注意:填充位用斜体表示)

这里有个坑:如果接收方检测到连续6个相同位,就认为违反了位填充规则,立刻发送错误帧。我曾经在测试中故意发送连续6个显性位,结果总线瞬间被错误帧淹没——嗯,这就是CAN总线的「零容忍」态度。

关键总结:位填充规则保证了每个节点都能从总线电平跳变中提取时钟信息。没有它,CAN总线在长距离、高波特率下根本无法稳定工作。

3.5 知识体系总览

下面这张图是我自己画的,把本章的核心逻辑串起来了:

CAN远程帧与错误帧知识体系 远程帧 • 作用:请求数据,不携带数据场 • RTR=1,DLC表示请求字节数 • 仲裁场ID必须与目标数据帧一致 • 注意:防止请求风暴 错误帧 • 主动错误帧:6显性位+8隐性位 • 被动错误帧:6隐性位+8隐性位 • 触发条件:位错误、填充错误等 • 硬件故障是常见诱因 总线仲裁机制 • 多主架构,ID越小优先级越高 • 隐性位被显性位覆盖即退出 • 无中央调度,硬件自动完成 • 关键消息分配小ID 位填充规则 • 每5个相同位插入1个相反位 • 范围:SOF到CRC场 • 接收方自动删除填充位 • 连续6个相同位触发错误帧 核心逻辑:远程帧请求 → 仲裁决定谁发 → 位填充保证同步 → 错误帧处理异常

这张图把四个知识点串起来了:远程帧负责「要数据」,仲裁机制决定「谁先要」,位填充保证「要得稳」,错误帧处理「要坏了」的情况。你想想看,CAN总线这套机制是不是很完整?

好了,本章的内容就到这里。远程帧和错误帧是CAN总线调试中最容易出问题的环节,建议你在Wireshark里多抓几次实际波形,亲眼看看错误帧长什么样。下次我们聊聊CAN FD——那个更快、更猛的升级版。


公众号:蓝海资料掘金营,微信deep3321