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赢得仲裁,继续发送剩余数据
你想想看,这个过程完全在硬件里完成,不需要额外的仲裁帧,效率极高。
我的经验:设计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年代设计的总线协议,到现在还在用,说明它的设计有多扎实。