第3章:CAN远程帧与错误帧

大家好,我是老张。今天咱们聊聊CAN总线里两个容易被忽视,但实际项目中坑特别多的东西——远程帧和错误帧。

说实话,我刚入行那会儿,觉得远程帧挺酷的,能主动请求数据。后来才发现,这东西用不好,反而会惹麻烦。至于错误帧,嗯,它就像总线上的“交警”,平时不出现,一出问题就得靠它来维持秩序。

3.1 远程帧的作用

远程帧,说白了就是一个“请求”。它不携带数据,只带一个ID。这个ID告诉其他节点:“嘿,谁有这个ID的数据,赶紧发给我!”

举个例子。BMS里有个温度传感器节点,平时不主动发数据。主控想知道当前温度,就发一个远程帧,ID设为温度传感器的ID。传感器收到后,立刻回复一个数据帧,把温度值传回来。

远程帧的结构和数据帧很像,但有两点关键区别:

  • RTR位:远程帧的RTR位是隐性(1),数据帧是显性(0)。这是区分两者的关键。
  • 数据长度码(DLC):远程帧的DLC表示期望接收的数据字节数,而不是实际发送的数据。

重要提醒:远程帧本身不包含数据场。它只是一个“空壳子”,用来触发其他节点的数据发送。

我在项目中遇到过一个问题:某个节点收到远程帧后,回复的数据帧ID和远程帧ID相同。如果总线上有多个节点使用同一个ID,就会发生冲突。所以,远程帧的ID必须唯一对应一个数据源。

3.2 错误帧的类型

错误帧是CAN总线自我保护的机制。当节点检测到总线错误时,就会主动发送错误帧,通知其他节点“刚才那帧数据有问题,别用了”。

错误帧分两种:

错误帧类型 触发条件 行为
主动错误帧 节点处于主动错误状态 发送6个连续显性位,强制破坏当前帧
被动错误帧 节点处于被动错误状态 发送6个连续隐性位,不破坏总线

主动错误帧比较“暴力”,直接拉低总线电平,让所有节点都知道出错了。被动错误帧则比较“温柔”,它只是尝试通知,但不强制破坏。

个人经验:我曾经调试一个BMS系统,发现某个节点频繁发送被动错误帧。查了半天,原来是它的时钟精度不够,导致位时序偏差。换了个晶振就好了。所以,硬件设计时一定要关注CAN控制器的时钟源。

3.3 错误处理机制

CAN总线有一套完整的错误计数机制。每个节点都有两个计数器:

  • 发送错误计数器(TEC):发送失败时增加,成功时减少。
  • 接收错误计数器(REC):接收出错时增加,成功时减少。

根据这两个计数器的值,节点会进入不同的状态:

状态 条件 行为
主动错误 TEC < 127 且 REC < 127 正常通信,检测到错误时发送主动错误帧
被动错误 TEC > 127 或 REC > 127 只能发送被动错误帧,且发送前需等待8个隐性位
总线关闭 TEC > 255 完全断开与总线的连接,不再参与任何通信

你想想看,这个机制其实挺聪明的。它让“犯错少”的节点继续工作,让“犯错多”的节点逐渐退出,避免一个坏节点拖垮整个总线。

避坑指南:我曾经遇到一个案例,某个节点因为软件bug,不断发送错误数据帧,导致TEC迅速飙升到255以上,最终进入总线关闭状态。整个BMS系统因此失去了那个节点的数据,差点引发过充事故。所以,一定要在软件里监控TEC和REC的值,提前预警。

3.4 总线关闭状态

总线关闭是CAN节点的“终极惩罚”。一旦进入这个状态,节点就像被踢出了群聊,再也收不到任何消息,也发不出任何消息。

为什么会这样?说白了,是为了保护总线。如果一个节点频繁出错,说明它可能硬件坏了或者软件跑飞了。如果让它继续发错误帧,整个总线都会被它搞瘫痪。所以,干脆让它闭嘴。

总线关闭后,节点怎么恢复?有两种方式:

  • 硬件复位:重新上电或复位CAN控制器,计数器清零。
  • 软件恢复:通过协议请求节点主动复位,或者等待128个11个隐性位(总线空闲)后自动恢复。

我个人习惯在BMS主控里加一个“看门狗”任务,定期检查各节点的错误计数器。如果发现某个节点接近总线关闭,就主动复位它,而不是等它自己崩溃。

关键点:总线关闭不是永久性的。只要错误原因被消除,节点可以通过复位重新加入总线。但复位前,一定要确保硬件和软件都恢复正常,否则会陷入“关闭-复位-再关闭”的死循环。

嗯,这里要注意:在BMS这种安全关键系统里,总线关闭可能导致严重后果。比如,电池监控节点关闭了,你就不知道电池状态了。所以,设计时一定要考虑冗余方案,比如双CAN总线,或者增加一个备用通信通道。

好了,这一章的内容就这些。远程帧和错误帧虽然基础,但理解透了,能帮你少踩很多坑。下一章咱们聊聊CAN的位时序和同步,那才是真正考验硬件功底的地方。