3、CAN协议基础:CAN远程帧、错误帧、过载帧、帧间隔

好,咱们继续往下聊。前面我们把CAN的数据帧和遥控帧(也就是远程帧)的基本结构讲清楚了。但说实话,一个总线要稳定运行,光靠数据帧和远程帧是远远不够的。你想想看,万一总线上出了错怎么办?某个节点发疯了怎么办?

嗯,这就是我们今天要聊的——错误帧、过载帧和帧间隔。这三兄弟,说白了就是CAN总线的“交警”和“清道夫”。

3.1 远程帧:我只要数据,你别发给我

远程帧,也叫遥控帧。它的作用很简单:一个节点向另一个节点请求数据

我记得刚入行那会儿,有个老工程师跟我说:“远程帧就是‘我要,你别给’。” 我当时一愣,后来才明白——远程帧本身不携带数据场,它只是告诉目标节点:“嘿,把你那个ID为0x123的数据发给我。”

远程帧的结构和数据帧几乎一样,区别只有两点:

  • RTR位为隐性(1):表示这是一个远程帧请求
  • 没有数据场:DLC虽然存在,但表示请求的数据长度,而不是实际发送的数据

重要: 远程帧的仲裁场和数据帧完全一样。如果总线上同时出现一个数据帧和一个远程帧,且ID相同,那么数据帧会赢得仲裁(因为RTR=0,显性优先)。

我在项目中遇到过一个问题:某个传感器节点一直发远程帧,但目标节点没响应。查了半天,发现是DLC写错了。目标节点认为请求的是8字节,但实际只准备了2字节的数据,结果一直没发出来。嗯,这种坑,踩过一次就记住了。

3.2 错误帧:总线的“紧急刹车”

错误帧,是CAN总线最核心的容错机制。没有它,CAN就不叫CAN了。

错误帧的长度是6个显性位 + 8个隐性位,总共14位。结构很简单:

  • 错误标志(Error Flag):6个连续的显性位
  • 错误界定符(Error Delimiter):8个连续的隐性位

为什么会这样?因为一旦某个节点检测到错误,它会立刻拉低总线,发送6个显性位。其他节点收到这个“异常信号”后,也会跟着发送错误标志。这样一来,总线上就会出现6~12个显性位(取决于节点间的同步情况)。

注意: 错误帧的发送时机非常关键。节点只能在检测到错误的下一个位时间开始发送错误帧。如果错过了这个窗口,错误帧就会变成过载帧——嗯,这是另一个故事了。

我曾经调试过一个ECU,它在高温下频繁报错。用CAN分析仪一看,错误帧满天飞。后来发现是晶振漂移了,导致位时序不对。你想想看,一个节点在错误的状态下不断重发错误帧,整个总线都被它拖垮了。这就是所谓的“总线关闭”状态。

3.3 过载帧:我忙,别打扰我

过载帧,说白了就是节点在说:“我处理不过来了,你等会儿。”

过载帧的结构和错误帧几乎一样:

  • 过载标志(Overload Flag):6个显性位
  • 过载界定符(Overload Delimiter):8个隐性位

但触发条件完全不同。过载帧只在两种情况下产生:

  1. 接收节点内部条件未准备好:比如CPU太忙,缓冲区满了
  2. 帧间隔的间歇场检测到显性位:这属于总线异常,但节点用“过载”来响应

我个人习惯把过载帧看作是“礼貌的拒绝”。它不像错误帧那样是“出事了”,而是“我暂时不行”。

小技巧: 如果你的系统频繁出现过载帧,别急着怀疑硬件。先看看接收节点的中断优先级和DMA配置。很多时候,是软件没来得及把数据从CAN控制器读走。

3.4 帧间隔:总线的“呼吸节奏”

帧间隔,是CAN总线上两个帧之间的“休息时间”。它保证了总线上的节点有足够的时间同步和准备。

帧间隔由三部分组成:

字段 长度 说明
间歇场(Intermission) 3个隐性位 所有节点必须等待这3位才能开始下一帧
总线空闲(Bus Idle) 任意长度 总线处于隐性状态,节点可以开始发送
暂停发送(Suspend Transmission) 8个隐性位 仅错误被动节点需要等待

这里有个细节:间歇场的3个隐性位,是强制性的。任何节点都不能在这3位期间发送数据。如果某个节点在间歇场检测到显性位,它会认为这是一个过载帧的开始,然后发送过载标志。

我记得有一次,一个同事问我:“为什么我的CAN总线在高速运行时,偶尔会丢帧?” 我让他抓波形一看,发现帧间隔被压缩了——某个节点在间歇场就开始发送数据。嗯,这其实是违反了CAN协议的。后来发现是那个节点的晶振精度不够,导致位时间计算有偏差。

3.5 四种帧的对比总结

好了,我们把CAN的四种帧类型放在一起对比一下:

帧类型 用途 数据场 触发条件
数据帧 发送数据 有(0~8字节) 节点主动发送
远程帧 请求数据 节点主动发送
错误帧 报告错误 任何节点检测到错误
过载帧 请求延迟 接收节点忙或间歇场异常

你可能会问:“为什么远程帧和过载帧用得少?” 嗯,说实话,在大多数汽车应用中,远程帧确实用得不多。大家更习惯用数据帧来主动上报。而过载帧,只有在系统设计不合理时才会频繁出现。

但作为工程师,你必须理解它们。因为当你遇到总线异常时,能看懂错误帧和过载帧,就等于拿到了诊断的“钥匙”。

核心要点:

  • 远程帧:RTR=1,无数据场,用于请求数据
  • 错误帧:6显性+8隐性,由错误检测触发
  • 过载帧:6显性+8隐性,由接收忙或间歇场异常触发
  • 帧间隔:3隐性间歇场 + 总线空闲 + 8隐性暂停(仅错误被动节点)

下一章,我们会深入CAN的位时序和同步机制。嗯,那才是真正考验硬件功底的地方。到时候我会分享一个我当年调CAN波特率的血泪史——保证让你印象深刻。