1. 总线架构与通信模型
1.1 多主架构
- 无主从之分,任意节点均可主动抢占总线发送数据。
- 广播式通信:所有节点接收总线上的全部帧,通过 ID 过滤决定是否处理。
1.2 与 SPI/I2C 的差异
| 维度 | CAN | SPI | I2C |
|---|---|---|---|
| 主从关系 | 多主,无主从 | 一主多从 | 一主多从 |
| 通信方式 | 广播,节点按需过滤 | 点对点全双工 | 点对点半双工 |
| 同步方式 | 异步(无时钟线) | 同步(有时钟线) | 同步(有时钟线) |
| 仲裁机制 | 非破坏性位仲裁 | 无仲裁,主机控制 | 无仲裁,主机控制 |
| 物理层 | 差分信号 | 单端信号 | 单端信号 |
2. 物理层与信号定义
2.1 差分信号
CAN_H与CAN_L构成差分对。- 显性位(Dominant):
CAN_H≈ 3.5V,CAN_L≈ 1.5V,差分电压典型值约 2V(范围约 1.5V~3.0V)。 - 隐性位(Recessive):
CAN_H≈CAN_L≈ 2.5V,差分电压典型值约 0V(范围约 -0.5V~0.05V)。
2.2 线与逻辑
- 总线电气特性为线与结构。
- 显性位(逻辑0)可覆盖隐性位(逻辑1)。
- 该特性是 CAN 仲裁机制的基础。
2.3 逻辑电平映射
- 显性位对应逻辑0,隐性位对应逻辑1。
- 该映射由线与的电气特性决定:0 覆盖 1,ID 中 0 越多的节点(ID 数值越小)优先级越高。
3. 数据帧格式
3.1 标准数据帧结构
| 字段 | 长度 | 说明 |
|---|---|---|
SOF | 1 bit(显性) | 帧起始 |
| 仲裁场 | 12 bit | 11-bit ID + RTR 位 |
| 控制场 | 6 bit | IDE + r0 + DLC(4 bit) |
| 数据场 | 0~8 byte | 实际载荷数据 |
| CRC 场 | 15 bit + 1 bit | CRC 序列 + CRC 界定符(隐性) |
| ACK 场 | 2 bit | ACK Slot + ACK 界定符(隐性) |
EOF | 7 bit(隐性) | 帧结束 |
IFS | 3 bit(隐性) | 帧间隔 |
3.2 关键控制位
| 位 | 全称 | 取值与含义 |
|---|---|---|
RTR | Remote Transmission Request | 数据帧中为0(显性),远程帧中为1(隐性)。相同 ID 下,数据帧优先级高于远程帧 |
IDE | Identifier Extension | 标准帧(11-bit ID)中为0(显性),扩展帧(29-bit ID)中为1(隐性) |
r0 | Reserved | 标准 CAN 中固定为0(显性)。CAN FD 中重定义为 FDF(Flexible Data-rate Format),FDF=1 表示 CAN FD 帧 |
DLC | Data Length Code | 4 bit,表示数据场字节数,取值范围 0~8 |
3.3 扩展帧差异
- 扩展帧在 11 位基础 ID 后插入一个固定为隐性的
SRR位。 - 随后发送
IDE=1,再接 18 位扩展 ID。 - 扩展帧控制场中增加
r1保留位,发送时固定为0(显性)。
4. 总线仲裁机制
4.1 仲裁前提
- 总线空闲判定:连续检测到 11 个隐性位。
- 多个节点可能在同一时刻开始发送
SOF。
4.2 位仲裁过程
- 仲裁覆盖整个仲裁场(ID +
RTR),而非仅SOF。 - 各节点在发送每一位的同时监听总线电平。
- 若发送隐性位(1)但检测到显性位(0),则判定仲裁失败,自动退出发送并转为接收模式。
- 仲裁失败的节点在总线再次空闲时自动重发,无需上层干预。
4.3 优先级规则
- ID 数值越小,优先级越高。
- 原因:ID 中 0(显性位)更多的节点在仲裁中更早胜出。
5. ACK 应答机制
5.1 ACK 场结构
ACK 场由两个位组成:
- ACK Slot:1 bit,应答窗口
- ACK Delimiter:1 bit,固定为隐性位
5.2 发送方行为
- 在 ACK Slot 期间向总线发送隐性位,同时监听总线电平。
- 在 ACK Delimiter 期间发送隐性位。
- 两个位时间严格连续,ACK Delimiter 在 ACK Slot 的下一个 bit time 准时发送,不等待、不延迟。
5.3 接收方行为
- 若 CRC 校验通过,在 ACK Slot 期间向总线发送显性位。
- 发送方的隐性位与接收方的显性位进行线与,总线呈现显性。
- 若 CRC 校验失败,接收方不发显性位,总线保持隐性。
5.4 应答判定
- 发送方在 ACK Slot 期间检测到显性位 → 至少有一个节点正确接收。
- 发送方在 ACK Slot 期间检测到隐性位 → 无节点正确接收,产生 ACK Error,进入错误处理/重发流程。
- 若 ACK Delimiter 期间检测到显性位,产生 Form Error(格式错误)。
5.5 时序要点
- ACK Slot 的时长为一个 bit time,由总线波特率决定。
- 位时序为刚性同步,每个位时间的操作预先确定,非事件驱动。
- 发送方与接收方在 ACK Slot 的同一 bit time 内同步操作,非先后串行时序。
6. 远程帧
- 远程帧用于向总线请求特定 ID 的数据。
- 远程帧包含仲裁场和控制场,但不包含数据场。
- 相同 ID 下,数据帧的
RTR=0 会覆盖远程帧的RTR=1,数据帧优先级更高。
7. 三节点网络通信过程模拟
以下以一个典型工业控制场景为例,模拟三个节点在 CAN 总线上的完整交互过程。
7.1 网络拓扑与节点定义
| 节点 | 角色 | 分配 ID | 功能描述 |
|---|---|---|---|
| Node A | 温度采集模块 | 0x100 | 周期性发送温度数据 |
| Node B | 电机驱动模块 | 0x200 | 接收控制指令,反馈状态 |
| Node C | 主控制器 | 0x300 | 下发指令,汇总传感器数据 |
总线波特率:500 kbps(位时间 2 μs)。
7.2 场景一:正常数据广播
Node A 完成温度采样后,向总线发送一帧数据。
帧内容:
- ID:
0x100 - DLC:2
- Data:
0x01 0xA4(表示温度 42.0°C,按协议编码)
总线时序:
| 阶段 | 总线电平 | 说明 |
|---|---|---|
SOF | 显性 | Node A 发送帧起始 |
| 仲裁场 | 0x100 逐位发送 | Node A 发送 ID 位,无竞争,总线电平与发送一致 |
| 控制场 | DLC=2 | Node A 发送控制信息 |
| 数据场 | 0x01 0xA4 | Node A 发送 2 byte 温度数据 |
| CRC 场 | CRC 序列 + CRC Delimiter(隐性) | Node A 发送 CRC 校验值 |
| ACK Slot | 显性 | Node B 与 Node C 均 CRC 校验通过,同时发送显性位覆盖总线 |
| ACK Delimiter | 隐性 | Node A 发送隐性位,总线恢复隐性 |
EOF | 7×隐性 | 帧结束 |
IFS | 3×隐性 | 帧间隔,总线进入空闲 |
节点过滤行为:
- Node B 的接收过滤器配置为仅接收 ID
0x300(控制指令)与0x100(温度)。收到0x100后,Node B 读取温度数据用于电机过热保护逻辑。 - Node C 的接收过滤器配置为接收
0x100与0x200。收到0x100后,Node C 将温度值存入本地缓冲区,供上层应用读取。
7.3 场景二:总线竞争与仲裁
总线空闲期间,Node B 与 Node C 同时准备发送。
待发送帧:
- Node B:ID
0x200,电机状态反馈 - Node C:ID
0x300,控制指令
仲裁过程逐位分析:
| 位位置 | Node B 发送 | Node C 发送 | 总线实际电平 | 结果 |
|---|---|---|---|---|
SOF | 显性(0) | 显性(0) | 显性 | 双方继续 |
| ID[10] | 0(0x200 最高位) | 0(0x300 最高位) | 显性 | 双方继续 |
| ID[9] | 0 | 0 | 显性 | 双方继续 |
| ID[8] | 1(0x200 的 bit8=1) | 1(0x300 的 bit8=1) | 隐性 | 双方继续 |
| ID[7] | 0 | 0 | 显性 | 双方继续 |
| ID[6] | 0 | 0 | 显性 | 双方继续 |
| ID[5] | 0 | 0 | 显性 | 双方继续 |
| ID[4] | 0 | 0 | 显性 | 双方继续 |
| ID[3] | 0 | 0 | 显性 | 双方继续 |
| ID[2] | 0 | 0 | 显性 | 双方继续 |
| ID[1] | 0 | 0 | 显性 | 双方继续 |
| ID[0] | 0 | 0 | 显性 | 双方继续 |
RTR | 0(数据帧) | 0(数据帧) | 显性 | 双方继续 |
将 0x200 与 0x300 展开为 11 位二进制:
0x200=0b010 0000 00000x300=0b011 0000 0000
差异出现在 ID[8] 位:0x200 为 0,0x300 为 1。
| 位位置 | Node B 发送 | Node C 发送 | 总线实际电平 | 结果 |
|---|---|---|---|---|
SOF | 0 | 0 | 显性 | 继续 |
| ID[10] | 0 | 0 | 显性 | 继续 |
| ID[9] | 1 | 1 | 隐性 | 继续 |
| ID[8] | 0 | 1 | 显性 | Node C 检测到隐性发送但显性总线,仲裁失败,退出发送 |
- Node C 在 ID[8] 位发送隐性位(1),但监听到总线为显性位(0)。
- Node C 判定仲裁失败,立即退出发送状态,转为接收模式。
- Node B 继续完成后续字段的发送。
仲裁结果:
- Node B(
0x200)获得总线使用权,完整发送电机状态帧。 - Node C(
0x300)在总线空闲后自动重发控制指令帧。
7.4 场景三:ACK 应答细节
Node B 发送的电机状态帧到达 ACK 阶段。
ACK 场时序(500 kbps,位时间 2 μs):
| 时刻 | 字段 | Node B(发送方) | Node A(接收方) | Node C(接收方) | 总线电平 |
|---|---|---|---|---|---|
| T0 | CRC Delimiter | 发隐性 | 监听 | 监听 | 隐性 |
| T0+2μs | ACK Slot | 发隐性 + 监听 | CRC 校验通过 → 发显性 | CRC 校验通过 → 发显性 | 显性(线与结果) |
| T0+4μs | ACK Delimiter | 发隐性 | 发隐性 | 发隐性 | 隐性 |
- Node B 在 ACK Slot 期间检测到显性位 → 记录发送成功。
- 若 Node A 或 Node C 中任一 CRC 校验失败,该节点在 ACK Slot 期间不发显性位;但只要另一节点校验通过,总线仍为显性,Node B 仍判定成功。
- 若 Node A 与 Node C 均 CRC 校验失败,ACK Slot 保持隐性,Node B 产生 ACK Error。
7.5 场景四:错误帧与错误处理
假设 Node A 在接收 Node B 的帧时,因电磁干扰导致 CRC 校验失败。
错误处理流程:
- Node A 在 CRC 场结束后发现校验不匹配。
- Node A 在 ACK Delimiter 之后立即发送错误帧(6~12 个连续显性位,即 Error Flag)。
- 总线上所有节点(包括 Node B 与 Node C)检测到错误帧后,均丢弃当前帧。
- Node B 作为发送方,检测到总线上出现错误帧,其发送错误计数器(
TEC)加 8。 - 总线空闲后,Node B 自动重发该帧。
- 若 Node A 的接收错误计数器(
REC)持续增加,当REC> 127 时,Node A 进入错误被动状态(Error Passive),此后 Node A 发送的错误帧由 6 个显性位缩短为 6 个隐性位。
7.6 通信时序汇总
以下为一个完整周期内三个节点的总线活动概览:
| 时隙 | 总线状态 | 活动节点 | 说明 |
|---|---|---|---|
| 1 | 空闲 | — | 连续 11 个隐性位 |
| 2 | 数据帧 | Node A → 广播 | 温度数据,ID 0x100 |
| 3 | 应答 | Node B、Node C | ACK Slot 发显性 |
| 4 | 空闲 | — | IFS 帧间隔 |
| 5 | 竞争 | Node B vs Node C | 同时开始发送 |
| 6 | 仲裁 | Node B 胜出 | ID 0x200 < 0x300 |
| 7 | 数据帧 | Node B → 广播 | 电机状态反馈 |
| 8 | 应答 | Node A、Node C | ACK Slot 发显性 |
| 9 | 空闲 | — | IFS 帧间隔 |
| 10 | 数据帧 | Node C → 广播 | 控制指令重发,ID 0x300 |
| 11 | 应答 | Node A、Node B | ACK Slot 发显性 |
| 12 | 空闲 | — | 进入下一周期 |