第3章 标称位时间与数据位时间:不同速率段的采样点配置差异
CAN FD 跟经典 CAN 最大的不同,就是一个帧里跑着两套位时间。
仲裁段还是老规矩,125kbps~1Mbps,大家都能容忍。可一进数据段,速率蹭地跳到 2M、5M 甚至 8M。你想想看,同样一套采样点配置,能应付得了这两种节奏吗?
答案显然是不能。我在前几个项目里就吃过这个亏——标称位怎么调都稳,数据段却时不时冒个位错误出来。后来才发现,不是硬件不行,是采样点没跟着速率走。
3.1 标称位与数据位:两个“世界”
标称位时间(Nominal Bit Time)对应仲裁段,速率一般 ≤1Mbps。数据位时间(Data Bit Time)对应数据段,速率可以跳到 2Mbps、5Mbps 甚至 8Mbps。两者虽然都用 TQ(时间量子)来划分,但 TQ 长度、段分配完全独立。
| 特性 | 标称位时间 | 数据位时间 |
|---|---|---|
| 典型速率 | 125k–1Mbps | 1M–8Mbps |
| TSEG1 段 | 较宽(占 60%–80%) | 较窄(占 50%–70%) |
| SJW | 通常 ≤4 TQ | 通常 ≤2 TQ |
| 采样点推荐 | 80%–87.5% | 70%–80% |
为什么数据段采样点要往左移?数据段位时间短,TQ 数量也少(一般 8~20 个 TQ),如果采样点太靠后,振荡器瞬态抖动、线缆回波很容易把采样点推出有效窗口。我有个项目,标称位采样点设在 87.5%,数据段也照搬这个值,结果 2Mbps 下 BER 直接飙升到 10⁻³。后来把数据段采样点调到 75%,错误率瞬间降到 0。
3.2 不同速率段的采样点配置差异
我把常见速率组合分成三档来说,这样好记。
- 低速组合(标称 125k–250k / 数据 500k–1M)
这种场景 TQ 数量多(标称位 16~25 TQ),采样点窗口宽松。我一般把标称位采样点设在 83%~85%,数据段设在 75%~80% 就行。SJW 标称给 3~4 TQ,数据段给 1~2 TQ。 - 中速组合(标称 500k / 数据 2M)
这是 CAN FD 最常用的组合。标称位我惯用 80%~87.5%,数据段只能给 70%~75%。数据段 TQ 通常只有 10 个左右,采样点每挪 1% 影响都很大。注意 SJW 数据段别超过 1 TQ,否则相位缓冲失效。 - 高速组合(标称 1M / 数据 5M 或 8M)
数据段 5M 时 TQ 往往只有 8 个,采样点推荐 70%~73%。8M 下甚至只能做到 68%~70%。我试过在 8M 下把采样点设到 75%,结果一连串 CRC 错误——说白了就是采样点撞上了位流边沿。
核心原则:数据段的采样点必须比标称段更靠左(更靠前)。速率越高,采样点越要往 70% 方向压,同时减少 SJW 以降低相位裕量的浪费。
3.3 实际配置中的“隐形”陷阱
记得去年调试一个车载网关,标称位 500k,数据段 2M,晶振 40MHz。按手册算出来的寄存器值看起来很完美,结果上总线跑压力测试,错误帧率一直下不来。
我用示波器抓了位流,发现数据段的采样点正好卡在上升沿附近。为什么?因为我用的是统一 TQ 计算公式——把数据段的 TQ 数量设得和标称段一样(比如 16 TQ)。但数据段时间短,16 TQ 算出来的采样点位置其实很靠后。最终我强制把数据段 TQ 数量降到 10,采样点才回到 75%。
避坑指南(个人经验):
- 不要直接复用标称段的 TSEG1/TSEG2 比例。
- 数据段 TQ 数最好 ≤12,否则位时间太长,更难满足抖动容忍。
- 采样点计算公式:
采样点 = (1 + TSEG1) / (1 + TSEG1 + TSEG2) × 100%,但前提是你算清了每个 TQ 的时长。 - 如果用自动配置工具(如 STM32CubeMX、MCAL 的 CanTrcv),仍要手动验证数据段采样点是否符合预期——工具默认值经常偏向标称段。
3.4 一张图看懂速率与采样点的关系
下面这张图是我自己总结的,把不同速率段下的推荐采样点范围画在了一起。你会看到,数据段 5M 以上,采样点只能缩在 68%~73% 这个窄区间里,一点都不能马虎。
个人实用提示:如果你的控制器允许独立设置标称位和数据位的 TSEG1/TSEG2,我建议先把数据段的 TQ 总数固定为 10,然后从 70% 开始向上调整。每增加 1% 采样点,跑一遍位错误率测试。我曾用这种方法把某项目的数据段 BER 从 10⁻⁵ 压到 10⁻⁹。
3.5 配置实例:寄存器级别
下面以 STM32G4 的 FDCAN 外设为例,展示标称位 500kbps、数据位 2Mbps 时的典型寄存器配置。注意两个 Bit Timing 寄存器是分开的。
// 假设 MCU 时钟 40MHz,TQ 时长:
// 标称段:时钟分频 1 → TQ = 25ns,位时间 500ns → 20 TQ
// 数据段:时钟分频 1 → TQ = 25ns,位时间 500ns → 10 TQ(数据段速率 2M,位时间 500ns)
//
// 标称段:采样点 85% → 17 TQ 处于相位缓冲前
// TSEG1 = 16,TSEG2 = 3,SJW = 3
FDCAN1->NBTP = ( (1-1)<<24 ) | // NSJW = 3-1
( (16-1)<<16 ) | // NTSEG1 = 16-1
( (3-1)<<8 ) | // NTSEG2 = 3-1
( (1)<<0 ); // 预分频器 = 1
// 数据段:采样点 75% → 7.5 TQ,取 TSEG1=7, TSEG2=2,采样点 = (1+7)/(1+7+2)=8/10=80%(略高,但可接受)
// 若需要精确 75%,可将 TQ 总数改为 8:TSEG1=5,TSEG2=2 → (1+5)/(1+5+2)=6/8=75%
FDCAN1->DBTP = ( (1-1)<<20 ) | // DSJW = 1-1
( (5-1)<<13 ) | // DTSEG1 = 5-1
( (2-1)<<10 ) | // DTSEG2 = 2-1
( (1)<<0 ); // 数据预分频器 = 1
注意,代码里的 DTSEG1/DTSEG2 实际值都是“段长度 - 1”,这和经典 CAN 寄存器是一样的。数据段我特意选了 8 TQ,就是为了让采样点卡在 75%。如果你用 10 TQ,75% 的采样点是非整数,硬件会向下取整,这时候你最好实测一下边沿抖动。
注意:数据段速率超过 8Mbps 时,部分 MCU 需要额外调整延迟补偿(Transceiver Delay Compensation)。采样点配置必须和延迟补偿配合,否则采样点再准也没用。我踩过这个坑,后面章节(第7章)会专门讲。
好了,以上就是标称位与数据位时间在采样点配置上的核心差异。说白了,就是“一个尺子不能量两个世界”。
你如果正在设计 CAN FD 节点,不妨先按我列的这张速率-采样点对照表来设初值,然后再根据实测边沿位置微调 TSEG1。记住,数据段采样点宁可偏左也别偏右——偏右了直接出错误帧,偏左至少还能靠 SJW 兜底。