一、CAN 简述
全称:Conrtoller Area Network,是ISO国际标准化的串行通信协议。低速CAN通信速率10 ~ 125Kbps,长度可达1000m,高速CAN通信速率125Kbps ~ 1Mbps。长度≤40m。CAN组成由控制器和收发器完成。
低速CAN总线拓扑图:
开环总线环境,最多支持20个节点
高速CAN总线拓扑图:
闭环总线环境,终端电阻(120Ω)用于阻抗匹配,减少回波反射。最多支持30个节点
- 总线类型:多主结构(Multi-master),所有节点平等,可以主动发送。
- 通信介质:一条差分双绞线(CAN-H、CAN-L)。
- 错误检测、错误通知、错误恢复。
- 电平定义:
- 显性位(Dominant):CAN-H > CAN-L,逻辑
0 - 隐性位(Recessive):CAN-H < CAN-L,逻辑
1 - 显性位比隐性位“强”,即显性覆盖隐性
- 显性位(Dominant):CAN-H > CAN-L,逻辑
CAN总线以“帧”形式进行通信。CAN协议定义了5种类型的帧:数据帧、遥控帧、错误帧、过载帧、间隔帧,其中数据帧最为常用。
| 帧类型 | 帧作用 |
|---|---|
| 数据帧(Data Frame) | 用于发送单元向接收单元传输数据的帧 |
| 遥控帧(Remote Frame) | 用于接收单元向具有相同ID的发送单元请求数据的帧 |
| 错误帧(Error Frame) | 用于当检测出错误时向其他单元通知错误的帧 |
| 过载帧(Overload Frame) | 用于接收单元通知其尚未做好接收准备的帧 |
| 间隔帧(Inter Frame Space) | 用于将数据帧及遥控帧与前面帧分隔开的帧 |
数据帧格式:
数据帧由7段组成,分成标准帧(CAN2.0A)和扩展帧(CAN2.0B),主要体现在仲裁段和控制段。
数据帧的 7 个段结构
帧起始 (SOF):1 位显性电平(逻辑0),表示帧开始并同步节点。
仲裁段:包含标识符 ID 和 RTR 位,决定优先级和帧类型。
控制段:包含 IDE、保留位和 4 位 DLC(数据长度码)。
数据段:0-8 字节实际数据,由 DLC 指定长度。
CRC 段:15 位校验序列 + 1 位界定符,检测传输错误。
ACK 段:1 位应答槽 + 1 位界定符,确认接收成功。
帧结束 (EOF):7 位隐性电平,表示帧传输完成。
标准帧与扩展帧区别
标准帧:11 位 ID,仲裁段共 12 位(11 位 ID+1 位 RTR),总长度约 44-108 位。
扩展帧:29 位 ID(11 位基础 ID+18 位扩展 ID),增加 SRR 和 IDE 位,总长度约 64-128 位。
标准帧优先级高于扩展帧(相同基础 ID 时)。
关键控制位说明
RTR 位:显性 (0) 为数据帧,隐性 (1) 为遥控帧。
IDE 位:显性 (0) 为标准帧,隐性 (1) 为扩展帧。
DLC:4 位编码,表示 0-8 字节数据长度。
二、仲裁机制详解(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 则接收 | 可设置静默模式用于诊断,始终不发送任何电平 |