2、CAN总线物理层:差分信号原理、CAN_H与CAN_L电平定义、显性与隐性电平

好,咱们进入物理层。说实话,很多工程师做CAN通信出问题,根源都在物理层。协议栈写得再漂亮,电平不对,一切都是白搭。今天我就把差分信号、CAN_H/CAN_L电平、还有显隐性这几个核心概念,掰开了揉碎了讲清楚。

2.1 为什么CAN要用差分信号?

你想想看,汽车发动机舱里,电磁干扰有多严重?火花塞点火、电机启停,那噪声简直像在开水里煮。如果用普通的单端信号(比如UART的TX/RX),一根信号线对地,干扰一上来,电平就乱跳,通信直接崩了。

CAN总线聪明在哪?它用两根线——CAN_H和CAN_L,传的是电压差。接收器只看两根线之间的差值,不看它们各自对地的绝对值。这就好比两个人抬杠,不管地面怎么晃,只要他俩的力气差不变,结果就不变。干扰同时作用在两根线上,差值基本不受影响。这就是共模抑制。

我在项目里遇到过一件事:一台设备在实验室跑得好好的,装到电动叉车上就频繁丢帧。查了半天,发现是电机驱动器产生的共模干扰太强,把单端信号线打穿了。换成CAN总线后,问题直接消失。嗯,差分信号就是这么硬气。

2.2 CAN_H与CAN_L的电平定义

CAN总线在物理层定义了两种电平状态:显性隐性。这两个词听着玄乎,其实很简单。

咱们先看具体电压值。以最常用的高速CAN(ISO 11898-2)为例:

状态 CAN_H电压 CAN_L电压 差分电压 (CAN_H - CAN_L)
隐性 (Recessive) 2.5V 2.5V ≈ 0V
显性 (Dominant) 3.5V 1.5V ≈ 2V

看到没?隐性时,两根线都是2.5V,差值为0。显性时,CAN_H被拉到3.5V,CAN_L被拉到1.5V,差值约2V。接收器就是靠检测这个差分电压是0V还是2V,来判断总线上的逻辑电平。

核心记忆点:

  • 隐性 = 差分电压 ≈ 0V → 逻辑"1"
  • 显性 = 差分电压 ≈ 2V → 逻辑"0"

这里有个容易混淆的地方:显性电平对应逻辑0,隐性电平对应逻辑1。跟咱们平时习惯的"高电平=1"正好相反。我第一次用CAN时也犯过嘀咕,后来习惯了就好。你只要记住:CAN总线上,谁想抢总线,谁就拉显性(0)。

2.3 显性与隐性:总线仲裁的物理基础

为什么会这样?因为CAN总线是线与机制。多个节点同时发送时,只要有一个节点输出显性(0),总线就被拉成显性。隐性(1)只有在所有节点都输出隐性时才能维持。

说白了,显性电平的"优先级"更高。这就是CAN总线非破坏性仲裁的物理基础。两个节点同时发数据,谁的ID更小(显性位更多),谁就能赢得仲裁。这个咱们后面讲数据链路层时会细说。

我曾经帮一个客户排查过总线锁死的问题。现象是总线一直处于显性状态,所有节点都发不出数据。用示波器一量,CAN_H和CAN_L的电压分别是3.5V和1.5V,纹丝不动。最后发现是一个节点的CAN收发器坏了,输出一直卡在显性。嗯,这就是典型的"显性故障"。

避坑指南:

我曾经在调试时忽略了一个细节:CAN收发器的隐性电平并不是绝对的0V差分。实际测量时,由于电阻匹配和噪声,隐性差分电压可能在-50mV到+50mV之间波动。只要不超过接收器的阈值(通常±0.5V),都算正常。别一看到几毫伏的波动就以为是故障。

2.4 收发器是怎么工作的?

收发器(Transceiver)是MCU的CAN控制器和物理总线之间的桥梁。控制器输出逻辑信号(0或1),收发器把它转换成CAN_H和CAN_L上的差分电压。

简单来说:

  • 控制器输出逻辑0(显性)→ 收发器内部驱动CAN_H到3.5V,CAN_L到1.5V
  • 控制器输出逻辑1(隐性)→ 收发器释放总线,靠终端电阻把两根线拉到2.5V

接收方向相反:收发器检测CAN_H和CAN_L的差分电压,如果大于0.9V就判为显性(0),小于0.5V就判为隐性(1)。中间有迟滞,防止噪声误触发。

我习惯在选型时关注收发器的几个关键参数:

  • 共模输入范围:高速CAN一般是-2V到+7V,恶劣环境下要选更宽的
  • 循环延迟:影响最大通信速率,延迟越大,速率上限越低
  • 斜率控制:有些收发器支持调整上升/下降沿斜率,能减少EMI

个人经验:

如果你在做低速或容错CAN(ISO 11898-3),电平定义会不一样。隐性时CAN_H≈0V,CAN_L≈5V;显性时CAN_H≈5V,CAN_L≈0V。千万别拿高速CAN的电压值去套,我见过有人因此烧了收发器。

2.5 总结一下

物理层是CAN通信的基石。差分信号给了它强大的抗干扰能力,显隐性电平定义了总线仲裁的规则。你只要记住:

  • 两根线,看差值
  • 隐性≈0V差,显性≈2V差
  • 显性优先,逻辑0抢总线

下一节咱们讲终端电阻。这东西看着就两个电阻,但放不对位置、选不对阻值,整个网络都跑不起来。到时候我分享一个因为终端电阻没接好,导致通信时好时坏的案例,保证让你印象深刻。