第2章 CAN物理层:信号是怎么在总线上跑的

做CAN总线开发,很多人一上来就怼着软件配置、报文格式猛啃。但我个人习惯,先搞懂物理层。为什么?因为车上70%以上的通信故障,根源都在物理层——线断了、电平不对、终端电阻掉了。你软件写得再漂亮,物理层不给力,一切都是白搭。

这一章,咱们就把CAN物理层的底裤扒干净。差分信号怎么传、CAN_H和CAN_L到底多少伏、显性隐性啥意思、那个120欧的电阻到底干嘛用——一个一个说清楚。

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

车上的电磁环境有多恶劣,做过实车测试的兄弟都懂。发动机点火、电机驱动、继电器通断,随便一个动作都能在线上感应出几伏甚至几十伏的噪声。单端信号(比如UART的TX/RX对GND)在这种环境里,基本就是裸奔。

CAN用的是差分信号传输。说白了,就是一对绞在一起的线——CAN_H和CAN_L,信号不依赖GND,而是靠两根线之间的电压差来传递信息。

核心优势:

  • 共模抑制:外界噪声同时耦合到CAN_H和CAN_L上,差值不变,信号不受影响
  • 抗干扰强:绞线进一步抵消电磁辐射,我见过在变频器旁边跑CAN,照样稳如老狗
  • 故障容错:一根线断了或对地短路,另一根还能维持通信(当然,得看具体故障模式)

你想想看,如果车上每个ECU都用单端信号,那地环路、共模噪声这些问题够你喝一壶的。差分信号,就是汽车电子工程师的护身符。

2.2 CAN_H与CAN_L的电平定义

CAN总线在静默状态(没有节点发送数据)时,CAN_H和CAN_L都维持在2.5V左右。这个电压叫隐性电平。当有节点开始发送数据时,CAN_H被拉高到3.5V,CAN_L被拉低到1.5V,两根线之间产生2V的压差——这就是显性电平。

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

这里有个容易搞混的点:隐性对应逻辑1,显性对应逻辑0。为什么这么设计?因为CAN总线是“线与”机制——多个节点同时发送时,只要有一个节点输出显性(0),总线就被拉成显性。这正好对应了总线仲裁的优先级逻辑:ID小的节点(显性位更多)优先级更高。

避坑指南:我曾经在项目里遇到过,用示波器量CAN_H和CAN_L对GND的波形,发现两根线都在2.5V附近抖动,但差分电压始终接近0V。查了半天,原来是收发器的共模电压出了问题。记住:看差分,别只看单端。

2.3 显性电平与隐性电平的博弈

显性和隐性,不是简单的“高电平”和“低电平”。它们是总线访问权的体现。

  • 隐性电平:总线空闲,或者节点发送逻辑1。此时总线处于“弱上拉”状态,任何节点都可以把它拉成显性。
  • 显性电平:节点主动驱动总线,产生2V差分电压。显性会覆盖隐性——这就是仲裁的基础。

我画个图帮你理解:

CAN总线显性/隐性电平示意图 2.5V (隐性) 显性区域 CAN_H CAN_L 差分电压 ≈ 2V 说明: • 隐性状态:CAN_H = CAN_L = 2.5V,差分电压 = 0V,对应逻辑1 • 显性状态:CAN_H = 3.5V,CAN_L = 1.5V,差分电压 = 2V,对应逻辑0 • 显性会覆盖隐性,多个节点同时发送时,总线呈现显性

从图上你能看到,显性状态时CAN_H和CAN_L像一对“翅膀”一样张开,差分电压达到2V。隐性状态时它们合拢在2.5V。收发器就是靠检测这个差分电压来识别总线状态的。

2.4 总线终端电阻:为什么是120Ω?

终端电阻,是CAN总线物理层里最容易被忽视、但又最关键的东西。没有它,你的CAN总线根本跑不起来。

为什么需要终端电阻?两个原因:

  1. 消除信号反射:CAN总线是传输线,信号在末端如果不匹配阻抗,就会反射回来,和原始信号叠加,造成波形畸变。120Ω匹配了电缆的特性阻抗(约120Ω),让信号“有去无回”。
  2. 提供差分负载:显性状态时,收发器需要驱动电流流过CAN_H和CAN_L之间的负载。终端电阻就是那个负载。没有它,显性电平拉不出来。

注意:终端电阻必须且只能安装在总线的两端。中间节点不要加!我见过有人每个节点都焊了个120Ω,结果总线负载太重,显性电平都拉不到3.5V,通信直接挂掉。

标准CAN总线(ISO 11898-2)要求:

  • 终端电阻:120Ω ± 1%
  • 功率:至少1/4W(实际推荐1/2W以上,特别是长距离总线)
  • 位置:总线最远的两端

为什么是120Ω,不是50Ω、100Ω?因为CAN总线用的双绞线特性阻抗大约就是120Ω。你拿50Ω的同轴电缆来跑CAN,反射照样严重。所以,线缆类型和终端电阻要匹配。

2.5 终端电阻的匹配与测量

在实际项目中,怎么确认终端电阻装对了?我教你一个土办法:

测量步骤:

  1. 断开所有节点的电源(重要!带电测会不准)
  2. 用万用表电阻档,测量CAN_H和CAN_L之间的电阻
  3. 正常值应该在60Ω左右(两个120Ω并联)
  4. 如果测到120Ω:只有一端有电阻,另一端掉了
  5. 如果测到40Ω:有三个或更多终端电阻并联
  6. 如果测到无穷大:两端电阻都掉了

我曾经在一个售后故障排查中,客户说CAN通信时好时坏。我远程指导他用万用表一量,CAN_H和CAN_L之间电阻在120Ω到无穷大之间跳变——原来是总线一端的终端电阻虚焊了,振动时接触不良。重新焊好,问题解决。

这里有个细节:测量时万用表显示的60Ω是直流电阻,而终端电阻在高速信号下呈现的是交流阻抗。但直流测量已经能判断大部分问题了。

2.6 物理层常见故障与排查

搞CAN这么多年,我把物理层故障归纳为三类:

故障类型 现象 排查方法
终端电阻缺失 通信不稳定,波形过冲/振铃 万用表测CAN_H-CAN_L电阻,应为60Ω
CAN_H/CAN_L短路 总线一直显性或一直隐性,无法通信 万用表测CAN_H-CAN_L电阻,接近0Ω
共模电压偏移 差分电压正常但节点收不到数据 示波器测CAN_H/CAN_L对GND,看共模是否在2.5V附近

经验之谈:车上最常见的物理层故障,不是芯片烧了,而是连接器松动、端子氧化、线束折断。所以排查时,先动动插头、晃晃线束,往往比拿示波器瞎戳管用。

嗯,物理层的东西就这些。看似简单,但每一个细节都关系到总线能不能稳定工作。下一层咱们要聊数据链路层了——帧格式、仲裁、错误检测,那才是CAN协议的精髓所在。