2. CAN总线物理层:差分信号原理、CAN_H与CAN_L电平定义、总线拓扑结构(直线型与星型)、终端电阻的作用与选型
各位同学,咱们今天聊聊CAN总线的物理层。说实话,很多做嵌入式开发的朋友,一上来就扎进协议栈里,反而把最底层的物理层给忽略了。我个人觉得,物理层就像房子的地基——你上层协议写得再漂亮,物理层没搞对,通信照样一塌糊涂。我在项目里见过太多这种案例了,今天咱们就把这块掰开揉碎了讲清楚。
2.1 差分信号原理:为什么CAN要用两根线?
先问大家一个问题:为什么CAN总线要用两根线(CAN_H和CAN_L),而不是像UART那样一根TX一根RX?
答案很简单——抗干扰。你想想看,工业现场电机一启动、变频器一工作,那电磁环境简直是个大熔炉。单端信号在这种环境下,分分钟被干扰得面目全非。
差分信号的核心思想是:用两根线上的电压差来表示逻辑状态。具体来说:
- 显性电平(Dominant):CAN_H比CAN_L高,电压差约2V。此时总线被拉低,逻辑上代表"0"。
- 隐性电平(Recessive):CAN_H和CAN_L电压相等,电压差接近0V。逻辑上代表"1"。
为什么差分能抗干扰?因为干扰信号通常是共模的——它同时作用在两根线上。你想想看,如果外界来了一个电磁脉冲,CAN_H和CAN_L同时被抬高了1V,但它们的差值基本不变。接收器只看差值,所以干扰就被抵消了。
关键点:差分信号的本质是"用差值说话"。共模干扰再大,只要差值不变,数据就不会错。
我记得有一次在现场调试,客户说他们的CAN通信时不时丢包。我拿示波器一看,CAN_H和CAN_L的波形都在跳,但差分信号非常干净。最后发现是地线没接好,导致共模电压漂移。嗯,这里要注意——差分信号虽然抗共模干扰,但共模电压范围是有极限的,一般CAN收发器能承受-12V到+12V,超出这个范围就挂了。
2.2 CAN_H与CAN_L电平定义
咱们把电平定义说得再细一点。标准CAN总线(ISO 11898-2)定义了两种电平状态:
| 状态 | CAN_H电压 | CAN_L电压 | 差分电压 (CAN_H - CAN_L) | 逻辑值 |
|---|---|---|---|---|
| 隐性(Recessive) | 2.5V | 2.5V | 0V | 1 |
| 显性(Dominant) | 3.5V | 1.5V | 2V | 0 |
说白了,总线空闲时两根线都是2.5V。当某个节点要发送数据时,它把CAN_H拉到3.5V,把CAN_L拉到1.5V,产生2V的压差。这个压差就是"显性位"。
这里有个有意思的机制:显性位会覆盖隐性位。如果两个节点同时发送,一个发显性(0),一个发隐性(1),总线最终呈现显性(0)。这就是CAN总线仲裁的基础——谁先发0,谁就赢了。
实战技巧:用示波器看CAN总线时,我习惯把CH1接CAN_H,CH2接CAN_L,然后用数学通道做CH1-CH2。这样一眼就能看出差分信号的质量。如果差分信号的上升沿或下降沿有毛刺,多半是终端电阻匹配有问题。
2.3 总线拓扑结构:直线型 vs 星型
CAN总线的拓扑结构,说白了就是节点怎么连在一起。最常见的两种是直线型和星型。
2.3.1 直线型(总线型)
这是CAN总线的标准拓扑。所有节点都挂在一根主干线上,每个节点用很短的支线(stub)连接上去。
直线型的优点很明显:结构简单,信号反射最小。我建议在大多数项目里优先用这种拓扑。支线长度一般不要超过0.3米,如果节点多,支线长了会引起信号反射。
2.3.2 星型拓扑
星型拓扑就是所有节点都连到一个中心集线器上。这种结构在工业现场偶尔会见到,但我个人不太推荐。
星型拓扑最大的问题是信号反射。因为从集线器到每个节点的距离不一样,信号到达各节点的时间不同,反射波会叠加在原始信号上。我曾经在一个项目里被迫用了星型拓扑(现场布线限制),结果通信速率只能降到50kbps才能稳定工作。如果你非要用星型,我建议在集线器处做特殊处理,比如加中继器或使用CAN-FD的灵活数据率功能。
避坑指南:我曾经见过一个团队,把CAN总线接成了环形拓扑。结果整个网络像振荡器一样不停自激,数据完全没法看。记住——CAN总线不支持环形拓扑,也不支持T型分支过多。直线型是最安全的选择。
2.4 终端电阻的作用与选型
终端电阻是CAN总线里最容易被人忽视,但又最关键的东西。说白了,它的作用就两个:
- 消除信号反射:当信号在总线末端遇到阻抗突变时,会产生反射波。终端电阻把末端阻抗匹配到传输线的特性阻抗,让信号被吸收而不是反射回来。
- 提供偏置电压:在隐性状态时,终端电阻把CAN_H和CAN_L都拉到2.5V,保证总线处于确定状态。
2.4.1 为什么是120Ω?
标准CAN总线的特性阻抗大约是120Ω。所以终端电阻也选120Ω,这样阻抗匹配,反射最小。两个120Ω电阻并联在总线上,等效电阻是60Ω——这就是你在总线上测到的直流电阻。
我教你一个快速判断终端电阻是否正常的方法:用万用表测CAN_H和CAN_L之间的电阻。如果总线断电且所有节点都断开,你应该测到60Ω(两个120Ω并联)。如果只测到一个120Ω,说明有一端的终端电阻没接。如果测到开路,说明两端都没接。
2.4.2 选型要点
| 参数 | 推荐值 | 说明 |
|---|---|---|
| 阻值 | 120Ω ±1% | 精度要高,否则匹配不好 |
| 功率 | 0.25W 或 0.5W | 一般应用足够,高电压环境需计算 |
| 封装 | 0805 或 1206 | 贴片常用,插件可选 |
| 温度系数 | ±100ppm/°C | 工业环境建议用更低的 |
我的习惯:在样机阶段,我通常用可调电阻先调到120Ω,用示波器看信号质量。确认没问题后,再换成固定电阻。另外,如果总线长度超过100米,或者节点数超过30个,我建议用0.5W的电阻,防止长时间工作发热。
2.4.3 常见错误
嗯,这里要重点说一下。我见过太多人犯这些错误:
- 只在总线一端接终端电阻:这样反射只消除了一半,信号质量依然很差。
- 每个节点都接终端电阻:多个电阻并联后等效阻值远小于60Ω,总线驱动能力下降,通信距离缩短。
- 用普通电阻代替:普通电阻的寄生电感大,高频特性差。建议用贴片电阻或金属膜电阻。
核心原则:CAN总线两端各接一个120Ω电阻,且只能接在两端。中间节点不要接终端电阻。这是铁律,别问我为什么——我吃过亏。
好了,物理层的内容就这些。记住一句话:物理层搞好了,CAN通信就成功了一半。下一节咱们聊数据链路层,到时候会讲到帧格式和仲裁机制,那才是CAN总线的精髓所在。