2. CAN协议基础:CAN总线物理层特性、差分信号原理、CAN帧结构
大家好,我是你们的老朋友。今天咱们来聊聊CAN总线的基础知识。说实话,CAN协议在汽车电子里太常见了,几乎每个ECU都离不开它。我当年刚入行时,第一次调试CAN通信就遇到了信号干扰问题,折腾了两天才搞定。所以今天我把这些经验都揉碎了讲给你听。
2.1 CAN总线物理层特性
CAN总线物理层,说白了就是信号怎么在线上跑的问题。它用的是两根线——CAN_H和CAN_L。这两根线绞在一起,形成双绞线结构。为什么要绞?为了抗干扰。你想想看,两根线绞在一起,外部电磁干扰对两根线的影响几乎一样,这就为后面的差分信号打下了基础。
CAN总线的电平状态有两种:显性(Dominant)和隐性(Recessive)。显性电平对应逻辑0,隐性电平对应逻辑1。这里有个关键点:显性电平会覆盖隐性电平。也就是说,只要有一个节点发送显性电平,总线就呈现显性状态。这个特性在总线仲裁时特别有用。
我习惯把CAN总线的物理层特性总结成一张表,方便你对照:
| 参数 | 高速CAN(ISO 11898-2) | 低速CAN(ISO 11898-3) |
|---|---|---|
| 最大速率 | 1 Mbps | 125 kbps |
| 总线长度(1 Mbps时) | 约40米 | 约500米 |
| 显性电平电压差 | 约2V | 约1.5V |
| 隐性电平电压差 | 约0V | 约0V |
| 终端电阻 | 120Ω(两端各一个) | 不强制要求 |
2.2 差分信号原理
差分信号是CAN总线的核心。为什么不用单端信号?因为汽车环境太嘈杂了。发动机点火、电机运转、各种电磁干扰,单端信号在这种环境下根本扛不住。
差分信号的工作原理其实很简单:发送端在CAN_H和CAN_L上分别输出互补的信号。接收端只关心两根线之间的电压差,不关心它们对地的绝对电压。这样一来,外部干扰同时作用在两根线上,电压差基本不变,信号就保住了。
具体来说:
- 显性状态: CAN_H电压约3.5V,CAN_L电压约1.5V,差分电压约2V
- 隐性状态: CAN_H和CAN_L电压都约2.5V,差分电压约0V
嗯,这里要注意一点:差分电压的阈值是有容差的。不同厂家的CAN收发器,阈值可能略有不同。我建议你在选型时留出20%的余量,别卡着极限值设计。
2.3 CAN帧结构
CAN协议定义了四种帧类型:数据帧、远程帧、错误帧和过载帧。咱们重点讲前三种,过载帧用得少,先放一放。
2.3.1 数据帧
数据帧是干活的主力。它负责把数据从一个节点传到另一个节点。标准格式的数据帧长这样:
SOF + 11位ID + RTR + IDE + r0 + 4位DLC + 0~8字节数据 + 15位CRC + CRC分隔符 + ACK + ACK分隔符 + EOF
我拆开来讲:
- SOF(帧起始): 1位显性电平,告诉所有节点"我要发数据了"
- ID(标识符): 标准帧11位,扩展帧29位。ID越小,优先级越高
- RTR(远程发送请求): 数据帧里是显性(0),远程帧里是隐性(1)
- DLC(数据长度码): 4位,表示数据字节数,范围0~8
- 数据段: 0~8字节,想传啥传啥
- CRC: 15位校验码,加上1位分隔符
- ACK: 接收节点在ACK槽里发送显性电平,表示"我收到了"
- EOF: 7位隐性电平,表示帧结束
2.3.2 远程帧
远程帧,说白了就是"请求帧"。一个节点发远程帧,意思是"谁有数据?给我发一份"。远程帧的结构和数据帧几乎一样,唯一的区别是RTR位为隐性(1),而且没有数据段。
举个例子:ECU_A想获取ECU_B的传感器数据,ECU_A就发一个远程帧,ID填ECU_B的数据帧ID。ECU_B收到后,就会发送对应的数据帧。
2.3.3 错误帧
错误帧是CAN总线的"交警"。当节点检测到总线错误时,就会发送错误帧,通知所有节点"刚才那帧有问题,别用了"。
错误帧由两部分组成:
- 错误标志: 6位相同电平(显性或隐性),主动错误节点发6位显性,被动错误节点发6位隐性
- 错误分隔符: 8位隐性电平
CAN协议定义了五种错误类型:
- 位错误: 发送节点监控总线,发现发送的电平和总线电平不一致
- 填充错误: 连续5个相同电平后,没有插入相反电平
- CRC错误: 接收节点计算的CRC和发送的不一致
- 格式错误: 帧格式不符合规范
- ACK错误: 发送节点在ACK槽没收到显性电平
为什么会这样设计?因为CAN总线要求高可靠性。任何一个节点发现错误,都要立即通知大家,避免错误数据被误用。
好了,CAN协议的基础就讲到这里。下一章咱们聊聊CAN的位时序和同步机制,这可是理解CAN通信质量的关键。有什么问题,欢迎随时交流。