2、CAN物理层:差分信号原理、CAN_H与CAN_L电平、显性电平与隐性电平、总线拓扑结构
好,咱们正式开始聊CAN总线的物理层。
很多人一上来就啃协议栈,什么数据帧、远程帧背得滚瓜烂熟。但我得说一句大实话:物理层搞不明白,你后面所有的工作都是空中楼阁。我在项目里见过太多“软件没问题,硬件死活不通”的案例,最后查出来,全是物理层上的坑。
今天这一章,咱们就把CAN物理层的底裤扒干净。你搞懂了这些,后面看什么协议都通透。
2.1 为什么非得用差分信号?
先问一个问题:汽车发动机旁边,电磁干扰那么强,为什么CAN还能稳定通信?
答案就是——差分信号。
说白了,CAN总线不靠一根线的绝对电压传数据,而是靠两根线(CAN_H和CAN_L)的电压差来传递信息。你想想看,如果外界来个强电磁干扰,两根线上同时被叠加了同样的噪声,那它们的差值是不是基本不变?
对,这就是差分信号的抗干扰精髓。
核心公式:
总线电平 = CAN_H - CAN_L
干扰来了?没关系,只要两根线受到的干扰一致,差值就稳如老狗。
我记得有一次在调试一个车载空调控制器,总线老是莫名其妙丢包。示波器一挂上去,发现CAN_H上有个毛刺,但CAN_L上也有个一模一样的毛刺。嘿,差分信号一减,毛刺消失了。这就是物理层的魅力。
2.2 CAN_H与CAN_L的电平秘密
CAN总线上的电平,不是简单的0和1。它分两种状态:显性电平和隐性电平。
咱们直接看数据:
| 状态 | CAN_H电压 | CAN_L电压 | 差分电压 (CAN_H - CAN_L) | 逻辑值 |
|---|---|---|---|---|
| 隐性电平 | 2.5V | 2.5V | 0V | 逻辑1 |
| 显性电平 | 3.5V | 1.5V | 2V | 逻辑0 |
嗯,这里要注意:显性电平是逻辑0,隐性电平是逻辑1。这个跟咱们平时习惯的“高电平=1”正好相反。我刚入行时也经常搞混,后来养成了一个习惯——脑子里记着“显性=强势=0”。
为什么会这样设计?其实是为了总线仲裁。当多个节点同时发送时,显性电平(0)会覆盖隐性电平(1)。谁先发0,谁就抢到总线控制权。这个咱们后面讲数据链路层时会细聊。
个人经验:
我建议你在调试时,用示波器同时抓CAN_H和CAN_L,然后做数学运算(CH1 - CH2)。看差分波形比看单端波形直观得多。显性位就是2V左右的脉冲,隐性位就是0V。一眼就能看出数据流。
2.3 显性电平与隐性电平的博弈
总线上的节点,其实都在“抢”这根线。
当所有节点都“闭嘴”(不发送)时,总线处于隐性状态,两根线都是2.5V。这时候谁都可以发言。
一旦有节点要发送数据,它就会把CAN_H拉到3.5V,把CAN_L拉到1.5V,制造出2V的差分电压。这就是显性状态。
关键点来了:显性状态会覆盖隐性状态。哪怕只有一个节点在拉显性,总线就是显性的。其他节点如果同时发隐性,它们会发现自己拉不动总线,于是乖乖退出发送,进入接收模式。
我曾经在一个项目中遇到过一个问题:某个节点莫名其妙地一直发显性位,导致整个总线被它“霸占”,其他节点全成了哑巴。查了半天,发现是那个节点的CAN收发器坏了,输出一直卡在显性状态。嗯,这种故障在物理层排查时,用万用表量一下CAN_H和CAN_L的对地电压就能快速定位——如果CAN_H一直3.5V、CAN_L一直1.5V,那肯定有节点在“死占”总线。
避坑指南:
我曾经在产线上遇到过一批产品,上电后总线通信时好时坏。排查到最后,发现是CAN收发器的共模电压范围不够宽。在强干扰环境下,CAN_H和CAN_L的共模电压被拉偏了,导致收发器无法正确识别差分信号。所以选型时,一定要关注收发器的共模输入范围,至少要做到-12V到+12V。
2.4 总线拓扑结构:怎么把节点连起来?
CAN总线的拓扑,说白了就是一条主干线,上面挂一堆节点。
最常见的结构是直线型(总线型)拓扑。所有节点都并联到同一对双绞线上。主干线的两端,必须各接一个120欧姆的终端电阻。
为什么是120欧?因为CAN总线的特性阻抗大约是120欧。终端电阻的作用是吸收信号反射,防止波形畸变。没有终端电阻,或者电阻值不对,总线上的信号就会像回声一样来回弹,导致通信错误。
终端电阻的黄金法则:
- 主干线两端各一个120Ω电阻
- 绝对不能只在中间接一个60Ω的
- 分支线(stub)越短越好,一般不超过0.3米
我见过最离谱的案例,是一个工程师为了省两个电阻,把终端电阻省了。结果总线长度才2米,通信就各种报错。后来加上电阻,问题全消失了。你想想看,省两个几毛钱的电阻,换来几天的排查时间,值不值?
除了直线型,还有星型拓扑和树型拓扑。但我个人建议,能不用就别用。星型拓扑会在中心点产生严重的信号反射,除非你使用CAN中继器或集线器,否则通信质量很难保证。我在一个农业机械项目里被迫用过星型拓扑,结果调试了整整两周才把终端匹配搞定。从那以后,我坚持所有CAN网络都用直线型。
| 拓扑类型 | 优点 | 缺点 | 推荐场景 |
|---|---|---|---|
| 直线型(总线型) | 信号质量好,设计简单 | 布线灵活性差 | 所有场景,首选 |
| 星型 | 布线方便 | 信号反射严重,需特殊处理 | 不推荐,除非有中继器 |
| 树型 | 灵活 | 分支过长会导致信号畸变 | 短距离、低速场景 |
我的布线习惯:
我习惯在PCB设计时,把CAN_H和CAN_L走成差分对,等长、等距、包地。线宽一般10mil,间距20mil。终端电阻放在最远端的两个节点上,而不是放在PCB板中间。这样能最大程度保证信号完整性。
好了,物理层的东西就这些。你掌握了差分信号的原理,记住了显性/隐性的电平值,搞懂了总线拓扑和终端电阻,CAN物理层这块就算拿下了。下一章咱们进入数据链路层,看看数据是怎么在总线上“跑”起来的。