一、CAN 总线基本特性简述
- 总线类型:多主结构(Multi-master),所有节点平等,可以主动发送。
- 通信介质:一条差分双绞线(CAN-H、CAN-L)。
- 电平定义:
- 显性位(Dominant):CAN-H > CAN-L,逻辑
0 - 隐性位(Recessive):CAN-H < CAN-L,逻辑
1 - 显性位比隐性位“强”,即显性覆盖隐性
- 显性位(Dominant):CAN-H > CAN-L,逻辑
二、仲裁机制详解(Arbitration)
原理:
- 当多个节点几乎同时开始发送时,会发生仲裁过程。
- 仲裁只发生在发送“标识符 ID”这段期间(帧起始 → 标识符结束)。
- ID 越小,优先级越高。仲裁按位进行,当某节点发现总线状态与自己发送的位不一致(它发1,但总线是0),它会立即中止发送,变为监听。
示例:
假设三个节点同时发:
| 节点 | 要发送的帧 ID(标准帧 11位) |
|---|---|
| A | 0x320 → 011 0010 0000 |
| B | 0x110 → 001 0001 0000 ✅ 胜 |
| C | 0x270 → 010 0111 0000 |
逐位对比(从左到右):
- 第 1 位:全是
0(显性),继续。 - 第 2 位:B=0,A=1 → A发现输了,退出
- 第 3 位:B=1,C=0 → B=1 ≠ 总线=0,B退出?
- 不,实际是 C=1,B=0 → C退出
- 最终 B 获胜,继续发送,A/C进入监听。
重点:
- 冲突在仲裁阶段自动解决。
- 所有节点都实时监听总线上的实际电平(不是“我发了什么”,而是“我看到什么”)。
三、冲突机制详解(Collision)
CAN 中没有传统以太网那样的“碰撞(Collision)”
- 仲裁阶段解决冲突
- 不存在两个节点同时完整发帧然后撞上的现象
- 唯一“可能撞车”的情况是:硬件电气层接线错误造成的非协议级错误
四、错帧机制详解(Error Frame)
CAN 协议定义了五种错误类型。当节点发现错误时,主动发一个错误帧来打断当前通信,通知其他节点“重来一次”。
错误帧结构:
- 主体为 6~12 个显性位(0)
- 表示有严重错误,通知所有节点当前帧无效
错误类型:
| 错误类型 | 含义 |
|---|---|
| Bit Error | 发送的位与检测的总线状态不符(如发送1却检测到总线为0) |
| Stuff Error | 连续发送 6 个相同位(CAN 规定最多5位相同,需插入反位) |
| CRC Error | CRC 校验失败 |
| Form Error | 帧格式非法(如 ACK 槽不是 recessive) |
| Acknowledge Error | 发送帧时接收方未在 ACK 位应答 |
示例:
- 节点 A 发帧,节点 B 检测到 CRC 错误
- 节点 B 立即发送“错误帧” → 主动插入 6 个显性位
- 所有节点检测到错误帧 → 当前帧作废
- 节点 A 稍后会自动重发(硬件层重发)
五、监听机制详解(Listening)
普通监听:
- 所有非发送节点默认都是监听状态
- 监听期间实时接收并判断是否是“感兴趣的帧”
- 如果匹配 ID,就触发接收回调(或设置标志位)
静默监听模式(Silent Mode):
- 某些测试设备(如监听器)可以配置为只接收不发送
- 用于协议分析、总线监听等用途
六、综合例子说明仲裁 + 错误帧 + 监听过程
假设你有 3 个 USB-CAN 设备连接:
- CAN1:发送 ID
0x300,数据[11 22 33 44] - CAN2:发送 ID
0x100,数据[AA BB CC DD] - CAN3:设置为只监听 ID
0x100
过程:
- CAN1 和 CAN2 同时发送 → 仲裁阶段发生
- ID 比较 →
0x100 < 0x300,CAN2 获胜 - CAN1 停止发送,进入监听状态
- CAN3 检测到 ID = 0x100,符合接收条件,保存数据
[AA BB CC DD] - CAN2 的帧被 CAN3 正确接收
- 如果 CAN3 检测到 CRC 错误(比如线缆干扰),它立即发送错误帧(6 个显性位)
- 所有节点放弃该帧
- CAN2 稍后自动重发
- CAN3 成功接收新帧并应答 ACK
总结表格
| 术语 | 定义 | 特点或行为 |
|---|---|---|
| 仲裁 | 通过 ID 优先级解决多主竞争,ID 越小越优先 | 发送期间动态检测电平,仲裁失败自动退出发送 |
| 冲突 | 传统意义上无冲突,仲裁阶段解决 | “冲突”变成了“仲裁失败” |
| 错帧 | 出现 Bit、CRC、格式等错误时插入显性位打断 | 所有节点丢弃当前帧,发送方稍后自动重发 |
| 监听 | 非发送节点监听总线,如匹配 ID 则接收 | 可设置静默模式用于诊断,始终不发送任何电平 |