1. CAN总线基础:从起源到仲裁机制
大家好,我是你们的嵌入式系统讲师。今天咱们来聊聊CAN总线——这个在汽车和工业领域无处不在的通信协议。说实话,我最早接触CAN总线是在做车载诊断系统的时候,那会儿被它的抗干扰能力惊到了。嗯,咱们就从它的起源开始说起吧。
1.1 CAN协议的起源
CAN(Controller Area Network)是上世纪80年代由德国博世公司开发的。当时汽车电子系统越来越复杂,各个ECU之间需要通信,传统的点对点接线方式已经不堪重负。你想想看,一辆豪华车可能有几十个ECU,如果每个都单独连线,线束重量和成本都受不了。
我个人觉得,CAN总线最聪明的地方在于它用两条线就解决了所有ECU之间的通信问题。1986年,博世在SAE大会上正式发布了CAN协议,后来被国际标准化组织采纳为ISO 11898标准。我在做第一个CAN项目时,用的还是20年前的SJA1000控制器,现在想想真是感慨。
1.2 CAN物理层特性
CAN总线物理层用的是差分信号传输。说白了,就是靠两条线——CAN_H和CAN_L的电压差来传递信息。这样做的好处很明显:抗干扰能力强。
关键参数:
- 显性电平(逻辑0):CAN_H比CAN_L高2V左右
- 隐性电平(逻辑1):CAN_H和CAN_L电压相等(约2.5V)
- 总线电压范围:-2V到+7V(ISO 11898标准)
我记得有一次在实验室调试,电机启动瞬间总线电压被拉到-3V,普通RS485早就挂了,但CAN总线居然还能正常工作。这就是差分信号的优势。
| 参数 | 高速CAN(ISO 11898-2) | 低速CAN(ISO 11898-3) |
|---|---|---|
| 最大速率 | 1 Mbps | 125 kbps |
| 总线长度 | 40m @ 1Mbps | 500m @ 125kbps |
| 终端电阻 | 120Ω(两端) | 2.2kΩ(每节点) |
避坑指南:我曾经因为终端电阻没接好,导致总线反射严重,通信时好时坏。后来用示波器一看,信号边沿全是振铃。记住:高速CAN必须在总线两端各接一个120Ω电阻,不能省。
1.3 CAN数据帧结构
CAN的数据帧分为标准帧(11位ID)和扩展帧(29位ID)。咱们先看标准帧的结构:
帧起始(1bit) + 仲裁场(12bit) + 控制场(6bit) + 数据场(0-8byte) + CRC场(16bit) + 应答场(2bit) + 帧结束(7bit)
这里我重点说说数据场。CAN帧最多只能带8个字节的数据。为什么这么少?因为CAN设计初衷是实时控制,短帧意味着低延迟。我在做电机控制时,8个字节刚好够放一个电流环的反馈数据。
个人经验:如果你需要传输超过8字节的数据,比如固件升级,就得自己实现分包协议。我习惯在数据场前两个字节放序列号和总包数,后面6个字节放实际数据。这样接收端可以重组完整数据包。
1.4 CAN总线仲裁机制
这是CAN总线最精彩的部分。多个节点同时发送时,怎么决定谁先发?答案是:按ID优先级仲裁。
仲裁过程是这样的:
- 所有发送节点同时发送帧起始位和ID位
- 每个节点在发送位的同时监听总线电平
- 如果某个节点发送了隐性位(1),但总线上是显性位(0),说明有更高优先级的节点在发送
- 该节点立即停止发送,转为接收模式
为什么会这样?因为显性位(0)会覆盖隐性位(1)。所以ID值越小,优先级越高。我见过不少新手把ID设成0x7FF,结果发现自己的报文总是发不出去——因为优先级太低了。
仲裁规则总结:
- ID越小,优先级越高
- 标准帧优先级高于扩展帧(因为RTR位不同)
- 数据帧优先级高于远程帧
- 仲裁不会破坏数据,胜出的节点继续发送
嗯,这里要注意:仲裁机制要求所有节点的时钟精度在1.5%以内。我曾经用内部RC振荡器做CAN节点,结果时钟偏差太大,仲裁时老是出错。后来换了晶振,问题就解决了。
好了,这一章的内容就到这里。CAN总线的基础知识是后面所有章节的基石。下一章咱们会深入CAN控制器和收发器的选型,到时候我会分享一些实际项目中的选型经验。