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总线拓扑结构:
这张图里,四个ECU通过分支线挂在主线上。注意分支线必须尽可能短,否则会产生信号反射。我一般要求硬件工程师把分支控制在20cm以内,超过30cm就要加中继器或CAN网桥。
1.5 总结与实战要点
好了,这一章的内容就这些。总结几个关键点,做驱动开发时一定要记住:
- CAN是差分信号,抗干扰能力强,但布线要规范
- 终端电阻必须加,两端各120Ω,少一个都不行
- 分支越短越好,超过30cm容易出问题
- 波特率与线长成反比,长线用低速,短线用高速
- CAN 2.0A/B和CAN FD,驱动开发都要支持
个人建议:刚开始学CAN驱动,先拿一个USB-CAN适配器配合PCAN-View或candump工具,在桌面上搭一个最小系统——两个节点、两根线、两个120Ω电阻。把显性位、隐性位、仲裁、错误帧这些概念在示波器上看一遍,比读十遍书都管用。