3、CAN总线通信原理:多主竞争、显性隐性、位仲裁机制、位填充规则
说到CAN总线,很多朋友第一反应就是“它很可靠”。但可靠在哪?核心就在它那套独特的通信原理上。今天我就把这几个关键点拆开来讲。你看完就能明白,为什么CAN能在汽车、工业这种嘈杂环境里,还能稳稳当当传数据。
我个人习惯,每次讲原理都会先画个整体框架。咱们从最根本的总线电平开始。
3.1 多主竞争:谁都能抢,但得讲规矩
CAN总线上的节点,没有“老大”。任何一个节点,只要总线空闲,都能开始发数据。这就叫“多主”。
你想想看,要是两个节点同时发,不就打架了吗?嗯,确实会。但CAN不是硬碰硬,它有一套“软件握手”的协议。
我在做车身网关项目时,就遇到过两个ECU抢着发报文。一个报车速,一个报转向。结果总线上一团乱。后来我抓包一看,原来是仲裁机制没看懂。
3.2 显性隐性:0和1的物理含义
这个好理解。CAN总线上,电信号有两种状态:
- 显性(Dominant): 逻辑0。此时CAN_H电压≈3.5V,CAN_L电压≈1.5V,差分电压约2V。
- 隐性(Recessive): 逻辑1。此时两条线电压都≈2.5V,差分电压≈0V。
关键点来了:显性信号会“覆盖”隐性信号。说白了,只要有一个节点发0,总线就是0。
3.3 位仲裁机制:谁优先级高,谁先走
这才是CAN总线的灵魂。
当多个节点同时发送时,它们会从CAN帧的“仲裁段”开始,逐位往总线上发。每个节点都会同时监听总线电平。如果自己发的是隐性(1),但总线上是显性(0),那说明有别人在发优先级更高的数据。它会立刻停止发送,转为接收模式。
这个仲裁过程,比CPU的上下文切换快多了。
举个例子:
节点A发:1010 1100
节点B发:1011 0010
从最高位开始比:
- 第1位:A发1,B发1,一致,继续。
- 第2位:A发0,B发1,总线显性(0)→ B发现自己是隐性而总线是显性,B退出。
- A继续发完剩下的数据。
你看,整个过程没有冲突,没有丢数据,没有重传。这就是CAN的高明之处。
3.4 位填充规则:确保时钟同步不出错
CAN总线没有单独的时钟线。所有节点都靠总线信号边沿来同步,自己恢复时钟。
但问题来了:如果连续发5个相同的位(比如5个0或5个1),总线就没有跳变沿了。没有跳变,节点就没法纠正自己的时钟偏差。久了就会丢位,整帧数据就毁了。
所以,CAN协议规定:发送器在连续发送5个相同位后,必须插入一个极性相反的位。
| 发送数据 | 实际线上波形(含填充) |
|---|---|
| 0000 0 1111 1 | 0000 01 1111 10 |
| 1111 1 0000 0 | 1111 10 0000 01 |
接收器看到5个相同位后,就知道下一个位是填充的,会自动把它去掉。这样,数据内容一点没变,但总线保证每6个位最多会有一次跳变。
我记得有个同事调试时,线上数据总是对不上,用逻辑分析仪看也没问题。后来我让他把“位填充”的规则手工算一遍,发现接收器误把填充位当成了数据。原因就是他的时钟恢复算法没有正确处理填充位。
- 位填充解决了时钟同步问题。
- 发送器在5个连续相同位后,插入一个相反位。
- 接收器自动删除填充位。
- 只有数据段和CRC段会做填充。帧起始、仲裁段、控制段、ACK段不填充。
下面这张图,我把CAN总线仲裁和填充的整个流程串起来了。你看一遍,基本就能在大脑里跑一遍总线逻辑。
你看,整个通信过程就像一场有秩序的“辩论赛”。谁先拿到“话筒”(发送权),靠的是ID大小。谁能在长句中间保持“节奏”(时钟同步),靠的是填充规则。这两者一起,保证了CAN总线的高效和可靠。
好了,这一章就到这。记住这三个关键词:显性隐性定胜负,位仲裁定优先,位填充定同步。后面章节我们会用实际抓包数据,一步步验证这些原理。