第2章 物理层基础:差分信号、电平逻辑与终端电阻

CAN总线的物理层,说白了就是信号怎么在线上跑的问题。很多初学者一上来就扎进协议栈,结果板子调不通,回头才发现是物理层没搞对。我刚开始做CAN项目时也吃过这个亏——两根线接反了,查了整整两天。

这一章我们就把物理层的几个核心概念掰开揉碎讲清楚。你搞懂了这些,后面再遇到总线通信问题,至少知道从哪里下手排查。

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

先问一个问题:为什么CAN不直接用单端信号(比如UART那种TX/RX对地传输)?

原因很简单——工业现场太吵了。电机启停、变频器开关、继电器吸合,这些都会在线上感应出很强的共模噪声。单端信号只有一根信号线加一个地,噪声叠加在信号上,接收端根本分不清哪个是信号哪个是干扰。

差分信号就不一样。它用两根线(CAN_H和CAN_L)来传输,接收端只看两根线之间的电压差。噪声同时耦合到两根线上,一减就没了。这就是所谓的共模抑制。

核心优势:

  • 抗共模干扰能力强,适合长距离(最远可达1km)
  • 电磁辐射小,两根线辐射互相抵消
  • 不需要公共地参考,节点间可以存在一定电位差

我记得有一次在工厂调试,现场变频器一启动,RS-485直接乱码,CAN总线纹丝不动。这就是差分信号的价值。

2.2 CAN_H和CAN_L的电平逻辑

CAN总线上只有两种状态:显性和隐性。这两个词你后面会反复见到,先记住它们的电平关系。

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

隐性状态时,两根线都是2.5V,差分电压接近0。显性状态时,CAN_H拉到3.5V,CAN_L拉到1.5V,差分电压约2V。

这里有个关键点:显性会覆盖隐性。也就是说,只要有一个节点输出显性,总线就是显性。这就是CAN总线仲裁的基础——谁先发0(显性),谁就赢得总线控制权。

避坑指南:

我曾经遇到过一个问题:用示波器量CAN_H和CAN_L对地波形都正常,但就是通信不上。后来发现是CAN收发器的共模电压范围超了。CAN收发器允许的共模电压一般是-2V到+7V,如果两个节点地电位差太大,超出这个范围,即使差分信号正确也收不到。所以长距离通信时,建议加隔离。

2.3 显性电平与隐性电平的物理实现

收发器内部是怎么产生这两种电平的?我画个简化的示意图你就明白了。

CAN收发器输出级简化原理 VCC (5V/3.3V) GND S1 S2 CAN_H VCC (5V/3.3V) GND S3 S4 CAN_L 隐性状态 S1/S3断开 S2/S4闭合 CAN_H=CAN_L=2.5V 显性状态 S1/S3闭合 S2/S4断开 CAN_H=3.5V, CAN_L=1.5V

收发器内部其实就是一组开关。隐性时,CAN_H和CAN_L都通过电阻接到2.5V(由分压电阻产生)。显性时,CAN_H直接拉到VCC,CAN_L拉到GND。

你想想看,如果两个节点同时发显性,总线电压会怎样?答案是:CAN_H被拉到最高,CAN_L被拉到最低,差分电压最大。这就是显性覆盖隐性的物理基础。

2.4 总线终端电阻的作用

这是CAN物理层最容易出错的地方。终端电阻,说白了就是接在总线两端的120Ω电阻。

为什么要加这个电阻?两个原因:

  1. 阻抗匹配,消除信号反射——信号在线上传输,遇到阻抗突变就会反射。反射回来的信号叠加在原信号上,会造成波形畸变,导致误码。
  2. 提供隐性电平的偏置——没有终端电阻时,总线处于高阻态,容易受干扰。终端电阻把CAN_H和CAN_L之间的阻抗拉低,让隐性电平稳定在2.5V。

重要:

终端电阻必须且只能加在总线的最两端。中间节点不要加。如果加多了,等效电阻变小,差分信号幅度不够,通信距离会缩短。如果加少了(比如只加一端),信号反射严重,总线长度稍长就会出错。

标准CAN总线要求两端各一个120Ω电阻,并联后等效60Ω。这就是你用万用表量CAN_H和CAN_L之间应该是60Ω的原因。

我遇到过最典型的故障:一个工程师在调试时发现总线通信时好时坏,用示波器看波形有严重的过冲和振铃。查了半天,发现终端电阻加在了中间两个节点上,总线两端反而没有。把电阻挪到两端后,波形干净得像教科书一样。

2.5 总线拓扑与节点连接

CAN总线推荐的是直线型拓扑,也叫总线型。所有节点都挂在同一条主干线上,每个节点用尽量短的支线接入。

参数 推荐值 说明
最大节点数 110个(标准) 受收发器驱动能力限制
最大总线长度 1km(5kbps时) 速率越低,距离越远
支线最大长度 0.3m(1Mbps时) 高速时支线必须极短
终端电阻 120Ω × 2 两端各一个

为什么支线要短?因为支线相当于一个短截线,会产生反射。速率越高,对反射越敏感。1Mbps时,支线超过30cm就可能出问题。我个人习惯是能不用支线就不用,直接把节点做在主线上。

经验之谈:

如果你在实验室调试,用杜邦线搭CAN总线,注意线不要太长。我见过有人用20cm的杜邦线做支线,1Mbps下怎么都调不通。换成双绞线直接焊上去,问题立刻解决。

2.6 常见物理层故障排查

最后分享几个我实际项目中遇到的CAN物理层故障,你以后大概率也会碰到:

  • CAN_H和CAN_L接反——所有节点都收不到数据。用万用表量差分电压,正常时显性约2V,接反了变成-2V。
  • 终端电阻缺失或位置不对——波形有过冲/振铃,总线长度稍长就丢帧。用示波器看CAN_H对GND波形,正常是方波,有反射时会出现台阶或振荡。
  • 共模电压超限——两个节点地电位差太大,收发器进入保护状态。用万用表量两个节点GND之间的电压,超过1V就要小心了。
  • 总线短路——CAN_H对地短路、CAN_L对地短路、或者两根线短路。用万用表量CAN_H和CAN_L对GND的电阻,正常应该是2.5V偏置电压通过电阻分压后的值。

嗯,物理层就这些。说白了就是两根线、两个电阻、一个差分信号。但就是这看似简单的东西,搞不好能让整个项目卡壳。你把这些基础打牢了,后面学协议帧、仲裁、错误处理的时候,会轻松很多。