2. CAN总线物理层:差分信号原理、CAN_H与CAN_L电平定义、显性电平与隐性电平
好,咱们开始聊CAN总线的物理层。
说实话,很多工程师学CAN总线,上来就怼协议栈、怼报文格式,结果硬件上出了问题,查半天查不到原因。我个人的经验是——物理层搞不明白,上层玩得再花也是白搭。
这一节,咱们就把CAN总线物理层的底裤扒干净。重点就三个东西:差分信号、CAN_H与CAN_L的电平定义、以及显性电平与隐性电平。
2.1 为什么CAN要用差分信号?
你想想看,汽车里面电磁环境多恶劣?发动机点火、电机启停、各种继电器噼里啪啦。要是用普通的单端信号(比如UART那种一根线对地传数据),稍微来点共模干扰,信号就废了。
CAN总线聪明就聪明在——它用两根线传一个信号。
这两根线分别是CAN_H(高电平线)和CAN_L(低电平线)。接收器不看单根线的绝对电压,而是看两根线的电压差:
V_diff = CAN_H - CAN_L
为什么要看差值?因为外界的电磁干扰通常是同时作用在两根线上的(这叫共模干扰)。比如来了个干扰,CAN_H从2.5V跳到了3.0V,CAN_L也从2.5V跳到了3.0V,差值呢?还是0V。信号纹丝不动。
核心结论:差分信号天然抗共模干扰。这是CAN总线能在工业现场、汽车底盘这种恶劣环境中存活下来的根本原因。
我在项目中遇到过一件事:有个客户用CAN通信,距离大概200米,怎么调都丢包。后来发现他用的线缆是普通双绞线,屏蔽层没接地。换成带屏蔽的CAN专用线缆,问题立刻消失。嗯,差分信号虽然抗干扰,但线缆质量不能省。
2.2 CAN_H与CAN_L的电平定义
CAN总线在空闲时,两根线的电压是多少?
标准答案是:2.5V。
没错,CAN_H和CAN_L在总线空闲时,都稳定在2.5V。这时候差分电压V_diff = 0V。这个状态叫做隐性电平(Recessive Level)。
那当有节点要发送数据时呢?它会主动拉高CAN_H、拉低CAN_L:
- CAN_H:从2.5V 上升到 3.5V(大约)
- CAN_L:从2.5V 下降到 1.5V(大约)
这时候差分电压V_diff = 3.5V - 1.5V = 2.0V。这个状态叫做显性电平(Dominant Level)。
我习惯用一个简单的表格来记:
| 状态 | CAN_H电压 | CAN_L电压 | 差分电压 (V_diff) | 逻辑值 |
|---|---|---|---|---|
| 隐性 (Recessive) | 2.5V | 2.5V | 0V | 1(逻辑高) |
| 显性 (Dominant) | 3.5V | 1.5V | 约2.0V | 0(逻辑低) |
小提示:注意看,CAN总线的逻辑和常规思维是反的。隐性电平对应逻辑1,显性电平对应逻辑0。我第一次用示波器抓波形时,差点被这个搞晕。
2.3 显性电平与隐性电平的博弈
为什么叫“显性”和“隐性”?
这名字起得特别形象。你想想看:
- 隐性电平:总线空闲时的状态,像空气一样“看不见”。任何节点都可以把它拉成显性。
- 显性电平:只要有一个节点输出显性,总线就变成显性。其他节点想保持隐性?没门。
说白了,显性电平会覆盖隐性电平。这就是CAN总线实现“线与”仲裁的物理基础。
我曾经调试过一个多节点通信的系统,发现有一个节点老是发不出数据。用示波器一量,好家伙,这个节点的CAN_H电压死活拉不到3.5V,只能到3.0V。查了半天,是CAN收发器的驱动能力出了问题。你看,物理层一个小细节,就能让整个网络瘫痪。
2.4 实际波形长什么样?
如果你用示波器去抓CAN_H和CAN_L的波形,会看到这样的景象:
示波器通道1(黄色):CAN_H —— 在2.5V和3.5V之间跳变
示波器通道2(绿色):CAN_L —— 在2.5V和1.5V之间跳变
数学通道(红色): CAN_H - CAN_L —— 在0V和2.0V之间跳变
我个人习惯把数学通道打开,直接看差分信号。这样最直观,干扰一眼就能看出来。
避坑指南:我曾经犯过一个低级错误——用示波器探头的地线夹子夹在CAN_H上,结果把总线对地短路了。记住,CAN总线是浮地的,示波器探头的地线不能随便乱夹。最好用差分探头,或者用两个通道做减法。
2.5 总结一下
这一节的内容,说白了就三句话:
- 差分信号:CAN_H减CAN_L,抗干扰的秘诀。
- 电平定义:隐性2.5V对2.5V,显性3.5V对1.5V。
- 显性压倒隐性:这是CAN总线仲裁的物理基础。
嗯,物理层搞明白了,后面讲仲裁、讲错误处理,你才能听得懂。下一节咱们聊聊CAN总线的终端电阻——别小看那两个120欧姆的电阻,接不对位置,整个网络都废了。