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 总结一下

这一节的内容,说白了就三句话:

  1. 差分信号:CAN_H减CAN_L,抗干扰的秘诀。
  2. 电平定义:隐性2.5V对2.5V,显性3.5V对1.5V。
  3. 显性压倒隐性:这是CAN总线仲裁的物理基础。

嗯,物理层搞明白了,后面讲仲裁、讲错误处理,你才能听得懂。下一节咱们聊聊CAN总线的终端电阻——别小看那两个120欧姆的电阻,接不对位置,整个网络都废了。