通信协议篇四:CAN 总线原理与通信机制基础详解

CAN(Controller Area Network,控制器局域网)是 Bosch 在 1980 年代提出的一种高可靠串行总线。它采用差分传输,支持多主通信,通过报文 ID 完成仲裁,并带有较完整的错误检测机制。

ℹ️ 本文范围:本文主要介绍经典 CAN。文中会顺带提到 CAN FDCAN 2.0A / 2.0B,但重点仍然是基础概念、帧格式、仲裁和同步机制。

1. 特点与应用背景

CAN 的几个典型特点:

  • 差分传输:抗干扰能力强
  • 多主通信:多个节点可共享同一总线
  • 优先级仲裁:通过报文 ID 决定先发谁
  • 错误检测较完整:有 CRC、ACK、位填充、帧检查等机制

常见场景有汽车电子、工业控制、医疗设备等。


2. 先分清几组常见说法

  • 经典 CAN(Classical CAN):单帧数据最长 8 字节
  • CAN FD(Flexible Data-Rate):支持更长数据段和更高数据阶段速率
  • CAN 2.0A / 2.0B:常见旧写法;通常可理解为 2.0A 主要对应 11 位标准帧2.0B 支持 29 位扩展帧
⚠️ 注意标准帧 / 扩展帧 说的是 ID 长度;经典 CAN / CAN FD 说的是协议发展阶段,这两组概念不要混在一起。

3. CAN 的核心概念

概念 含义 重点记忆
标准帧 11 位 ID 常见、开销更小
扩展帧 29 位 ID 可表示更多报文类型
显性位 逻辑 0 仲裁里更“强”
隐性位 逻辑 1 遇到显性位会失败
ACK 应答位 至少有一个节点正确接收才会响应
滤波器 决定接收哪些 ID 提高处理效率
FIFO 接收缓存队列 常用 FIFO0 / FIFO1
Mailbox 发送邮箱 发送缓存单元

4. CAN 数据帧格式

经典 CAN 中,标准数据帧最常见,可简化理解为:

SOF -> ID -> RTR -> IDE -> r0 -> DLC -> DATA -> CRC -> ACK -> EOF

CAN数据帧格式
CAN数据帧格式

4.1 标准数据帧字段总览

字段 英文全称 位数 主要作用 关键说明
SOF Start of Frame 1 帧起始 1 位显性位,表示一帧开始
ID Identifier 11 标识报文并参与仲裁 ID 越小,优先级越高
RTR Remote Transmission Request 1 区分数据帧与远程帧 0=数据帧,1=远程帧
IDE Identifier Extension 1 区分标准帧与扩展帧 标准帧中该位用于标识标准格式
r0 Reserved Bit 1 保留位 经典 CAN 中通常保留
DLC Data Length Code 4 表示数据长度 经典 CAN 取值 0~8
DATA Data Field 0~8 字节 有效载荷 真正需要传输的数据内容
CRC Cyclic Redundancy Check 15+1 差错检测 含 CRC 序列和 CRC 界定符
ACK Acknowledge 1+1 接收确认 接收方在当前帧里的位级回应;至少 1 个节点正确收到后,会在 ACK Slot 把总线拉成显性位
EOF End of Frame 7 帧结束 7 位隐性位,表示该帧结束

4.2 常见帧类型

帧类型 含义 说明
数据帧 真正承载数据 最常用
远程帧 请求对方发送数据 自己不带数据
错误帧 节点检测到通信错误时发出 用于通知本次通信无效
过载帧 用于延迟下一帧发送 基础阶段了解即可

4.3 看一帧报文先看什么

平时看报文,通常先看这 3 个字段:

  • ID:表示报文类型,也决定优先级
  • DLC:表示数据长度
  • DATA:实际数据内容

扩展帧的基本思路和标准帧一致,只是把 ID11 位扩展到 29 位。它只是 ID 更长不等于 CAN FD


5. CAN 的基础硬件认识

5.1 CAN 控制器与 CAN 收发器

模块 作用
CAN 控制器 组帧、仲裁、错误检测、滤波、收发缓存管理
CAN 收发器 在 MCU 逻辑电平和 CAN 差分信号之间做转换

很多 MCU 只集成 CAN 控制器,不包含物理层收发器,所以接实际总线时通常还要外接 CAN 收发器。

CAN总线收发模块
CAN总线收发模块

常见收发器:

  • TJA1050
  • MCP2551
  • SN65HVD230

5.2 总线连接方式

CAN总线连接示意图
CAN总线连接示意图

MCU(CAN_TX/CAN_RX)
       │
       ▼
  CAN 收发器
       │
  CAN_H   CAN_L
       │
  ===== 总线 =====

总线两端通常各接一个 120Ω 终端电阻,作用主要是:

  • 阻抗匹配
  • 抑制信号反射
  • 提高信号完整性
💡 一句话记忆

两端各 120Ω,中间节点一般不加。

6. CAN 为什么能自动分优先级

CAN 的关键机制是仲裁

6.1 显性位、隐性位与线与效果

在 CAN 总线上:

  • 显性位 = 0
  • 隐性位 = 1

它在逻辑效果上类似线与:

  • 只要有节点发显性位 0,总线就是显性位 0
  • 只有所有节点都发隐性位 1,总线才是隐性位 1

直接记:0 会覆盖 1

6.2 发送并回读

CAN 节点发送时会边发边回读总线

如果某个节点:

  • 自己发的是隐性位 1
  • 回读到的却是显性位 0

就说明别的节点优先级更高,当前节点立即退出仲裁。

6.3 为什么 ID 越小优先级越高

ID 是逐位参与仲裁的,而仲裁依赖:

  • 显性位 0 会覆盖隐性位 1
  • 节点会实时回读总线状态

所以更早出现显性位 0 的报文更容易保住仲裁权。

例如:

  • 0x100 优先级高于 0x200
  • ID 数值越小,优先级越高

6.4 什么叫非破坏性仲裁

多个节点同时发时:

  • 胜出的节点继续正常发送
  • 失败的节点立即退出
  • 已发出的有效位流不会被破坏

这就是非破坏性仲裁

💡 记忆口诀

谁先保住显性位,谁继续发;谁发隐性却读到显性,谁退出。

7. 相关概念:位填充、错误状态、滤波器

7.1 同步与位填充

CAN 没有独立时钟线,节点只能靠各自本地时钟工作。若一帧里长期没有电平跳变,采样点就可能慢慢漂移。

所以 CAN 要解决两个问题:

  1. 一帧开始时先对齐时间基准
  2. 传输过程中如果有漂移,还要继续修正

对应机制:

  • 硬同步:通常在检测到 SOF 边沿时进行
  • 再同步:后续检测到边沿时继续微调采样点
  • 位填充:连续 5 个相同位后,自动插入 1 个相反位,用来制造边沿

位填充规则被破坏,就会判定为 Stuff Error

💬 一句话对比:I2C 靠时钟线,CAN 靠边沿,USART 靠波特率。

7.2 错误状态

CAN 节点会根据错误计数器进入不同状态:

  • Error Active:正常工作,能主动报错
  • Error Passive:还能通信,但行为受限
  • Bus-Off:错误太多,被强制退出总线

这样可以避免异常节点一直拖垮整条总线。

7.3 滤波器

CAN 是广播式通信,总线上所有节点都能看到报文,但并不是所有报文都要处理。

所以 MCU 通常会用滤波器筛选自己关心的 ID,例如:

  • 只接收 0x123
  • 只接收某一类 ID 范围

8. CAN 的优点与局限

8.1 优点

  • 抗干扰强
  • 多节点共享总线
  • 自带优先级仲裁
  • 错误检测机制较完整
  • 可靠性高,适合工业与汽车场景

8.2 局限

  • 经典 CAN 单帧数据只有 8 字节
  • 速率和距离存在权衡
  • 调试门槛高于 UART
  • 工程上还要考虑收发器、终端电阻、滤波器、波特率等问题

9. 常见问题整理

9.1 CAN 和 UART / SPI / I2C 的区别

CAN 不追求最简单,也不追求最高速,重点是高可靠、多主通信和仲裁机制

9.2 120Ω 终端电阻的作用

作用就是阻抗匹配,减少反射,保证信号完整性,所以总线两端通常各接一个 120Ω 电阻。

9.3 为什么适合汽车和工业控制

因为它同时有:

  • 差分传输带来的抗干扰能力
  • 多主仲裁带来的实时性
  • 错误检测机制带来的可靠性

10. 速记版

📋 速记

  • 物理层CAN_H / CAN_L 差分信号
  • 硬件结构:CAN 控制器 + CAN 收发器 + 两端 120Ω
  • 优先级规则:ID 越小,优先级越高
  • 经典 CAN 数据长度:最大 8 字节
  • ACK:接收方在当前帧里的位级回应,不是额外再回一帧
  • 同步方式:靠边沿,不靠独立时钟线
  • 核心可靠性来源:差分传输 + 仲裁机制 + CRC / ACK / 位填充

STM32 配置、接线、代码、中断和调试内容可单独整理为 CAN 实战篇。