第2章:CAN总线基础——协议原理、帧结构、仲裁机制与物理层
各位同学,咱们今天聊聊CAN总线。说实话,这玩意儿在车载网络里,就像人的脊柱一样重要。我做了十几年嵌入式,从最早的8位单片机到现在的多核处理器,CAN总线始终是绕不开的核心。今天我就把CAN总线的底裤给大家扒干净。
2.1 CAN协议原理:为什么它这么能打?
CAN(Controller Area Network)是德国Bosch公司在1986年发明的。你想想看,三十多年前的技术,到现在还在用,说明它的设计思想确实超前。
CAN协议的核心思想就四个字:多主通信。什么意思?就是总线上任何一个节点,随时都可以发消息,不需要等谁批准。这跟咱们常见的I2C、SPI那种主从模式完全不同。
关键特性:
- 多主总线:每个节点都能主动发消息
- 实时性:消息优先级高的先发,延迟可控
- 错误检测:5种错误检测机制,误码率极低
- 自动重发:出错后自动重发,不用软件干预
我记得刚入行那会儿,有个老工程师跟我说:“小伙子,CAN总线最牛的地方,不是它能传多快,而是它能在恶劣环境下稳定工作。”后来我在一个商用车项目里,亲眼看到CAN总线在-40℃到125℃的温差下,依然稳如老狗。嗯,这话一点不假。
2.2 CAN帧结构:数据是怎么打包的?
CAN总线上跑的数据,我们叫它“帧”。帧的结构,说白了就是数据包的格式。CAN有两种帧格式:标准帧(11位ID)和扩展帧(29位ID)。
咱们先看标准帧的结构:
SOF | 11位ID | RTR | IDE | r0 | DLC | 数据段(0-8字节) | CRC | ACK | EOF
我来拆开讲:
| 字段 | 长度 | 说明 |
|---|---|---|
| SOF | 1位 | 帧起始,显性电平(0) |
| ID | 11位 | 标识符,决定优先级 |
| RTR | 1位 | 远程帧请求位 |
| DLC | 4位 | 数据长度,0-8字节 |
| 数据段 | 0-64位 | 实际数据,最多8字节 |
| CRC | 15位 | 循环冗余校验 |
| ACK | 2位 | 应答位 |
| EOF | 7位 | 帧结束,隐性电平(1) |
个人经验:我建议你在设计CAN通信协议时,尽量把数据塞满8字节。为什么?因为CAN帧的包头开销是固定的,数据段越长,有效传输效率越高。我曾经在一个项目中,因为没注意这个细节,导致总线负载率飙升到80%以上,后来优化了一下数据打包方式,直接降到了40%。
2.3 CAN总线仲裁机制:谁先说话?
这个问题很有意思。多个节点同时发消息,总线怎么决定听谁的?
答案是:按优先级来。优先级由ID决定,ID越小,优先级越高。
具体怎么仲裁?我给大家讲个故事。假设总线上有两个节点同时发消息:
- 节点A:ID = 0x123(二进制:0001 0010 0011)
- 节点B:ID = 0x456(二进制:0100 0101 0110)
它们同时开始发SOF位,都是显性电平,没问题。然后开始发ID位。第一位,A发0,B发0,一样。第二位,A发0,B发1。这时候,A的0(显性)覆盖了B的1(隐性)。B一看,自己发的跟总线上的不一样,就知道自己输了,乖乖退出发送,转为接收模式。
核心原理:CAN总线采用“线与”逻辑。显性电平(0)可以覆盖隐性电平(1)。谁先发0,谁就赢。
你可能会问:“那如果两个节点ID完全一样怎么办?”嗯,这个问题问得好。实际项目中,我们要求每个节点的ID必须唯一。如果真出现ID冲突,那就会一直仲裁失败,数据永远发不出去。我曾经在调试一个ECU时,发现某个报文总是丢帧,查了两天才发现是ID重复了。那叫一个崩溃啊。
2.4 CAN物理层:信号是怎么在线上跑的?
物理层,说白了就是电信号怎么在两根线上传输。CAN总线用两根线:CAN_H和CAN_L。
信号电平有两种状态:
- 显性(Dominant):CAN_H = 3.5V,CAN_L = 1.5V,差分电压 = 2V,代表逻辑0
- 隐性(Recessive):CAN_H = 2.5V,CAN_L = 2.5V,差分电压 = 0V,代表逻辑1
为什么用差分信号?说白了就是为了抗干扰。两根线绞在一起,外界噪声对两根线的影响是一样的,差分电压不变。这在汽车这种电磁环境恶劣的地方,特别管用。
避坑指南:我曾经在一个项目中,因为CAN总线布线没注意,把CAN_H和CAN_L线分开了,结果通信时好时坏。后来查资料才知道,CAN总线必须用双绞线,而且绞距要控制在2-5cm。另外,终端电阻一定要加,120Ω,一个在总线两端。不加终端电阻,信号反射会让你怀疑人生。
CAN总线的通信速率跟总线长度有关系:
| 速率 | 最大总线长度 |
|---|---|
| 1 Mbps | 40 m |
| 500 kbps | 100 m |
| 250 kbps | 250 m |
| 125 kbps | 500 m |
| 50 kbps | 1000 m |
你想想看,为什么速率越高,总线长度越短?因为信号在线上传输需要时间,速率高了,位时间就短,如果总线太长,信号还没传到另一端,下一个位就来了,那不乱套了吗?
好了,CAN总线的基础就讲到这里。下一章咱们聊聊CAN的高层协议,比如J1939、CANopen这些。记住我今天讲的这些,后面你会用得着。
课后小建议:如果你手头有开发板,建议拿示波器看看CAN_H和CAN_L的波形。亲眼看到显性和隐性的电平变化,比看十遍书都管用。我当年就是这么学的。