2. CAN总线基础:物理层、数据链路层与仲裁机制

CAN总线,说白了就是车载网络里的“老大哥”。从1990年代诞生到现在,几乎每辆车里都有它的身影。我刚开始做车载网络那会儿,第一个接触的就是CAN。嗯,咱们今天就把它的底细摸清楚。

2.1 CAN总线的物理层

物理层解决的是“信号怎么在线上跑”的问题。CAN总线用两根线——CAN_H和CAN_L,构成差分传输。

核心概念:显性电平 vs 隐性电平

  • 显性电平(Dominant):CAN_H ≈ 3.5V,CAN_L ≈ 1.5V,逻辑上代表“0”
  • 隐性电平(Recessive):CAN_H ≈ 2.5V,CAN_L ≈ 2.5V,逻辑上代表“1”
  • 显性电平会“覆盖”隐性电平——这是仲裁机制的基础

为什么用差分?抗干扰。我在一个项目中遇到过,某款车在EMC测试时CAN通信老丢帧。查了半天,发现是CAN_H和CAN_L的绞距不均匀,共模抑制比下降了。换了对绞线,问题解决。你想想看,两根线拧得越紧,抗干扰越好。

参数 高速CAN(ISO 11898-2) 低速CAN(ISO 11898-3)
最大速率 1 Mbps 125 kbps
总线长度(1 Mbps时) ≤ 40 m ≤ 500 m
终端电阻 120 Ω(两端各一个) 不需要
显性电平差 ≥ 1.5V ≥ 1.2V

我的习惯:设计CAN网络时,终端电阻一定要放在总线物理两端,而不是ECU内部。曾经有个项目把电阻焊在了PCB上,结果节点一多,信号反射得一塌糊涂。

2.2 数据链路层与报文帧结构

数据链路层负责“怎么把数据打包发出去”。CAN有四种帧类型,咱们重点看数据帧。

2.2.1 标准帧 vs 扩展帧

CAN 2.0A定义了11位ID的标准帧,CAN 2.0B增加了29位ID的扩展帧。我个人习惯:能用标准帧就别用扩展帧,因为帧头短,总线利用率高。

标准帧结构(11位ID):
| SOF | 11位ID | RTR | IDE | r0 | DLC | 数据段(0-8字节) | CRC | ACK | EOF |

扩展帧结构(29位ID):
| SOF | 11位ID | SRR | IDE | 18位ID | RTR | r1 | r0 | DLC | 数据段 | CRC | ACK | EOF |

字段说明:

  • SOF(Start of Frame):1位显性,同步信号
  • ID:标识符,决定优先级(数值越小优先级越高)
  • RTR(Remote Transmission Request):区分数据帧(0)和远程帧(1)
  • DLC(Data Length Code):4位,表示数据字节数(0-8)
  • CRC:15位校验 + 1位定界符
  • ACK:2位(应答间隙 + 定界符)

避坑指南:我曾经在项目中看到有人把DLC设成8但只发了3个字节,接收方读到的全是垃圾数据。记住:DLC必须与实际数据长度一致,否则CRC校验过不了。

2.3 CAN总线仲裁机制

仲裁是CAN最巧妙的设计。多个节点同时发送时,谁优先级高谁先发,而且不丢数据。

为什么会这样?因为CAN总线是“线与”逻辑。显性电平(0)会覆盖隐性电平(1)。仲裁时,每个节点在发送ID的每一位时,都会回读总线电平。如果自己发的是隐性(1),但读到的是显性(0),说明有更高优先级的节点在发,自己立刻退出发送。

仲裁规则:ID数值越小,优先级越高。0x000最高,0x7FF最低(标准帧)。

举个例子:

  • 节点A发ID = 0x123(二进制:0001 0010 0011)
  • 节点B发ID = 0x456(二进制:0100 0101 0110)
  • 从最高位开始比:第1位A发0,B发0 → 继续;第2位A发0,B发1 → A显性覆盖B隐性 → B退出
  • 节点A赢得仲裁,继续发送剩余数据

你想想看,这个过程完全在硬件里完成,不需要额外的仲裁帧,效率极高。

CAN总线仲裁流程 节点A ID = 0x123 节点B ID = 0x456 CAN总线 仲裁开始:逐位比较ID 位1: A=0, B=0 位2: A=0, B=1 B退出仲裁 A继续发送数据 结果:节点A赢得总线,节点B等待重发

我的经验:设计ID分配时,把实时性要求高的信号(如刹车、转向)放在小ID。我曾经见过一个项目把车窗信号ID设得比刹车还小,结果刹车指令被堵了——这要是上路,后果不堪设想。

2.4 错误检测与处理

CAN有5种错误检测机制,我挑几个重点说:

  • 位错误(Bit Error):发送时回读电平不一致
  • 填充错误(Stuff Error):连续5个相同位后没有填充反相位
  • CRC错误:接收方计算的CRC与发送方不一致
  • 格式错误(Form Error):固定格式位(如CRC定界符)不是隐性
  • ACK错误:发送方在ACK间隙没读到显性电平

检测到错误后,节点会发送错误帧(6个显性位),强制总线进入错误状态,然后重发。嗯,这里要注意:错误计数器超过255,节点会进入Bus Off状态,彻底断开总线。

我曾经踩过的坑:某次台架测试,CAN总线突然瘫痪。查日志发现一个ECU的错误计数器飙到了256,进入了Bus Off。原因是它的CAN收发器电源纹波太大,导致位采样出错。加了个LC滤波,问题解决。所以,硬件设计别马虎。

2.5 小结

CAN总线的物理层靠差分信号抗干扰,数据链路层用ID仲裁决定优先级,错误机制保证可靠性。这三个东西,是理解所有车载网络的基础。你想想看,一个1990年代设计的总线协议,到现在还在用,说明它的设计有多扎实。