一、CAN总线基础:从协议到故障界定

各位好,我是老周。在车载网络这行摸爬滚打了十几年,今天咱们聊聊CAN总线。说实话,CAN总线是车载通信的基石,不管你以后做诊断、刷写还是搞自动驾驶,都绕不开它。这一章,我把最核心的东西拎出来讲透。

1.1 CAN协议概述——为什么是它?

CAN(Controller Area Network)是上世纪80年代由Bosch公司开发的串行通信协议。为什么汽车行业选它?说白了,就三个字:可靠、实时、低成本。

我刚开始做项目时,遇到过一台车在高速上突然报“发动机通信丢失”。查了一整天,最后发现是CAN总线上一根线的终端电阻虚焊了。嗯,从那以后,我对CAN物理层的敬畏心就上来了。

CAN的核心特点:

  • 多主总线:任何节点都可以主动发消息,不需要主机轮询
  • 差分信号:抗干扰能力强,适合车载恶劣环境
  • 非破坏性仲裁:优先级高的报文自动胜出,低优先级的自动退让
  • 错误检测机制:5种错误检测方式,误码率极低

你想想看,一辆现代汽车上有几十个ECU,如果每个ECU之间都点对点连线,那线束得有多重?CAN总线用两根线就把所有节点串起来了,这就是它的价值。

1.2 CAN总线物理层——两根线的学问

物理层看着简单,就两根线:CAN_H和CAN_L。但这里面的门道不少。

参数 高速CAN(ISO 11898-2) 低速CAN(ISO 11898-3)
最大速率 1 Mbps 125 kbps
总线长度 ≤ 40 m @ 1 Mbps ≤ 500 m
隐性电平 CAN_H ≈ 2.5V, CAN_L ≈ 2.5V CAN_H ≈ 1.5V, CAN_L ≈ 3.5V
显性电平 CAN_H ≈ 3.5V, CAN_L ≈ 1.5V CAN_H ≈ 4.0V, CAN_L ≈ 1.0V
终端电阻 两端各120Ω 不需要

我曾经踩过的坑:有一次产线上批量出现CAN通信偶发中断,查了三天,最后发现是终端电阻用了100Ω的贴片,而不是120Ω。阻抗不匹配导致信号反射,在总线长度较长时就会丢帧。记住:高速CAN两端必须各接一个120Ω电阻,不能省!

物理层的信号逻辑是这样的:

  • 隐性(Recessive):CAN_H和CAN_L都是2.5V,差分电压≈0V,逻辑值为1
  • 显性(Dominant):CAN_H升到3.5V,CAN_L降到1.5V,差分电压≈2V,逻辑值为0

显性位会覆盖隐性位。这就是仲裁的基础——ID值越小(显性位越多),优先级越高。

1.3 CAN总线数据帧结构——报文长什么样?

CAN总线上跑的数据帧,我习惯把它拆成几个关键部分来看。咱们以最常用的标准帧(11位ID)为例:

帧起始(1bit) | 仲裁场(12bit) | 控制场(6bit) | 数据场(0~8byte) | CRC场(16bit) | ACK场(2bit) | 帧结束(7bit)

拆开来看:

字段 长度 说明
SOF 1 bit 帧起始,显性位,同步所有节点
Identifier 11 bit(标准帧) 报文ID,决定优先级,数值越小优先级越高
RTR 1 bit 远程帧标志,0=数据帧,1=远程帧
IDE 1 bit 扩展帧标志,0=标准帧,1=扩展帧
DLC 4 bit 数据长度,0~8字节
Data 0~64 bit 实际数据,最多8字节
CRC 15 bit + 1分隔符 循环冗余校验,检测传输错误
ACK 1 bit + 1分隔符 应答位,接收节点发送显性位确认
EOF 7 bit 帧结束,全部为隐性位

我个人的小习惯:看CAN报文时,先看ID,再看DLC,最后看数据。ID决定了这条报文是谁发的、优先级多高;DLC告诉你数据长度对不对;数据域才是真正的信号值。很多新手一上来就盯着数据看,反而忽略了ID和DLC,容易误判。

扩展帧(29位ID)的结构类似,只是仲裁场更长。我个人建议,能用标准帧就别用扩展帧,因为扩展帧的仲裁时间更长,总线利用率会下降。

1.4 CAN总线错误帧与故障界定——出了问题怎么办?

CAN总线最牛的地方,就是它的错误处理机制。我见过太多工程师,只会用CANoe抓报文,但看不懂错误帧,更不知道怎么定位故障。这一节,咱们把它讲透。

1.4.1 五种错误类型

CAN协议定义了5种错误:

  1. 位错误(Bit Error):发送节点在发送位的同时监控总线,如果读到的电平与发送的不一致,就报位错误。注意:仲裁期间和ACK位不报此错。
  2. 填充错误(Stuff Error):CAN协议规定,连续5个相同电平后必须插入一个相反电平。如果接收节点检测到连续6个相同电平,就报填充错误。
  3. CRC错误(CRC Error):接收节点计算的CRC与发送节点的不一致。
  4. 格式错误(Form Error):固定格式的位段(如CRC分隔符、ACK分隔符、EOF)出现非法电平。
  5. 应答错误(ACK Error):发送节点在ACK槽没有检测到显性位,说明没有节点收到有效报文。

实际排查经验:我在现场遇到过一台车,每次急刹车时仪表盘就黑屏。抓CAN日志发现,刹车瞬间总线上出现大量CRC错误和填充错误。最后定位到是刹车灯电源模块的开关噪声耦合到了CAN线上。解决办法是在CAN_H/CAN_L上加共模扼流圈,问题解决。

1.4.2 错误帧结构

当任何节点检测到错误时,它会发送一个错误帧。错误帧由两部分组成:

  • 错误标志(Error Flag):6个连续显性位(主动错误节点)或6个连续隐性位(被动错误节点)
  • 错误分隔符(Error Delimiter):8个连续隐性位

错误帧会破坏当前正在传输的报文,迫使所有节点重新发送。这就是CAN的“自愈”机制——出错就重来,直到成功为止。

1.4.3 故障界定——节点是怎么“变坏”的?

CAN控制器内部有两个计数器:发送错误计数器(TEC)和接收错误计数器(REC)。根据这两个计数器的值,节点会处于三种状态之一:

状态 条件 行为
主动错误 TEC ≤ 127 且 REC ≤ 127 正常通信,检测到错误时发送主动错误帧(6个显性位)
被动错误 TEC > 127 或 REC > 127 可以接收和发送,但检测到错误时只能发送被动错误帧(6个隐性位),且发送前要等待8个隐性位
总线关闭 TEC > 255 完全断开与总线的连接,不再发送任何报文

我曾经遇到的一个典型案例:某车型的BCM(车身控制模块)在高温老化测试后频繁报“总线关闭”。查TEC/REC寄存器发现,TEC飙到了255以上。原因是BCM的CAN收发器在高温下驱动能力下降,导致发送的显性位电平不够,被其他节点误判为位错误,进而触发TEC递增。最终解决方案是更换了宽温范围的收发器芯片。

故障界定的核心逻辑是:谁犯错多,谁就承担后果。一个节点如果频繁发送错误帧,它的TEC会不断增长,最终把自己“踢出”总线。这种设计保证了单个故障节点不会拖垮整个网络。

知识体系总览

下面这张图,我把本章的核心知识点串起来了。建议你保存下来,以后排查故障时对照着看。

CAN总线基础知识体系 CAN总线基础知识体系 CAN总线 协议概述 物理层 数据帧结构 错误帧与故障界定 多主总线 · 差分信号 非破坏性仲裁 · 错误检测 CAN_H / CAN_L 差分对 终端电阻 · 显性/隐性电平 ID · DLC · Data · CRC 标准帧(11bit) / 扩展帧(29bit) 5种错误类型 · 错误帧结构 TEC/REC · 主动/被动/总线关闭 💡 排查故障时,先看物理层(电阻/电平),再看错误计数器(TEC/REC) 最后分析错误帧类型,三步定位法最有效

我的排查三步法:

  1. 看物理层:用万用表测CAN_H和CAN_L之间的电阻,正常应该是60Ω(两个120Ω并联)。测对地电压,显性时CAN_H≈3.5V,CAN_L≈1.5V。
  2. 看错误计数器:用诊断工具读TEC和REC。如果某个节点的TEC持续增长,说明它在发送时频繁出错。
  3. 看错误类型:用CANoe或PCAN抓错误帧,看是位错误、CRC错误还是填充错误。不同类型指向不同的根因。

好了,这一章的内容就到这里。CAN总线的基础打牢了,后面讲诊断协议、讲故障排查,你才能听得懂、用得上。记住:车载通信的根,就在这两根线上。