2. CAN总线基础:从物理层到仲裁机制
各位好,我是老周。今天咱们聊聊CAN总线的基础。说实话,我在车载网络这行干了十几年,CAN总线就像老朋友一样熟悉。很多刚入行的工程师觉得CAN协议复杂,其实拆开来看,无非就是物理层怎么传信号、数据链路层怎么组报文、以及多个节点同时发消息时怎么抢通道——也就是仲裁机制。
嗯,咱们一个一个来。
2.1 CAN物理层:差分信号与总线电平
CAN总线物理层用的是差分信号传输。说白了,就是两根线——CAN_H和CAN_L,通过它们之间的电压差来表示逻辑0和逻辑1。
| 信号状态 | CAN_H电压 | CAN_L电压 | 差分电压 | 逻辑值 |
|---|---|---|---|---|
| 显性(Dominant) | 3.5V | 1.5V | 2.0V | 0 |
| 隐性(Recessive) | 2.5V | 2.5V | 0V | 1 |
为什么用差分?抗干扰能力强。车载环境电磁干扰严重,你想想看,发动机点火、电机运转,到处都是噪声。差分信号共模抑制比高,干扰信号在两根线上同时出现,差分电压不受影响。我在一个项目中遇到过,某款车在EMC测试时CAN通信频繁丢帧,最后查出来是CAN_H和CAN_L的绞距不对,共模扼流圈选型也有问题。换了个规格,问题就解决了。
2.2 CAN数据链路层:报文帧结构
CAN协议定义了四种帧类型:数据帧、远程帧、错误帧、过载帧。咱们最常用的是数据帧。数据帧又分标准帧和扩展帧,区别在于ID的长度。
2.2.1 标准帧(11位ID)
标准帧的格式是这样的:
SOF + 11位ID + RTR + IDE + r0 + DLC + 数据段(0-8字节) + CRC + ACK + EOF
每个字段的含义:
- SOF(Start of Frame):1位显性,表示帧开始
- ID(Identifier):11位,决定报文优先级
- RTR(Remote Transmission Request):数据帧为显性,远程帧为隐性
- IDE(Identifier Extension):标准帧为显性
- DLC(Data Length Code):4位,表示数据字节数(0-8)
- 数据段:0-8字节,实际载荷
- CRC:15位校验 + 1位定界符
- ACK:2位(应答间隙 + 定界符)
- EOF:7位隐性,帧结束
2.2.2 扩展帧(29位ID)
扩展帧就是把ID从11位扩展到29位。结构上多了个SRR位和扩展ID段:
SOF + 11位基础ID + SRR + IDE(隐性) + 18位扩展ID + RTR + r1 + r0 + DLC + 数据段 + CRC + ACK + EOF
你可能会问:标准帧和扩展帧能不能混用?能。但要注意,标准帧的优先级永远高于扩展帧。为什么?因为标准帧的IDE位是显性,扩展帧的IDE位是隐性。仲裁时显性胜出。
- 标准帧:11位ID,帧头更短,实时性更好
- 扩展帧:29位ID,可分配更多节点和信号,但带宽利用率略低
- 我个人建议:能用标准帧就别用扩展帧,除非ID不够用
2.3 CAN总线仲裁机制
这是CAN协议最巧妙的地方。多个节点同时发送时,怎么决定谁先发?靠ID仲裁。
原理很简单:总线电平是“线与”逻辑。显性(0)会覆盖隐性(1)。仲裁时,每个节点逐位发送ID,从高位到低位。如果某个节点发送了隐性位,但总线上是显性,它就退出竞争。
举个例子:
- 节点A:ID = 0x123(二进制:0001 0010 0011)
- 节点B:ID = 0x456(二进制:0100 0101 0110)
从最高位开始比:
- 第1位:A发0,B发0,总线0,继续
- 第2位:A发0,B发1,总线0(显性覆盖隐性),B检测到总线与自身发送不一致,退出
- A继续发送剩余位,最终赢得仲裁
所以,ID值越小,优先级越高。0x000是最高优先级。
2.4 知识结构总览
下面这张图把CAN总线基础的核心知识点串起来了:
2.5 实际应用中的注意事项
讲完理论,说点实际的。你在配置车载网关时,CAN总线这块有几个地方容易出问题:
- 波特率必须一致:总线上所有节点的波特率要相同。常见的车载CAN波特率有125kbps、250kbps、500kbps。我记得有个项目,ECU和网关的波特率配置差了0.5%,结果通信时好时坏,排查了两天才发现。
- ID分配要有规划:高优先级报文(如制动、转向)用小编号ID,低优先级报文(如空调、车窗)用大编号ID。别把关键信号放在低优先级上。
- 数据长度别浪费:CAN帧最多8字节数据。能塞进一帧就别拆成两帧,减少总线负载。
好了,CAN总线基础就聊到这儿。物理层的差分信号、数据链路层的帧结构、仲裁机制的逐位竞争,这三块是后续学习网关配置和调试的基石。你把这些搞透了,后面遇到CAN相关的故障,心里就有底了。