1. CAN 总线基础:从诞生到物理层

1.1 为什么需要 CAN?—— 一段绕不开的背景

说到 CAN 总线,得先聊聊它为什么会出现。上世纪 80 年代,汽车上的电子设备越来越多,空调、ABS、发动机控制……每个模块之间都要连一堆线。你想想看,一辆车里的线束重量都快赶上发动机了,又重又乱,还容易出故障。

我记得当年做第一个车载项目时,光排查一根短路的地线就花了三天。那时候我就想,要是能有一条总线,让所有设备用两根线通信,该多省事。1986 年,博世公司正式提出了 CAN 协议 ——Controller Area Network。说白了就是给汽车上的各种控制器建一条“高速公路”,让它们可以共享数据,减少线束,提高可靠性。

这个协议很快被标准化,成了 ISO 11898 系列。到今天,CAN 依然是汽车、工业自动化、医疗设备里最常用的现场总线之一。

1.2 ISO 标准层级:CAN 在 OSI 模型里的位置

CAN 协议只定义了物理层和数据链路层,上面几层通常由更高层协议(比如 CANopen、J1939)来补充。我们来看一张表格,对比一下 OSI 和 CAN 的分层关系:

OSI 模型层 CAN 协议对应 典型功能
应用层用户自定义 / 高层协议(如 CANopen)信号打包、PDO/SDO 等
表示层—无
会话层—无
传输层—无
网络层—无
数据链路层CAN 协议核心帧封装、仲裁、CRC 校验、应答
物理层ISO 11898-2 / -5差分信号、终端电阻、位时序

你可以把 CAN 的物理层想象成一条“双车道公路”,数据链路层就是交通规则。没有交通规则,车再多也会堵死。实际上我们在抓包分析时,大部分故障都出在物理层 —— 比如信号反射、终端电阻缺失、共模干扰。所以这一章我们重点讲物理层。

1.3 物理层核心:差分信号

CAN 总线用两根线传输:CAN_H 和 CAN_L。它不靠单根线的电压高低来表示 0 和 1,而是靠两根线的电压差。这就是差分信号。

  • 显性(Dominant):CAN_H ≈ 3.5V,CAN_L ≈ 1.5V,差分电压约 2V,代表逻辑 0。
  • 隐性(Recessive):CAN_H ≈ 2.5V,CAN_L ≈ 2.5V,差分电压约 0V,代表逻辑 1。

你可能会问:为什么要用两根线?我刚开始学的时候也觉得多此一举。后来在项目中遇到一次强电磁干扰,单端信号全乱了,CAN 总线却稳如泰山。差分信号天然抗共模噪声 —— 干扰同时叠加在两根线上,差分值几乎不变。这就是 CAN 能在工厂、汽车这种吵闹环境里存活的原因。

我个人习惯:在示波器上同时看 CAN_H 和 CAN_L,再切换到“数学通道”做减法。这样一眼就能看出差分幅值是否达标。标准要求差分电压至少 1.5V 才算可靠显性。

1.4 物理层核心:终端电阻

CAN 总线两端必须各接一个 120Ω 的电阻。为什么是 120?因为双绞线的特性阻抗大约是 120Ω,终端电阻用来匹配阻抗,防止信号在末端反射。

我曾经遇到一个案例:生产线上一台设备偶尔掉线,抓包发现 CAN 帧的 ACK 位总是不稳定。最后发现是终端电阻忘记焊了,总线末端信号反射回来,把 ACK 撞坏了。装上电阻,问题立刻消失。

一定要注意:终端电阻只能加在总线两端,中间节点不能加。如果总线上有多个电阻并联,等效阻抗会变小,信号幅值下降,通信距离缩短。如果你发现总线空闲时 CAN_H 和 CAN_L 电压不是 2.5V 附近,多半是终端电阻出了问题。

1.5 一张图看懂物理层结构

下面这个 SVG 示意图展示了两个 CAN 节点通过双绞线连接,两端各有一个 120Ω 终端电阻。每个节点内部包含 CAN 控制器和收发器,收发器负责把差分信号转换成单端逻辑电平给控制器。

CAN 总线物理层连接结构 CAN 总线物理层连接结构 节点 A 控制器 收发器 120Ω CAN_H (2.5V / 3.5V) CAN_L (2.5V / 1.5V) 节点 B 控制器 收发器 120Ω 双绞线特性阻抗 ≈ 120Ω 差分信号:Vdiff = CAN_H - CAN_L 终端电阻消除信号反射 隐性:Vdiff ≈ 0V 显性:Vdiff ≈ 2V

小技巧:用万用表测量 CAN_H 与 CAN_L 之间的电阻。如果总线断电且只有两端有终端电阻,测到的阻值应该是 60Ω(两个 120Ω 并联)。如果只有 120Ω,说明一端没接电阻;如果是 40Ω 左右,可能中间某个节点也接了电阻。这个测量方法是我在现场排查时的首选。

1.6 物理层参数速查

下面这个表格汇总了 CAN 物理层的关键参数,方便你对照:

参数典型值说明
差分电压(显性)1.5 ~ 3.0 V推荐不低于 1.5V
差分电压(隐性)≤ 0.5 V理想为 0V
总线空闲电压≈ 2.5 VCAN_H 与 CAN_L 相等
终端电阻120 Ω ± 1%两端各一个,不可省略
最大传输距离(125kbps)约 500 m速度越低距离越长
最大节点数30 ~ 110取决于收发器驱动能力