3、CAN总线物理层:CAN总线电平标准(高速CAN、低速CAN)、CAN总线拓扑结构、终端电阻的作用与计算
各位工程师朋友,咱们今天聊聊CAN总线的物理层。说实话,很多做嵌入式开发的朋友,对CAN协议栈背得滚瓜烂熟,但一碰到物理层的问题就抓瞎。我见过不少项目,软件调得妥妥的,结果上车一跑,通讯就是不稳定。最后查出来,要么是终端电阻没算对,要么是拓扑结构走成了“菊花链”的变种。嗯,物理层这东西,看着基础,但坑是真不少。
3.1 CAN总线电平标准:高速CAN与低速CAN
CAN总线用差分信号传输,说白了就是靠两根线(CAN_H和CAN_L)的电压差来传递“0”和“1”。但不同标准下,这个电压差的范围是不一样的。
3.1.1 高速CAN(ISO 11898-2)
高速CAN是目前最主流的方案,速率能跑到1Mbps。它的电平定义很清晰:
- 显性电平(逻辑0):CAN_H比CAN_L高2V左右。典型值是CAN_H=3.5V,CAN_L=1.5V,差分电压约2V。
- 隐性电平(逻辑1):CAN_H和CAN_L都维持在2.5V左右,差分电压接近0V。
我个人的习惯是,在设计高速CAN节点时,一定用示波器去量一下CAN_H和CAN_L的共模电压。为什么?因为很多收发器对共模电压有要求,一旦偏离了2.5V,通讯就容易出问题。我曾经在一个项目中,因为地线回路处理不当,导致共模电压漂到了3V以上,结果总线上的节点时不时就掉线。排查了整整两天,最后发现是接地的问题。
关键点:高速CAN的隐性电平是2.5V,显性电平是CAN_H=3.5V、CAN_L=1.5V。差分电压2V是标准值。
3.1.2 低速CAN(ISO 11898-3)
低速CAN也叫容错CAN,速率一般不超过125kbps。它的电平标准和高速CAN不太一样:
- 显性电平(逻辑0):CAN_H拉到接近电源电压(比如5V),CAN_L拉到接近GND(比如0V)。差分电压很大。
- 隐性电平(逻辑1):CAN_H和CAN_L都拉到一个中间偏上的电压(比如2.5V或更高)。
你想想看,低速CAN为什么叫“容错”?因为它允许其中一根线短路到电源或地,总线还能继续工作。这在一些对可靠性要求极高的场合(比如车身控制)很有用。但代价就是速率上不去。
我的建议:如果你的系统对速率要求不高(比如门窗、灯光控制),而且希望有更强的抗故障能力,可以考虑低速CAN。但如果你要做动力总成或ADAS,老老实实用高速CAN。
3.2 CAN总线拓扑结构
CAN总线的拓扑结构,说白了就是节点怎么连到总线上。标准推荐的是直线型(总线型)拓扑。
3.2.1 标准总线型拓扑
所有节点都挂在一根主干线上,每个节点通过一个短的分支(stub)连接到主干。主干的两端各接一个120Ω的终端电阻。
我记得有一次,一个客户问我:“我的CAN总线为什么在高速下老是丢包?”我让他画了一下拓扑图,结果发现他把节点接成了星型。嗯,这就是典型的问题。CAN总线对信号反射非常敏感,星型拓扑会产生严重的信号反射,导致通讯失败。
避坑指南:千万不要用星型拓扑!我曾经见过一个项目,为了布线方便,把CAN节点接成了星型,结果总线速率只能降到50kbps才能工作。后来改成总线型,直接跑到了500kbps。
3.2.2 分支长度限制
分支(stub)的长度是有严格限制的。一般来说:
- 速率在1Mbps时,分支长度不能超过0.3米。
- 速率在500kbps时,分支长度不能超过1米。
- 速率在125kbps时,分支长度可以放宽到几米。
为什么会这样?因为分支相当于一个“短截线”,会产生信号反射。分支越长,反射越严重。我个人的经验是,哪怕速率不高,也尽量把分支控制在1米以内。这样以后升级速率时不用改硬件。
3.3 终端电阻的作用与计算
终端电阻是CAN总线物理层最容易被忽视,但又最关键的部分。它的作用有两个:
- 消除信号反射:在总线两端提供阻抗匹配,防止信号在末端反射回来干扰正常通讯。
- 提供显性电平的回路:在显性状态时,电流通过终端电阻形成回路,产生差分电压。
3.3.1 为什么是120Ω?
CAN总线的特性阻抗大约是120Ω。所以终端电阻也选120Ω,这样阻抗匹配,信号反射最小。你想想看,如果阻抗不匹配,信号到了末端就像撞到一堵墙,反弹回来,把原来的信号搅得乱七八糟。
我记得有一次,一个项目里CAN总线通讯时好时坏。我拿示波器一量,发现信号波形上有明显的“振铃”。一查,终端电阻用的是100Ω。换成120Ω后,波形立刻干净了。
关键公式:终端电阻R = 总线特性阻抗Z0。对于标准CAN总线,Z0 ≈ 120Ω,所以R = 120Ω。
3.3.2 终端电阻的计算
如果你用的是非标准线缆,或者总线长度特别长,可能需要重新计算终端电阻。计算方法如下:
1. 测量线缆的特性阻抗Z0(可以用TDR时域反射计测量)。
2. 终端电阻R = Z0。
3. 如果总线两端都接电阻,每个电阻的阻值就是Z0。
4. 如果只在一端接电阻(不推荐),阻值应为Z0/2。
但说实话,绝大多数情况下,直接用两个120Ω电阻就对了。我做了这么多年项目,99%的CAN总线都是用120Ω终端电阻。只有极少数特殊场合(比如长距离低速通讯)才需要调整。
3.3.3 终端电阻的放置位置
终端电阻必须放在总线的物理两端。不是任意两个节点,而是线缆的两个端点。很多新手会犯一个错误:把终端电阻放在节点内部,然后节点随便插到总线上。这样如果节点不在端点,终端电阻就没起到作用。
重要提醒:我曾经在一个项目中,发现总线上的终端电阻被放在了中间两个节点上,结果两端没有电阻。通讯距离一长,波形就严重畸变。后来把电阻移到两端,问题解决。记住:终端电阻的位置和节点位置无关,只和线缆的物理端点有关。
3.4 实际设计中的注意事项
最后,我总结几个实际设计中的要点:
- 共模扼流圈:在CAN_H和CAN_L上串一个共模扼流圈,可以有效抑制共模干扰。我习惯在每一个节点上都加。
- ESD保护:CAN总线是暴露在车外的,一定要加ESD保护器件。我推荐用TVS管,钳位电压选在36V左右。
- 线缆选择:尽量用双绞线,绞距越密越好。这样可以减少电磁辐射和外部干扰。
- 节点数量:标准CAN总线最多支持110个节点(取决于收发器驱动能力)。但实际项目中,我建议不要超过30个,否则总线负载太重,通讯延迟会变大。
好了,关于CAN总线物理层的内容就讲到这里。下一章我们会深入CAN数据链路层,聊聊帧格式和位时序。到时候我会分享一些我在调试CAN总线时遇到的“玄学”问题,保证让你大开眼界。