3. CAN总线协议详解(上):物理层那些事儿

各位好,欢迎来到CAN总线详解的上半部分。今天咱们不聊那些虚的,直接扎进CAN总线的物理层。说实话,搞车载这么多年,我见过太多工程师在软件层面调得飞起,结果一上实车,通讯就是不稳定。最后查出来,往往是物理层的基础没打牢。

物理层,说白了就是信号怎么在线上跑、怎么保证不出错。你想想看,车里环境那么恶劣,发动机点火、电机啸叫、各种电磁干扰,如果物理层设计得不够皮实,上层协议再牛也白搭。

3.1 差分信号:CAN总线的“防弹衣”

CAN总线为什么能在车里活得好好的?核心秘密就是差分信号。

传统的单端信号,比如UART,一根信号线对地传数据。干扰一来,电平就跳,数据就错。CAN不一样,它用两根线——CAN_H 和 CAN_L——来传一个信号。

怎么传的呢?

  • 发送端把原始信号分成两个互补的信号:一个正相,一个反相。
  • 接收端只看两根线的电压差,不看它们各自对地的绝对值。

举个例子:

  • 如果CAN_H是3.5V,CAN_L是1.5V,差值是2V,这叫显性电平(逻辑0)。
  • 如果CAN_H是2.5V,CAN_L也是2.5V,差值是0V,这叫隐性电平(逻辑1)。

核心优势: 外部干扰(比如发动机点火噪声)会同时耦合到CAN_H和CAN_L上,两根线的电压一起升高或降低。但它们的差值基本不变。这就是共模抑制,CAN总线抗干扰的底气所在。

我记得有一次在台架上测试,旁边就是大功率电机启动,示波器上CAN_H和CAN_L的波形都在剧烈抖动,但差分波形稳得像条直线。那一刻,我是真心佩服博世当年这帮人的设计。

3.2 总线电平与逻辑状态

刚才提到了显性和隐性,咱们展开说说。

CAN总线只有两种逻辑状态:

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

这里有个关键点:显性电平会“覆盖”隐性电平。什么意思呢?如果总线上有多个节点同时发送,只要有一个节点发送显性(0),总线就是显性。这就是CAN总线仲裁机制的基础——谁先发0,谁就赢。

避坑指南: 我曾经遇到过一个项目,样车跑着跑着CAN通讯就中断了。查了三天,最后发现是某个节点的CAN收发器供电电压偏低,导致它发出的隐性电平只有2.3V,而其他节点是2.5V。虽然差值不大,但接收端的比较器阈值被打破了,误判频发。所以,电源质量直接影响CAN通讯的稳定性,别忽视。

3.3 终端电阻:为什么必须加?

很多刚入行的朋友问我:CAN总线两端为什么要各接一个120Ω的电阻?不接行不行?

答案是:不接,大概率会出问题。

终端电阻的作用有两个:

  1. 消除信号反射: 高速信号在传输线末端如果遇到阻抗突变,会产生反射。反射回来的信号会叠加在原信号上,造成波形畸变。120Ω匹配了CAN总线的特征阻抗(约120Ω),让信号“有去无回”。
  2. 提供总线偏置: 在隐性状态时,CAN_H和CAN_L都是2.5V。终端电阻把两根线“拉”在一起,确保总线在空闲时稳定在隐性电平。

标准CAN网络要求:

  • 总线两端各接一个120Ω电阻。
  • 两个电阻并联后,总电阻为60Ω。
  • 你可以用万用表在总线上任意两点测量CAN_H和CAN_L之间的电阻,正常值应该是60Ω左右。

小技巧: 我习惯在项目初期,先用万用表测一下CAN总线两端的电阻。如果测出来是120Ω,说明只接了一个终端电阻;如果是60Ω,说明两个都接上了;如果是0Ω或者无穷大,那肯定有地方短路或者断路了。这个习惯帮我省了不少排查时间。

3.4 位时序与同步机制

CAN总线没有单独的时钟线,时钟信息是嵌在数据信号里的。那接收端怎么知道什么时候该采样呢?这就靠位时序和同步机制。

一个CAN位时间被分成四段:

段名称 英文缩写 作用
同步段 Sync_Seg 用于同步总线上的各个节点,固定为1个Tq
传播段 Prop_Seg 补偿信号在总线上的传播延迟
相位缓冲段1 Phase_Seg1 用于补偿边沿相位误差,采样点之前
相位缓冲段2 Phase_Seg2 用于补偿边沿相位误差,采样点之后

其中,Tq是时间量子,是CAN控制器的最小时间单位。一个位时间由若干个Tq组成,通常为8到25个Tq。

采样点位于Phase_Seg1和Phase_Seg2之间。工程师可以通过调整Phase_Seg1和Phase_Seg2的长度,来移动采样点的位置。我个人习惯把采样点设置在87.5%左右,也就是一个位时间的后段。这样能给信号传播和振荡器误差留出更多余量。

3.5 同步机制:硬同步与重同步

CAN节点怎么保证自己的时钟和发送端对齐?靠两种同步方式:

  • 硬同步: 发生在总线从空闲(隐性)到开始传输(显性)的下降沿。每个节点检测到这个边沿后,会把自己的位时序计数器清零,强制对齐。
  • 重同步: 发生在数据传输过程中。如果接收端检测到边沿位置和预期有偏差,会通过缩短或延长Phase_Seg1/Phase_Seg2来调整,把采样点“拉”回到正确位置。

重同步的能力是有限的。CAN控制器有一个参数叫SJW(同步跳转宽度),它限制了每次重同步最多能调整多少个Tq。SJW通常设为1到4个Tq。

我曾经踩过的坑: 有次做多节点通讯测试,总线上挂了15个ECU,波特率500kbps。结果有个节点时不时丢帧。查了很久,发现那个节点的晶振精度是±1%,而其他节点是±0.1%。在长距离通讯时,累积的时钟误差超过了SJW的调整能力,导致同步失败。解决方案要么换晶振,要么把SJW设大一点。所以,同一个CAN网络里,尽量用同一精度等级的晶振。

3.6 知识结构总览

下面这张图把CAN物理层的核心要素串起来了,你可以对照着理解它们之间的关系。

CAN总线物理层知识结构 CAN物理层 差分信号 CAN_H / CAN_L 互补传输 共模抑制,抗干扰强 总线电平 显性(0) vs 隐性(1) 显性覆盖隐性 → 仲裁基础 终端电阻 两端各120Ω,并联60Ω 消除反射 + 提供偏置 位时序与同步 Sync_Seg + Prop_Seg + Phase_Seg1 + Phase_Seg2 硬同步(起始对齐)+ 重同步(持续调整)

这张图把咱们今天讲的内容串起来了。从差分信号到总线电平,从终端电阻到位时序同步,每一环都环环相扣。物理层搞扎实了,上层协议才能跑得稳。