1. CAN总线基础:从起源到物理层

各位同学,咱们今天聊聊CAN总线。说实话,我最早接触CAN是在做车载项目的时候,那时候刚毕业,看着示波器上两条绞在一起的线,完全搞不懂为什么汽车电子要用这么个东西。后来踩了不少坑,才慢慢摸透了它的脾气。

CAN总线,全称Controller Area Network,控制器局域网。这玩意儿是德国Bosch公司在1986年发明的,初衷很简单——解决汽车内部电子控制单元(ECU)之间的大量线束问题。你想想看,一辆车几十个ECU,如果每个信号都拉一根独立的线,那线束比车还重。

核心要点:CAN总线是一种多主总线,任何节点都可以主动发送数据,不需要主机调度。这是它和I2C、SPI最大的区别。

1.1 CAN协议的起源与演进

1986年,Bosch在SAE大会上正式发布了CAN协议。我记得当时汽车行业正被线束成本和可靠性问题折磨得够呛。传统点对点布线,一个高端车型的线束总长能超过2公里,重量几十公斤。这不仅是成本问题,更是安全隐患——接头越多,故障点越多。

CAN协议的目标很明确:

  • 减少线束:用两根线代替几十根信号线
  • 高可靠性:能在电磁干扰严重的汽车环境中稳定工作
  • 实时性:优先级高的消息必须按时送达
  • 灵活性:增减节点不需要改动硬件布线

后来CAN协议演进出几个版本:

版本 标准 数据帧长度 速率
CAN 2.0A 标准帧 11位ID 最高1Mbps
CAN 2.0B 扩展帧 29位ID 最高1Mbps
CAN FD 灵活数据速率 最多64字节 数据段最高8Mbps

我个人习惯把CAN 2.0A/B叫做经典CAN,CAN FD是后来为了应对大数据量需求推出的。做Linux驱动开发,经典CAN和CAN FD都要支持,因为现在很多新车型已经开始用CAN FD了。

1.2 CAN物理层特性

CAN物理层,说白了就是那两根线——CAN_H和CAN_L。但别小看这两根线,里面的门道不少。

电气特性:

  • 总线电压:CAN_H约3.5V,CAN_L约1.5V(显性位)
  • 隐性位时:CAN_H和CAN_L都约2.5V
  • 差分电压:显性位约2V,隐性位约0V
  • 终端电阻:总线两端各120Ω,匹配特性阻抗

避坑指南:我曾经在一个项目中忘记加终端电阻,结果总线信号反射得一塌糊涂,通信时好时坏。查了两天才发现是这个问题。记住,CAN总线两端必须各有一个120Ω电阻,少一个都不行。

速率与距离的关系:

速率 最大总线长度 典型应用
1 Mbps 40 m 车内动力系统
500 kbps 100 m 车身控制
250 kbps 250 m 工业控制
125 kbps 500 m 楼宇自动化

为什么会这样?因为速率越高,信号上升沿越陡,对总线电容越敏感。线越长,分布电容越大,信号畸变越严重。所以做驱动开发时,一定要根据实际线长配置正确的波特率。

1.3 CAN差分信号原理

CAN用差分信号传输,这是它抗干扰能力强的根本原因。咱们来拆解一下原理。

差分信号 vs 单端信号:

  • 单端信号:一根信号线+地线,干扰直接叠加在信号上
  • 差分信号:两根线互为参考,干扰同时作用在两根线上,相减后抵消

CAN收发器内部结构很简单:

  • 发送时:显性位驱动CAN_H拉高、CAN_L拉低;隐性位释放总线,靠终端电阻拉到2.5V
  • 接收时:比较CAN_H和CAN_L的电压差,差>0.9V判为显性,差<0.5V判为隐性

关键点:CAN总线采用"线与"逻辑。显性位会覆盖隐性位。这意味着如果两个节点同时发送,优先级低的节点检测到总线与自己的输出不一致,就会自动退出。这就是CAN的仲裁机制——无损位仲裁。

我记得有一次在实验室调试,示波器探头一搭上去,波形就变了。后来发现是探头地线夹子太长,引入了噪声。做CAN调试,示波器要用差分探头,或者用两个通道做数学减法,才能看到真实的差分信号。

1.4 CAN总线拓扑结构

CAN总线是典型的线性拓扑,也叫总线型拓扑。所有节点都挂在同一条总线上,像路灯一样串联。

标准拓扑要求:

  • 主线:双绞线,特性阻抗120Ω
  • 分支:越短越好,一般不超过30cm
  • 节点数:最多110个(取决于收发器驱动能力)
  • 终端:两端各一个120Ω电阻

警告:千万不要用星型拓扑或环形拓扑!我曾经见过一个项目,为了布线方便把CAN接成了星型,结果信号反射严重,怎么调波特率都不行。最后老老实实改回总线型,问题立刻解决。CAN的物理层设计就是为总线型优化的,别自作聪明。

下面这张图展示了典型的CAN总线拓扑结构:

CAN总线拓扑结构 120Ω 120Ω ECU 1 ECU 2 ECU 3 ECU 4 分支≤30cm 分支≤30cm 分支≤30cm 分支≤30cm CAN_H / CAN_L 双绞线

这张图里,四个ECU通过分支线挂在主线上。注意分支线必须尽可能短,否则会产生信号反射。我一般要求硬件工程师把分支控制在20cm以内,超过30cm就要加中继器或CAN网桥。

1.5 总结与实战要点

好了,这一章的内容就这些。总结几个关键点,做驱动开发时一定要记住:

  • CAN是差分信号,抗干扰能力强,但布线要规范
  • 终端电阻必须加,两端各120Ω,少一个都不行
  • 分支越短越好,超过30cm容易出问题
  • 波特率与线长成反比,长线用低速,短线用高速
  • CAN 2.0A/B和CAN FD,驱动开发都要支持

个人建议:刚开始学CAN驱动,先拿一个USB-CAN适配器配合PCAN-View或candump工具,在桌面上搭一个最小系统——两个节点、两根线、两个120Ω电阻。把显性位、隐性位、仲裁、错误帧这些概念在示波器上看一遍,比读十遍书都管用。