CAN 技术系列 03 · CAN 位定时与同步

📚 CAN总线技术系列 · 持续更新中

本系列从差分电气层一路打到 Linux SocketCAN,把"两根线"背后的电气/协议/控制器/驱动/实战全拧成一根线。

👉 想系统追更,戳这里查看完整专栏:

【CAN 技术系列】

👉 其他技术系列专栏,欢迎关注、交流、共同成长:

【SPI 技术系列】 【I2C 技术系列】 【串口技术系列】【RISC-V 架构系列】【Linux内核系列】 【操作系统设计思想系列】 【 Android 系统全景专栏】


03 · CAN 位定时与同步

本篇定位 :CAN 物理层和拓扑讲完,本篇讲位定时------CAN 的灵魂。CAN 是同步总线(位填充维持跳变),但没有共享时钟线 (不像 SPI/I2C),靠硬同步 + 重同步对齐。采样点、SJW、时钟容差配错,全网通信失败。本篇讲位时间组成、采样点、同步机制、BTR 寄存器配置。读完你能配任何 CAN 控制器的位定时。
位定时是 CAN 配错必死项

UART 异步,波特率配对就行。SPI/I2C 有共享时钟,主控速度。CAN 没有共享时钟,所有节点靠位定时参数各自同步,采样点/SJW/时钟容差必须全网一致 + 满足约束。配错一个节点,全网通信失败。这是 CAN 调试第二大坑(终端电阻第一)。做 CAN 网络,位定时必须算清。


目录

  • [03 · CAN 位定时与同步](#03 · CAN 位定时与同步)
  • 一、位时间组成
    • [1.1 位时间分段](#1.1 位时间分段)
    • [1.2 总位时间](#1.2 总位时间)
    • [1.3 Tq 计算](#1.3 Tq 计算)
  • 二、采样点
    • [2.1 采样点定义](#2.1 采样点定义)
    • [2.2 采样点推荐](#2.2 采样点推荐)
    • [2.3 采样点为何要靠后](#2.3 采样点为何要靠后)
    • [2.4 多采样(可选)](#2.4 多采样(可选))
  • 三、同步机制
    • [3.1 为什么需要同步](#3.1 为什么需要同步)
    • [3.2 硬同步(Hard Sync)](#3.2 硬同步(Hard Sync))
    • [3.3 重同步(Resync)](#3.3 重同步(Resync))
    • [3.4 同步规则](#3.4 同步规则)
    • [3.5 同步的物理意义](#3.5 同步的物理意义)
  • 四、SJW(同步跳转宽度)
    • [4.1 SJW 定义](#4.1 SJW 定义)
    • [4.2 SJW 工作原理](#4.2 SJW 工作原理)
    • [4.3 SJW 选择](#4.3 SJW 选择)
    • [4.4 SJW 与时钟容差](#4.4 SJW 与时钟容差)
  • 五、时钟容差
    • [5.1 时钟容差来源](#5.1 时钟容差来源)
    • [5.2 时钟容差约束](#5.2 时钟容差约束)
    • [5.3 典型容差](#5.3 典型容差)
    • [5.4 选晶振](#5.4 选晶振)
  • [六、BTR 寄存器配置](#六、BTR 寄存器配置)
    • [6.1 STM32 bxCAN BTR](#6.1 STM32 bxCAN BTR)
    • [6.2 配置示例:1Mbit/s, SP 87.5%, f_CAN=42MHz](#6.2 配置示例:1Mbit/s, SP 87.5%, f_CAN=42MHz)
    • [6.3 配置口诀](#6.3 配置口诀)
    • [6.4 DesignWare/M_CAN 位定时](#6.4 DesignWare/M_CAN 位定时)
  • [七、CAN FD 位定时](#七、CAN FD 位定时)
    • [7.1 两套位定时](#7.1 两套位定时)
    • [7.2 NBTP(标称位定时)](#7.2 NBTP(标称位定时))
    • [7.3 DBTP(数据位定时)](#7.3 DBTP(数据位定时))
    • [7.4 FD 位定时约束](#7.4 FD 位定时约束)
    • [7.5 FD 配置示例](#7.5 FD 配置示例)
  • [八、关键问题 Q&A](#八、关键问题 Q&A)
    • [Q1:采样点 87.5% 怎么算?](#Q1:采样点 87.5% 怎么算?)
    • [Q2:CAN 没有共享时钟,怎么同步?](#Q2:CAN 没有共享时钟,怎么同步?)
    • [Q3:SJW 配多大?](#Q3:SJW 配多大?)
    • Q4:时钟容差怎么满足?
    • Q5:位定时配错会怎样?
    • [Q6:CAN FD 数据段位定时怎么配?](#Q6:CAN FD 数据段位定时怎么配?)
  • 九、实战案例
    • [案例 1:采样点不一致,通信失败](#案例 1:采样点不一致,通信失败)
    • [案例 2:时钟偏差大,偶发错](#案例 2:时钟偏差大,偶发错)
    • [案例 3:SJW 太小,长帧错](#案例 3:SJW 太小,长帧错)
    • [案例 4:采样点太前,长总线错](#案例 4:采样点太前,长总线错)
    • [案例 5:CAN FD 数据段 CRC 错](#案例 5:CAN FD 数据段 CRC 错)
    • [案例 6:晶振温漂,低温通信失败](#案例 6:晶振温漂,低温通信失败)
    • [案例 7:BRP 算错,波特率不对](#案例 7:BRP 算错,波特率不对)
    • [案例 8:多节点位定时不一致](#案例 8:多节点位定时不一致)
  • 十、本篇小结与速查

一、位时间组成

1.1 位时间分段

CAN 一个位时间(Time Quantum, Tq)分四段:

复制代码
┌──────────┬─────────────────┬──────────────┐
│ SYNC_SEG │   TSEG1(PTS+    │   TSEG2      │
│ (同步段) │   PBS1)         │   (PBS2)     │
│ 1 Tq     │   1~16 Tq       │   1~8 Tq     │
└──────────┴─────────────────┴──────────────┘
           ↑采样点(SP)
段 含义 Tq 数
SYNC_SEG 同步段(跳变应在此时) 1
TSEG1 时间段1(传播 + 相位缓冲1) 1~16
TSEG2 时间段2(相位缓冲2) 1~8
  • SYNC_SEG:期望信号跳变发生在这(1 Tq)
  • TSEG1:采样前的时间(含传播延迟 + 相位调整)
  • TSEG2:采样后的时间(相位调整)
  • 采样点在 TSEG1/TSEG2 交界

1.2 总位时间

复制代码
位时间 = SYNC_SEG + TSEG1 + TSEG2 = (1 + TSEG1 + TSEG2) Tq
  • 典型位时间:16~25 Tq(采样点 75~87.5%)
  • Tq = CAN 时钟 / 分频

1.3 Tq 计算

复制代码
Tq = 1 / (f_CAN / BRP) = BRP / f_CAN
  • f_CAN:CAN 控制器输入时钟(如 40MHz)
  • BRP:波特率预分频(BTR 寄存器配)

二、采样点

2.1 采样点定义

采样点(Sample Point, SP)= 在位时间内的位置(百分比):

复制代码
SP = (1 + TSEG1) / (1 + TSEG1 + TSEG2) × 100%
  • 采样点在 TSEG1 末尾(TSEG2 开始)
  • 采样点越后,留给传播延迟的时间越多

2.2 采样点推荐

标准/协议 推荐采样点
CAN 2.0 75~87.5%
CANopen 87.5%
DeviceNet 87.5%
J1939 87.5%(高速)/ 85%(低速)
ARINC 825 75~80%
  • 87.5% 是主流(CANopen/J1939/DeviceNet)
  • 例:16 Tq 位时间,SP 87.5% → TSEG1=13, TSEG2=2

2.3 采样点为何要靠后

  • 传播延迟(信号从一节点到另一节点往返)占位时间一部分
  • 采样点靠后,留够传播延迟时间
  • 高速 + 长总线,采样点更要靠后(87.5%)

2.4 多采样(可选)

  • 部分控制器支持 3 采样(采 TSEG1 末 + 前两 Tq,多数表决)
  • 抗扰更好,但减少传播延迟裕量
  • 一般不用(单采样够)

三、同步机制

3.1 为什么需要同步

  • CAN 没有共享时钟(不像 SPI/I2C)
  • 各节点时钟独立(晶振),有偏差
  • 靠信号跳变(位填充保证跳变密度)同步

3.2 硬同步(Hard Sync)

  • **帧起始(SOF)**时,所有节点收到跳变,重置位定时到 SYNC_SEG

  • 每帧开始同步一次

  • SOF 是显性位(从隐性跳显性),所有节点看到

    隐性 ──↓ SOF(显性)── 所有节点硬同步,位定时归 SYNC_SEG

3.3 重同步(Resync)

  • 帧中间,信号跳变(位填充保证)用来微调相位

  • 跳变比期望早或晚 → 调整 TSEG1 或 TSEG2 长度

    期望跳变在 SYNC_SEG:
    跳变早(TSEG1 还没到)→ TSEG1 延长(最多 SJW)
    跳变晚(TSEG1 过了)→ TSEG2 缩短(最多 SJW)

3.4 同步规则

  • 只有隐性→显性跳变触发重同步(显性→隐性不触发)
  • 位填充保证最多 5 位有跳变(足够同步)
  • SOF 硬同步 + 帧中重同步 = 全程同步

3.5 同步的物理意义

  • 抵消节点间时钟偏差(晶振不完全一致)
  • 抵消传播延迟(信号到达各节点时刻不同)
  • 保证采样点对齐(各节点同时采样)

四、SJW(同步跳转宽度)

4.1 SJW 定义

  • 重同步时,TSEG1/TSEG2 可调整的最大量
  • SJW = 1~4 Tq
  • 太小:无法补偿时钟偏差
  • 太大:过度调整,振荡

4.2 SJW 工作原理

复制代码
跳变比期望早 3 Tq,SJW=2:
  → TSEG1 只能延长 2 Tq(SJW 限制),剩余 1 Tq 误差累积
跳变比期望晚 1 Tq,SJW=2:
  → TSEG2 缩短 1 Tq(在 SJW 内),完全补偿

4.3 SJW 选择

  • SJW = min(TSEG1, TSEG2, 4) 通常
  • 经验:SJW = TSEG2 / 2 或固定 1~2 Tq
  • 时钟偏差大,SJW 适当大;但不超过 TSEG2

4.4 SJW 与时钟容差

  • SJW 决定能补偿的最大时钟偏差
  • 时钟偏差 > SJW 能补偿 → 同步失败,通信错

五、时钟容差

5.1 时钟容差来源

  • 晶振初始偏差(±50ppm)
  • 温度漂移(±50ppm)
  • 老化(±50ppm)
  • 总计:可达 ±100~200ppm(差晶振),好晶振 ±20~50ppm

5.2 时钟容差约束

CAN 协议规定时钟容差上限:

复制代码
df < min(
  SJW / (20 × NBT),          // 重同步能力
  (1 - SP) / (2 × (13 + SP)), // 13 位累积偏差(填充前)
  SP / (2 × (14 - SP))        // 14 位累积偏差(填充后)
)
  • NBT:位时间 Tq 数(1+TSEG1+TSEG2)
  • SP:采样点(小数,如 0.875)
  • 三者取最小,就是允许的时钟容差

5.3 典型容差

配置 容差
1M, 16Tq, SP87.5%, SJW=2 0.5%(5000ppm)
500k, 16Tq, SP87.5%, SJW=2 0.5%
125k, 16Tq, SP87.5%, SJW=2 0.5%
  • 一般配置容差 0.10.5%(10005000ppm)
  • 普通晶振(±50ppm)远满足
  • 容差太严(SJW 小/位时间短)要选好晶振

5.4 选晶振

  • 普通 CAN:±50ppm 晶振够
  • 高速短位时间(1M, 8Tq):选 ±20ppm 晶振
  • 严禁 RC 振荡器(偏差 1%+)

六、BTR 寄存器配置

6.1 STM32 bxCAN BTR

复制代码
CAN_BTR:
bit 25-24 SJW[1:0]:  同步跳转宽度(0~3,值+1)
bit 22-16 TS2[6:0]:  TSEG2(0~7,值+1)
bit 15-0  TS1[3:0]:  TSEG1(0~15,值+1)  (注意位段,实际 TS1 4bit)
bit 9-0   BRP[9:0]:  波特率预分频(0~1023,值+1)

6.2 配置示例:1Mbit/s, SP 87.5%, f_CAN=42MHz

复制代码
位时间 = 42MHz / 1Mbit/s = 42 Tq
但要 TSEG1+TSEG2+1 ≤ 25(STM32 限制),要分频:
BRP = 3, Tq = 3/42MHz = 71.4ns
位时间 Tq 数 = 1Mbit/s 周期 / Tq = 1000ns / 71.4ns ≈ 14 Tq

NBT = 14:
SP 87.5% → TSEG1 = 12, TSEG2 = 1, SYNC=1 → 1+12+1=14 ✓
SP = 13/14 = 92.8%(过高)

重算 NBT=16(更标准):
BRP=2.625(非整数,不行)

换 f_CAN=48MHz:
BRP=3, Tq=62.5ns, NBT=16
SP 87.5% → TSEG1=13, TSEG2=2, 1+13+2=16
SP = 14/16 = 87.5% ✓

BTR = SJW=1(00) | TS2=1(2-1=1) | TS1=12(13-1=12) | BRP=2(3-1=2)

6.3 配置口诀

  1. 算 Tq 数:NBT = f_CAN / (BRP × bit_rate)
  2. 选 BRP 让 NBT 在 16~25(采样点好调)
  3. 按 SP 算 TSEG1/TSEG2:TSEG1 = NBT × SP - 1(取整)
  4. SJW 选 1~2
  5. 写 BTR

6.4 DesignWare/M_CAN 位定时

  • Bosch M_CAN 用 NBTP(标称位定时)/ DBTP(数据位定时 FD)
  • 字段:TSEG1/TSEG2/SJW/BRP,逻辑同 STM32

七、CAN FD 位定时

7.1 两套位定时

CAN FD 仲裁段和数据段速率不同,两套位定时:

段 速率 位定时
仲裁段 1M(兼容) NBTP(标称)
数据段 5M/8M DBTP(数据)

7.2 NBTP(标称位定时)

  • 和经典 CAN 一样
  • 仲裁段 + CRC 之前 + ACK 之后
  • SP 87.5%,1M

7.3 DBTP(数据位定时)

  • 数据段(BRS 后到 CRC 前)用
  • 5M/8M,位时间短
  • 采样点可以不同(通常也 75~87.5%)
  • TSEG1/TSEG2 数值小(短位时间)

7.4 FD 位定时约束

  • 数据段速率高,传播延迟约束严
  • 5M 位时间 200ns,传播延迟要 < 50ns(约 10m 总线)
  • 8M 位时间 125ns,总线更短
  • SJW 数据段通常 1~2 Tq

7.5 FD 配置示例

复制代码
仲裁段(NBTP):1M, SP87.5%, f_CAN=80MHz
  BRP=5, NBT=16, TSEG1=13, TSEG2=2, SJW=2

数据段(DBTP):5M, SP80%, f_CAN=80MHz
  BRP=2, NBT=8, TSEG1=5, TSEG2=2, SJW=1
  (5M 位时间 200ns,8 Tq × 25ns)

嵌入式视角:FD 位定时是升级难点

升 CAN FD,位定时要配两套(NBTP + DBTP)。数据段 5M 位时间 200ns,容差极小,总线要短(< 10m),收发器要 FD,采样点要算准。配错数据段 CRC 错。M_CAN,DBTP 寄存器配数据段位定时。


八、关键问题 Q&A

Q1:采样点 87.5% 怎么算?

A :SP = (1 + TSEG1) / (1 + TSEG1 + TSEG2)。NBT=16,SP 87.5%:TSEG1=13, TSEG2=2 → (1+13)/16 = 14/16 = 87.5%。采样点靠后(87.5%)留传播延迟裕量,主流推荐(CANopen/J1939)。

Q2:CAN 没有共享时钟,怎么同步?

A :硬同步 + 重同步。① 硬同步:每帧 SOF(隐性→显性跳变),所有节点位定时归 SYNC_SEG。② 重同步:帧中位填充保证跳变,跳变早晚调整 TSEG1/TSEG2(最多 SJW)。两者抵消时钟偏差 + 传播延迟。

Q3:SJW 配多大?

A :1~2 Tq 通常,不超过 TSEG2。SJW = min(TSEG1, TSEG2, 4)。时钟偏差大 SJW 适当大,但太大过度调整振荡。经验:SJW = TSEG2 / 2 或固定 2 Tq。

Q4:时钟容差怎么满足?

A :选好晶振 。CAN 协议容差通常 0.10.5%(10005000ppm),普通晶振 ±50ppm 远满足。严禁 RC 振荡器(偏差 1%+)。高速短位时间(1M,8Tq)容差严,选 ±20ppm 晶振。

Q5:位定时配错会怎样?

A :全网通信失败 (采样错位,误码)。配错的节点发的帧别人采错(可能 ACK 错),收的帧自己采错。位定时必须全网一致 + 满足传播延迟/时钟容差约束。这是 CAN 调试第二大坑(终端电阻第一)。

Q6:CAN FD 数据段位定时怎么配?

A :两套位定时(NBTP 仲裁段 + DBTP 数据段)。数据段 5M,位时间 200ns,NBT 小(8 Tq),SP 75~80%,SJW 1~2。数据段传播延迟约束严(总线 < 10m @ 5M)。配错数据段 CRC 错,仲裁段正常。


九、实战案例

案例 1:采样点不一致,通信失败

现象:两节点 CAN 通信失败,各自单测正常。

分析:节点 A 采样点 75%,节点 B 87.5%,互相采样错位。

解决:统一采样点 87.5%(重配 BTR),通信正常。

案例 2:时钟偏差大,偶发错

现象:某节点用 RC 振荡器(偏差 1%),CAN 偶发错。

分析:RC 偏差 10000ppm,超 CAN 容差(5000ppm),重同步跟不上。

解决:换晶振(±50ppm),通信稳定。

案例 3:SJW 太小,长帧错

现象:8 字节帧正常,长帧(连续多帧)偶发错。

分析:SJW=1 Tq,补偿能力弱,长帧累积偏差超 SJW。

解决:SJW 加到 2 Tq,长帧稳定。

案例 4:采样点太前,长总线错

现象:100m 总线 500k,采样点 75%,偶发错。

分析:采样点 75%,传播延迟裕量小,100m 往返延迟超裕量。

解决:采样点改 87.5%,传播延迟裕量大,稳定。

案例 5:CAN FD 数据段 CRC 错

现象:CAN FD 仲裁段正常,数据段 5M 偶发 CRC 错。

分析:DBTP 配错(采样点 70%),数据段位时间 200ns,采样窗口窄。

解决:DBTP 重配,采样点 80%,TSEG1/TSEG2 重新算,5M 稳定。

案例 6:晶振温漂,低温通信失败

现象:CAN 通信常温正常,-40°C 低温通信失败。

分析:晶振低温漂移到 +100ppm,超容差(配的 SJW 小)。

解决:换宽温晶振(±30ppm 全温),或加大 SJW。

案例 7:BRP 算错,波特率不对

现象:配 500kbit/s,实测 250kbit/s。

分析:BRP 寄存器值 = 实际分频 - 1(STM32),代码写 BRP=4 当成 4 分频,实际 5 分频。

解决:BRP 寄存器写 3(4-1),实际 4 分频,波特率正确。

案例 8:多节点位定时不一致

现象:5 节点 CAN,某节点加入后全网通信失败。

分析:该节点 BTR 配错(TSEG1 差 1),采样点不一致。

解决:所有节点统一 BTR 配置(相同 f_CAN + 相同 BRP/TSEG1/TSEG2/SJW),全网一致。


十、本篇小结与速查

核心要点

  • 位时间 = SYNC_SEG(1 Tq) + TSEG1(1~16) + TSEG2(1~8)
  • 采样点 SP = (1+TSEG1)/(1+TSEG1+TSEG2),主流 87.5%
  • 同步:硬同步(SOF 重置)+ 重同步(帧中跳变调整 TSEG1/TSEG2)
  • SJW(同步跳转宽度):1~4 Tq,重同步调整量上限,通常 1~2
  • 时钟容差:协议限 0.1~0.5%,选 ±50ppm 晶振(严禁 RC)
  • BTR 配置:算 NBT → 选 BRP → 按 SP 算 TSEG1/TSEG2 → 选 SJW
  • CAN FD 两套位定时:NBTP(仲裁段1M)+ DBTP(数据段5M/8M)
  • 位定时必须全网一致 + 满足传播延迟/时钟容差约束

位定时速查(f_CAN=48MHz)

速率 BRP NBT TSEG1 TSEG2 SJW SP
1M 3 16 13 2 2 87.5%
500k 6 16 13 2 2 87.5%
250k 12 16 13 2 2 87.5%
125k 24 16 13 2 2 87.5%
50k 60 16 13 2 2 87.5%

BTR 配置步骤

  1. 算 NBT = f_CAN / (BRP × bit_rate),选 BRP 让 NBT=16
  2. TSEG1 = NBT × SP - 1 = 16 × 0.875 - 1 = 13
  3. TSEG2 = NBT - 1 - TSEG1 = 16 - 1 - 13 = 2
  4. SJW = 2(通常)
  5. BTR = (SJW-1)<<24 | (TSEG2-1)<<16 | (TSEG1-1)<<0 | (BRP-1)

CAN FD 双位定时

  • NBTP(仲裁段):同经典,1M, SP87.5%
  • DBTP(数据段):5M/8M, NBT小(8), SP75~80%, SJW=1

检查清单

  • 全网位定时一致(BRP/TSEG1/TSEG2/SJW)
  • 采样点 87.5%(主流)
  • SJW 1~2 Tq
  • 晶振 ±50ppm 以内(禁 RC)
  • 传播延迟满足(总线长度)
  • FD 两套位定时(NBTP + DBTP)

延伸阅读

  • \[01-CAN物理层与差分电气] ------ 位填充维持同步
  • \[02-CAN信号完整性与拓扑] ------ 传播延迟与总线长
  • \[04-CAN帧格式] ------ SOF 同步
  • \[08-CAN控制器寄存器与IP架构] ------ BTR 寄存器
  • \[13-CAN调试与排查] ------ 位定时问题排查
  • \[03-SPI速度与电气约束] ------ 对比 SPI 采样窗口

参考资料

  • Bosch CAN Specification 2.0(位定时章节)
  • CiA 301(CANopen 位定时推荐)
  • STM32 RM0090(CAN BTR 章节)
  • Bosch M_CAN User Manual(NBTP/DBTP)

CAN 技术系列 00 · 总目录 · 上一篇:\[02-CAN信号完整性与拓扑] · 下一篇:\[04-CAN帧格式]


✨ 感谢你的阅读 ✨

技术之路漫漫,分享是为了更好地交流。

如果本文的内容对你有启发,希望能得到你的支持:

👍 点赞 | ⭐ 收藏 | 👀 关注

如果你在调试过程中遇到了其他问题,

欢迎在 评论区 💬 留言,我们一起探讨。

关注我,一起交流底层开发的那些事儿!🚀


相关推荐
晓蛋14 小时前
嵌入式开发中的C语言特性
嵌入式开发·陷阱·编程技巧·缺陷·c语言特性
硅基手札1 天前
操作系统设计思想系列 11 · ThreadX 深度 — 预抢占阈值·认证型设计
操作系统·开源项目·嵌入式开发·嵌入式操作系统·设计思想·threadx
硅基手札2 天前
操作系统设计思想系列 10 · VxWorks 深度 — 硬实时旗舰·完全抢占内核
操作系统·实时操作系统·嵌入式开发·vxworks·设计思想
硅基手札2 天前
Android 系统全景专栏 00 · 总目录
android·操作系统·嵌入式开发
硅基手札4 天前
操作系统设计思想系列 05 · RTOS 核心矛盾 — 资源受限 × 时间确定性的设计决策树
linux·mcu·架构·操作系统·嵌入式开发·rtos·设计思想
硅基手札5 天前
操作系统设计思想系列 06 · FreeRTOS 深度 — 极简可移植范本
架构·操作系统·freertos·实时操作系统·嵌入式开发·设计思想
Tronlong创龙6 天前
TLT153工控机:Docker 环境部署与容器开发实践(上)
docker·嵌入式开发·硬件开发·工业控制·工业开发板
.Bryce.7 天前
MCP+A2A+ANP,Agent通信协议的完整知识地图
java·人工智能·后端·agent·通信协议
杰克说11 天前
物联网消息协议MQTT详解
物联网·mqtt·信息与通信·通信协议