2、CAN物理层:差分信号原理、CAN_H与CAN_L电平、终端电阻作用、总线拓扑结构
大家好,欢迎来到第二讲。
上一讲我们聊了CAN总线能干什么,这一讲我们得把它的“地基”挖开看看。物理层,说白了就是信号怎么在线上跑。你想想看,汽车发动机舱里那么大的电磁干扰,要是用普通的0和5V传数据,早就被噪声淹没了。CAN为什么这么皮实?核心秘密就在——差分信号。
2.1 差分信号:为什么CAN能扛干扰?
我刚开始做嵌入式那会儿,对差分信号的理解就是“两根线传一个信号”,觉得挺浪费的。直到有一次在电机驱动项目里,用单端UART通信,电机一转,数据就全乱码了。后来换成CAN,同样的线缆长度,稳如老狗。这才真正体会到差分信号的价值。
差分信号的核心思想很简单:
- CAN_H 和 CAN_L 两根线,电压是反着变化的。
- 接收器不看单根线的绝对电压,而是看两根线的 电压差(Vdiff = CAN_H - CAN_L)。
为什么会这样?因为外部干扰通常是共模的——同时加到两根线上。比如一个强电磁脉冲过来,CAN_H从2.5V跳到3.0V,CAN_L也从2.5V跳到3.0V。单看每根线,信号变了,但它们的差值呢?3.0V - 3.0V = 0V,没变!这就是差分信号抗干扰的底层逻辑。
核心公式:
显性电平(逻辑0):CAN_H ≈ 3.5V,CAN_L ≈ 1.5V,Vdiff ≈ 2.0V
隐性电平(逻辑1):CAN_H ≈ 2.5V,CAN_L ≈ 2.5V,Vdiff ≈ 0V
我个人的习惯是,在画原理图时,一定把CAN_H和CAN_L这两根线走在一起,紧贴着走。这样共模干扰才能“公平”地加到两根线上,差分接收器才能完美抵消它。
2.2 CAN_H与CAN_L的电平逻辑
CAN总线上的电平不是简单的“高=1,低=0”。它分两种状态:
| 状态 | 逻辑值 | CAN_H电压 | CAN_L电压 | 差分电压 (Vdiff) |
|---|---|---|---|---|
| 隐性 (Recessive) | 1 | 2.5V | 2.5V | ≈ 0V |
| 显性 (Dominant) | 0 | 3.5V | 1.5V | ≈ 2.0V |
这里有个关键点:显性位会“覆盖”隐性位。如果总线上同时有节点发显性(0)和隐性(1),最终总线呈现的是显性(0)。这就是CAN总线仲裁的物理基础——谁先发0,谁就赢。
避坑指南: 我曾经在一个项目中,用示波器量CAN_H对地波形,发现只有2.5V和3.5V两种电平,就以为信号正常。结果通信就是时断时续。后来才发现,CAN_L的线虚焊了,一直浮空在2.5V。差分接收器收不到正确的差值。记住:一定要同时看CAN_H和CAN_L,或者直接看差分信号。
2.3 终端电阻:为什么是120Ω?
终端电阻,是CAN总线里最容易被人忽略,但又极其重要的元件。它的作用有两个:
- 消除信号反射:高速信号在传输线末端如果遇到阻抗突变,会产生反射,导致波形畸变。120Ω电阻匹配了CAN收发器的输出阻抗和双绞线的特性阻抗(约120Ω),让信号能量被吸收,而不是反射回来。
- 提供隐性电平偏置:当所有节点都处于隐性状态时,CAN_H和CAN_L都是2.5V。这个2.5V的偏置电压,就是由终端电阻网络提供的。
为什么偏偏是120Ω?因为CAN总线使用的双绞线,其特性阻抗标准就是120Ω。你想想看,如果线缆是75Ω的同轴电缆,那终端电阻就得用75Ω。所以,120Ω不是拍脑袋定的,是跟线缆特性阻抗匹配的。
重要提醒: 终端电阻必须安装在总线的最两端。我见过有人把所有节点的终端电阻都焊上了,结果总线上并联了十几个120Ω,等效电阻只有几欧姆,总线直接瘫痪。记住:一条CAN总线,且只有两个终端电阻,分别放在物理距离最远的两个节点上。
2.4 总线拓扑结构:直线型才是王道
CAN总线推荐使用 直线型(总线型)拓扑。所有节点都挂在一条主干线上,每个节点通过尽量短的支线(stub)连接到主干。
为什么不能随便接?
- 星型拓扑:中心节点一旦故障,全网瘫痪。而且信号在星型中心会产生严重的反射。
- 环形拓扑:CAN协议本身不支持环形,信号会绕圈,造成逻辑混乱。
- 树型拓扑:分支过多,阻抗不连续,反射严重,通信速率上不去。
我个人习惯,在设计CAN网络时,会严格遵守“主干一根线,支线尽量短”的原则。支线长度一般建议不超过0.3米。如果实在没办法,支线长了,就得降低通信速率来换取稳定性。
下面这张图,是我自己总结的CAN总线物理层知识结构,帮你理清思路:
2.5 实战中的几个关键参数
最后,我列一个我在项目里常用的参数速查表,方便你调试时参考:
| 参数 | 典型值 | 说明 |
|---|---|---|
| 总线空闲电压 | 2.5V | CAN_H 和 CAN_L 均为 2.5V |
| 显性差分电压 | 1.5V ~ 3.0V | 接收器通常以 0.9V 为阈值 |
| 终端电阻 | 120Ω (1%) | 必须使用高精度电阻 |
| 最大支线长度 | 0.3m (1Mbps时) | 速率越低,支线可以越长 |
| 共模电压范围 | -2V ~ +7V | CAN收发器的承受范围 |
个人经验: 调试CAN总线时,我第一件事就是拿万用表量CAN_H和CAN_L之间的电阻。如果总线断电时量到约60Ω(两个120Ω并联),说明终端电阻安装正确。如果量到120Ω,说明只装了一个。如果量到无穷大,嗯……你懂的,赶紧检查线路吧。