一、什么是 CAN 总线?
CAN (Controller Area Network,控制器局域网总线)由 BOSCH 公司开发,是一种简洁、高速、易扩展且可靠性极高的串行通信总线。它广泛应用于汽车电子、工业控制、嵌入式设备等领域。
CAN 总线的核心特征:
-
两线通信 :只需
CAN_H、CAN_L两条线,布线简单。 -
差分信号:抗干扰能力强,适合复杂的电磁环境。
-
高速 CAN(ISO 11898):速率 125 k ~ 1 Mbps,距离 < 40 m。
-
低速 CAN(ISO 11519):速率 10 k ~ 125 kbps,距离 < 1 km。
-
异步通信:无需时钟线,节点间约定波特率即可。
-
半双工多主结构:多个设备挂载在同一条总线上。
-
报文 ID 仲裁:11 位(标准帧)或 29 位(扩展帧)ID,既区分功能,也决定总线优先级。
-
可变数据长度:有效载荷 0 ~ 8 字节。
-
广播 + 请求:支持主动发送数据帧,也支持通过遥控帧请求数据。
-
内置可靠性机制:应答、CRC 校验、位填充、位同步、错误处理等。
二、CAN 与其他通信协议对比
| 协议 | 引脚 | 双工 | 时钟 | 电平 | 设备数量 | 典型场景 | | --- | --- | --- | --- | --- | --- | --- | | UART | TX、RX | 全双工 | 异步 | 单端 | 点对点 | 两个设备互连 | | I2C | SCL、SDA | 半双工 | 同步 | 单端 | 多设备 | 一主多从模块 | | SPI | SCK、MOSI、MISO、SS | 全双工 | 同步 | 单端 | 多设备 | 主控外挂高速模块 | | CAN | CAN_H、CAN_L | 半双工 | 异步 | 差分 | 多设备 | 多个控制器互相通信 |
CAN 最大的优势在于:多主、差分抗干扰、非破坏性仲裁、内置错误检测,这正是汽车网络所需要的。
三、硬件电路与物理层
3.1 总线拓扑
每个节点由 MCU + CAN 控制器 + CAN 收发器 组成。控制器输出 TX/RX,收发器将其转换为差分信号 CAN_H / CAN_L 后挂到总线上。
-
高速 CAN :闭环网络,总线两端必须各接 120 Ω 终端电阻,用于阻抗匹配、抑制反射。
-
低速 CAN :开环网络,在总线一端 接 2.2 kΩ 终端电阻。
-
实际布线中,CAN_H 与 CAN_L 通常采用双绞线,进一步增强抗干扰能力。
-

3.2 电平标准:隐性 vs 显性
CAN 用两根线的电压差 表示数据位,而不是单线对地电压。
高速 CAN
| 逻辑 | 名称 | 电平差 V(CAN_H - CAN_L) | | --- | --- | --- | | 1 | 隐性(Recessive) | ≈ 0 V | | 0 | 显性(Dominant) | ≈ 2 V |
典型电压值:隐性时 CAN_H = CAN_L = 2.5 V;显性时 CAN_H ≈ 3.5 V、CAN_L ≈ 1.5 V。
低速 CAN
| 逻辑 | 电平差 | | --- | --- | | 1(隐性) | ≈ -1.5 V | | 0(显性) | ≈ 3 V |
关键特性:"线与"。只要任意一个节点发送显性(0),总线就呈现显性;只有当所有节点都发隐性(1)时,总线才为隐性。这一特性是 CAN 总线仲裁的基础。
3.3 CAN 收发器
常用高速 CAN 收发器如 TJA1050 、PCA82C250 、TJA1042 等。它负责:
-
将控制器来的
TX单端信号转成差分电平发到总线; -
将总线差分电平转回
RX单端信号给控制器。
四、CAN 帧格式
4.1 五种帧类型
| 帧类型 | 用途 | | --- | --- | | 数据帧 | 节点主动发送数据(广播式) | | 遥控帧 | 节点主动请求数据(请求式) | | 错误帧 | 检测到错误时,通知其他节点并终止当前发送 | | 过载帧 | 接收方来不及处理,要求发送方暂缓 | | 帧间隔 | 分隔数据帧/遥控帧与后续帧 |
4.2 数据帧结构(标准帧 11 位 ID)
| 字段 | 长度 | 说明 | | --- | --- | --- | | SOF | 1 bit | 帧起始,显性位,标志数据开始 | | ID | 11 bit | 标识符,区分消息功能,ID 越小优先级越高 | | RTR | 1 bit | 远程请求位;数据帧为 0,遥控帧为 1 | | IDE | 1 bit | 扩展标志;0 = 标准帧,1 = 扩展帧 | | r0 | 1 bit | 保留位 | | DLC | 4 bit | 数据长度码,0 ~ 8 | | Data | 0 ~ 8 B | 实际传输的数据 | | CRC | 15 bit | 循环冗余校验 | | CRC 界 | 1 bit | CRC 结束标志 | | ACK | 1 bit | 应答位,接收方正确接收后拉低 | | ACK 界 | 1 bit | ACK 结束标志 | | EOF | 7 bit | 帧结束,7 个隐性位 |
扩展帧 :CAN 2.0B 中将 ID 扩展到 29 位,增加了 SRR 位(替代 RTR,固定为 1),并在标准帧的 r1 位置引入了 IDE 位。当标准帧 11 位 ID 与扩展帧的高 11 位 ID 相同时,标准帧优先级更高,这是通过 SRR = 1(隐性)来保证的。
4.3 遥控帧
遥控帧与数据帧结构几乎相同,但:
-
RTR = 1(隐性);
-
没有数据段;
-
用于请求总线上其他节点发送对应 ID 的数据。
4.4 位填充(Bit Stuffing)
发送方每发送 5 个相同电平 后,会自动插入一个相反电平的填充位;接收方检测到填充位后自动移除。
作用:
-
提供额外的跳变沿,帮助接收方执行再同步;
-
防止长序列无跳变导致采样失准;
-
把正常数据流与错误帧、过载帧区分开;
-
保持总线在发送正常数据时的活跃状态。
五、位时序、采样与波特率
CAN 没有时钟线,所有节点靠约定波特率工作。每个节点都按自己的时钟对总线采样。
5.1 位时序分段
一个数据位被细分为若干最小时间单位 Tq(Time Quantum),并进一步划分为:
| 段 | 长度 | 作用 | | --- | --- | --- | | SS (同步段) | 1 Tq | 期望出现跳变沿,用于同步 | | PTS (传播段) | 1 ~ 8 Tq | 补偿信号在总线上的传播延迟 | | PBS1 (相位缓冲段 1) | 1 ~ 8 Tq | 必要时延长以再同步 | | PBS2(相位缓冲段 2) | 2 ~ 8 Tq | 必要时缩短以再同步 |
采样点 通常位于 PBS1 末尾 / PBS2 起始处,即一位的中心附近。
5.2 同步机制
-
硬同步:在每一帧的 SOF 下降沿,所有接收方将自己的位时序拨到 SS 段位置。硬同步只在 SOF 处有效一次。
-
再同步 :如果后续数据位跳变沿偏离了 SS 段,接收方通过 SJW (再同步补偿宽度,1 ~ 4 Tq)延长 PBS1 或 缩短 PBS2,把采样点重新拉回中心。
5.3 波特率计算
bash
波特率 = 1 / 一个数据位的时长
= 1 / (T_SS + T_PTS + T_PBS1 + T_PBS2)
例如:SS = 1 Tq,PTS = 3 Tq,PBS1 = 3 Tq,PBS2 = 3 Tq,Tq = 0.5 μs,则:
bash
一个位 = (1+3+3+3) × 0.5 μs = 4 μs
波特率 = 1 / 4 μs = 200 kbps
在 STM32 中,位时序用 BS1、BS2 表示:
bash
波特率 = APB1 / (BRP + 1) / (1 + (TS1 + 1) + (TS2 + 1))
其中 SS = 1 Tq 固定,BS1 = TS1 + 1,BS2 = TS2 + 1。
六、总线仲裁
6.1 规则一:先占先得
如果当前已有设备在发送数据帧/遥控帧,其他设备不能同时发送数据帧/遥控帧(但可以发送错误帧/过载帧破坏当前帧)。只有当总线出现连续 11 个隐性位时,才认为总线空闲,设备才能开始发送。
6.2 规则二:非破坏性仲裁
若多个设备同时开始发送,CAN 根据 ID 逐位比较 进行仲裁。ID 越小,优先级越高。
实现仲裁依赖两个机制:
-
线与特性:任何节点发显性(0),总线就为 0;只有全发隐性(1)时总线才为 1。
-
回读机制:每个节点发完一位后都会读回总线电平。如果发的是 1,读回却是 0,说明优先级更高的节点发了 0,该节点自动退出竞争,转为接收。
因为仲裁不会破坏已经发出的数据,所以称为非破坏性仲裁。
6.3 优先级补充规则
-
同 ID 时:数据帧优先级高于遥控帧(RTR = 0 vs 1)。
-
标准帧 vs 扩展帧 :当标准帧 11 位 ID 与扩展帧高 11 位 ID 相同时,标准帧优先级更高(由
SRR = 1保证)。
七、错误处理
7.1 五种错误类型
| 错误类型 | 说明 | | --- | --- | | 位错误 | 发送方读回的总线电平与发送的不一致(仲裁期间除外) | | 填充错误 | 违反位填充规则(连续 6 个相同位) | | CRC 错误 | 接收方 CRC 计算结果与发送方不一致 | | 格式错误 | 固定格式位(如帧间隔、ACK 界等)不符合规定 | | ACK 错误 | 发送方在 ACK 位未收到显性应答 |
7.2 三种错误状态
每个节点通过两个计数器 TEC (Transmit Error Counter)和 REC(Receive Error Counter)管理自身状态:
| 状态 | 条件 | 行为 | | --- | --- | --- | | 主动错误 | TEC < 128 且 REC < 128 | 正常通信,检测到错误时发送主动错误帧(6 个显性位) | | 被动错误 | TEC ≥ 128 或 REC ≥ 128 | 仍可通信,但只能发送被动错误帧(6 个隐性位) | | 总线关闭 | TEC > 255 | 退出总线通信,需恢复过程 |
7.3 离线恢复
STM32 中 ABOM 位控制离线恢复:
-
ABOM = 1:进入总线关闭后自动进入恢复过程; -
ABOM = 0:软件需先请求进入再退出初始化模式,才会开始恢复。
八、STM32 bxCAN 外设应用
8.1 资源概览
STM32 内置 bxCAN 控制器,支持 CAN 2.0A/B,最高 1 Mbps。典型资源(以 STM32F103C8T6 为例):
-
3 个发送邮箱(带可配置优先级);
-
2 个接收 FIFO,每个 3 级深度;
-
14 个过滤器组(互联型为 28 个);
-
支持时间触发通信、自动离线恢复、自动唤醒、禁止自动重传、双 CAN 模式等。
8.2 发送与接收流程
发送流程:选择一个空邮箱 → 写入报文 → 请求发送。
接收流程:接收到报文 → 经过过滤器匹配 → 进入 FIFO 0 或 FIFO 1 → CPU 读取。
8.3 关键配置位
| 位 | 置 1 | 置 0 | | --- | --- | --- | | NART | 禁止自动重传,只发一次 | 发送失败自动重传直到成功 | | TXFP | 发送优先级按请求顺序 | 发送优先级按 ID 大小 | | RFLM | FIFO 溢出时丢弃新报文 | FIFO 溢出时覆盖最后一条 |
8.4 标识符过滤器
每个过滤器由两个 32 位寄存器 R1[31:0]、R2[31:0] 组成,可配置为:
-
FSCx(位宽):0 = 16 位,1 = 32 位;
-
FBMx(模式):0 = 屏蔽模式(Mask),1 = 列表模式(List);
-
FFAx(关联):0 = 关联 FIFO 0,1 = 关联 FIFO 1;
-
FACTx(激活):0 = 禁用,1 = 启用。
列表模式 :精确匹配若干 ID。 屏蔽模式 :用 ID + Mask 匹配一段 ID 范围。
注意:ID 写入寄存器时通常需要左移(标准 ID 左移 21,扩展 ID 左移 3 等),具体规则需参考 STM32 参考手册。
8.5 测试模式
| 模式 | 作用 | | --- | --- | | 静默模式 | 监听总线,不影响总线,用于分析 | | 环回模式 | 自测试,发送的报文可从 TX 引脚检测到 | | 环回静默模式 | 热自测试,不影响总线 |
8.6 工作模式
-
初始化模式:配置 CAN 外设,禁止收发;
-
正常模式:配置完成后进入,正常收发;
-
睡眠模式 :低功耗,
AWUM = 1时检测到总线活动自动唤醒,AWUM = 0需软件唤醒。
8.7 中断
bxCAN 占用 4 个中断向量:
-
发送中断:发送邮箱空;
-
FIFO 0 中断:收到报文 / FIFO 满 / FIFO 溢出;
-
FIFO 1 中断:收到报文 / FIFO 满 / FIFO 溢出;
-
状态/错误/唤醒/睡眠中断。
8.8 时间触发通信(TTCM)
使能 TTCM 后,bxCAN 内置一个 16 位计数器,每个 CAN 位时间自增一次。发送帧 SOF 时捕获计数值到发送邮箱的 TIME 寄存器;接收帧 SOF 时捕获到接收 FIFO 的 TIME 寄存器。若使能 TGT 且 DLC = 8,时间戳还会被写入数据段最后两个字节。
九、小结
| 知识点 | 一句话总结 | | --- | --- | | 物理层 | 两线差分,显性 0 / 隐性 1,终端电阻匹配 | | 帧格式 | 标准 11 位 ID / 扩展 29 位 ID,数据帧含 0~8 B 数据 | | 位时序 | SS + PTS + PBS1 + PBS2,采样点对齐中心 | | 仲裁 | ID 越小优先级越高,显性覆盖隐性,非破坏性 | | 错误处理 | 5 种错误、3 种状态、TEC/REC 计数器 | | STM32 | bxCAN 自动收发、过滤器、FIFO、中断、时间戳 |
CAN 总线之所以能成为汽车电子的事实标准,核心在于它在物理层、数据链路层、错误处理层都做了完整而简洁的设计。理解了"差分电平、非破坏性仲裁、位时序、错误状态机"这几个关键点,再看任何车载网络或 STM32 CAN 代码都会事半功倍。
十、补充AutoSAR架构下的CAN通信
