2、CAN物理层:差分信号原理、CAN_H与CAN_L电平定义、终端电阻的作用、总线拓扑结构
好,咱们正式开始啃CAN总线的物理层。很多刚入行的工程师觉得物理层就是一堆枯燥的电平定义,没什么好学的。我当年也这么想,直到有一次在实验室里,一辆车的CAN总线怎么都通不了,示波器一挂上去全是毛刺……折腾了两天才发现是终端电阻焊错了位置。从那以后,我再也不敢小看物理层了。
说白了,物理层就是CAN通信的“地基”。地基不稳,上层协议栈写得再漂亮也是白搭。今天咱们就把差分信号、电平定义、终端电阻和拓扑结构这四块硬骨头,一块一块啃干净。
2.1 为什么CAN要用差分信号?
汽车环境有多恶劣,你想想看:发动机点火时电磁干扰满天飞,雨刷电机、车窗电机一启动,电源线上全是毛刺。传统的单端信号(比如UART的TX/RX对GND),在这种环境下很容易被干扰吞掉。
CAN的解决方案很巧妙——用两根线传一个信号。这两根线分别叫CAN_H和CAN_L。发送端把逻辑“1”和“0”转换成两根线上的电压差;接收端只关心两根线之间的电压差,不关心它们各自对地的绝对电压。
为什么会这样?因为干扰通常是共模的——它同时作用在CAN_H和CAN_L上,两根线上的电压一起抬升或一起下降。但它们的差值基本不变。这就好比两个人站在晃动的船上,虽然船在上下颠簸,但他俩的相对高度差没变。
核心结论:差分信号天然免疫共模干扰。CAN总线能在-2V到+7V的共模电压范围内正常工作,这在汽车电瓶电压波动、接地偏移时特别管用。
我在项目中遇到过一辆新能源车,电机控制器一启动CAN就丢帧。查了半天,发现是CAN_H和CAN_L的绞距不均匀,导致两根线受到的干扰不一样。嗯,这里要注意:差分信号的优势依赖于两根线走线对称、紧密绞合。PCB上如果CAN_H和CAN_L走线距离拉得太开,或者用了不同长度的过孔,共模抑制能力就会大打折扣。
2.2 CAN_H与CAN_L的电平定义
CAN总线定义了两种逻辑状态:显性(Dominant)和隐性(Recessive)。这个命名很有意思——当多个节点同时发送时,显性位会“覆盖”隐性位。这就是CAN总线仲裁的物理基础。
咱们直接看电平值,我习惯用这张表来记:
| 状态 | CAN_H电压 | CAN_L电压 | 差分电压 (CAN_H - CAN_L) |
|---|---|---|---|
| 隐性(逻辑1) | 2.5V | 2.5V | ≈ 0V |
| 显性(逻辑0) | 3.5V | 1.5V | ≈ 2V |
你看,隐性时两根线都是2.5V,差分电压接近0V。显性时CAN_H被拉到3.5V,CAN_L被拉到1.5V,差分电压约2V。接收端的比较器就是靠检测这个差分电压是否超过某个阈值(通常是0.7V~0.9V)来判断总线状态的。
小技巧:用示波器看CAN总线时,我习惯把CH1接CAN_H,CH2接CAN_L,然后用数学通道做CH1-CH2。这样一眼就能看出差分信号的质量——幅值够不够2V、边沿陡不陡、有没有振铃。
这里有个容易踩的坑:CAN收发器的输出级是开漏结构。显性位由收发器主动驱动,隐性位则是靠总线上的偏置电阻把两根线拉到2.5V。所以当总线空闲时,你量到的就是2.5V的隐性电平。如果所有节点都休眠了,总线电压可能会漂移——我曾经遇到过这种情况,一个节点休眠后它的收发器把CAN_H拉到0V,导致整个总线通信瘫痪。
警告:千万不要用万用表电阻档去量CAN_H和CAN_L之间的电阻!万用表输出的电流可能会让收发器误判总线状态,严重时甚至会损坏收发器。测量终端电阻请断电后用电阻档,或者用示波器看波形。
2.3 终端电阻的作用
终端电阻,就是挂在CAN总线两端的120Ω电阻。很多初学者不理解:为什么非要加这个电阻?不加行不行?
我直接说结论:不加终端电阻,高速CAN(>125kbps)基本没法用。
原因有两个:
- 消除信号反射。 CAN总线的通信频率不低(经典CAN最高1Mbps),信号在总线上的波长和总线长度可比。如果总线末端不匹配,信号就会反射回来,和原始信号叠加,造成过冲、下冲和振铃。你想想看,接收端本来要判断一个显性位,结果反射波让差分电压掉到了阈值以下——误码就来了。
- 提供隐性电平偏置。 终端电阻和收发器内部的偏置电路配合,把总线空闲时的电压稳定在2.5V。没有终端电阻,总线电压会飘忽不定。
为什么是120Ω?这是由CAN总线的特性阻抗决定的。标准双绞线的特性阻抗大约在120Ω左右。用120Ω的电阻做终端匹配,就是为了让负载阻抗等于传输线的特性阻抗,从而消除反射。
关键点:终端电阻必须且只能加在总线的最两端。如果加在中间,反射照样存在。如果只加一端,另一端照样反射。如果加了三个……嗯,总等效电阻就变成80Ω了,收发器驱动能力可能不够。
我踩过的一个坑:有一块开发板,板载了120Ω终端电阻,但没加跳线或开关。我把这块板子接到一个已经有终端电阻的CAN网络里,结果等效电阻变成了60Ω。显性位的差分电压从2V掉到了1.2V左右,虽然还能通信,但噪声容限大幅降低。后来在产线上批量测试时,有5%的板子在强干扰下会丢帧。排查了三天才找到原因。
建议:设计CAN节点时,终端电阻一定要用跳线或拨码开关控制。调试阶段可以灵活选择是否接入。量产时根据网络拓扑决定——只有总线两端的节点才焊上电阻。
2.4 总线拓扑结构
CAN总线要求使用直线型(总线型)拓扑。说白了就是一根主干线,所有节点都挂在这根线上,用尽量短的支线(stub)连接。
为什么不能用星型或树型?因为分支会产生阻抗不连续点,信号会在分支处反射。分支越长、分支越多,反射越严重。
我画了一张图,把CAN总线的拓扑结构和关键参数标出来了:
这张图里我标了几个关键参数:
- 主干线:就是CAN_H和CAN_L两根双绞线,贯穿整个网络。
- 支线(stub):从主干线分叉到节点的连接线。在1Mbps速率下,支线长度不要超过0.3米。速率越低,支线可以越长——比如125kbps时支线可以到几米。
- 节点间距:没有严格限制,但总线的物理长度受速率限制。1Mbps时总线最长约40米,125kbps时可以到500米。
避坑指南:我曾经在一个项目中看到工程师用T型连接器做CAN总线分叉,结果每个分叉点都产生了一个阻抗不连续点。三个分叉点下来,波形已经没法看了。正确的做法是用菊花链(daisy-chain)方式——每个节点有两个DB9或RJ45接口,一进一出,保证主干线是连续的。
说到拓扑,还有一个容易忽略的点:电源和地线。CAN收发器需要稳定的5V或3.3V供电,而且节点之间的地电位差不能太大。如果两个节点相距很远,地线上有压降,就会抬高共模电压。当共模电压超过收发器的承受范围(通常是-2V~+7V),通信就会出错。我建议在长距离CAN网络中,使用隔离式CAN收发器(比如ISO1050),把节点之间的电气隔离开。
2.5 小结:物理层决定了CAN能跑多远、多快、多稳
咱们把这一章的核心点串一下:
- 差分信号让CAN在汽车这种强干扰环境中依然可靠——共模干扰被抵消,信号只看差值。
- CAN_H和CAN_L的电平定义了显性(0)和隐性(1)两种状态,显性位覆盖隐性位是仲裁的基础。
- 终端电阻必须加在总线两端,120Ω,消除反射并提供偏置。少一个、多一个、位置不对都会出问题。
- 总线型拓扑是CAN的唯一选择,支线要短,主干要连续,节点要菊花链。
这些物理层的细节,你在数据手册上都能找到,但真正用起来的时候,每一个参数背后都有坑。我做了十几年嵌入式,CAN物理层的问题至少占了我调试时间的30%。把这一章吃透了,后面学CAN协议帧、仲裁、位时序的时候,你会觉得顺很多。