4. CAN FD 位时序与同步:Tq 与位时间分段

好,咱们进入 CAN FD 协议栈移植里最绕、但也最核心的一环——位时序与同步。说实话,我刚接触 CAN 的时候,也被这些 Tq、SS、PTS 搞得头晕。后来在项目里调了几次总线,才真正明白这些东西到底在干什么。

你想想看,CAN 总线上的节点没有统一的时钟线,全靠自己内部晶振去猜对方什么时候发数据。那怎么保证大家节奏一致?靠的就是位时序和同步机制。说白了,就是大家约定好:一个 bit 怎么切段,什么时候采样,怎么调整误差。

4.1 位时间的基本概念

一个 CAN FD 的位时间,被分成了若干个小段。每个小段叫一个 Tq(Time Quantum,时间量子)。Tq 是 CAN 控制器内部的最小时间单位,由系统时钟分频得到。

核心公式:

位时间 = SS + PTS + PBS1 + PBS2 = N × Tq

其中 N 是总 Tq 数,通常取 8~25 之间。

我在项目里踩过一个坑:当时为了追求高速,把位时间压到 8 个 Tq,结果总线一长,采样点位置不对,通信直接崩了。后来老老实实改回 16 个 Tq,问题就解决了。所以我的建议是:别为了省那点时间把 Tq 总数压太低,留点余量给同步。

4.2 四个段的划分与作用

一个位时间被切成四段,每段干不同的事。我画了个图,你一看就明白:

CAN FD 位时间分段结构 一个位时间(N × Tq) SS 同步段 1 Tq PTS 传播段 1~8 Tq PBS1 相位缓冲段1 1~8 Tq PBS2 相位缓冲段2 2~8 Tq 采样点(SP) 说明: 采样点位于 PBS1 与 PBS2 之间。SS + PTS + PBS1 决定采样点位置。 PBS2 用于补偿振荡器误差,保证下一个位时间的同步。

四个段各司其职,我一个个讲:

段名 全称 作用 典型长度
SS 同步段 检测总线上的跳变沿,用于同步 固定 1 Tq
PTS 传播段 补偿总线传播延迟和收发器延迟 1~8 Tq
PBS1 相位缓冲段1 采样前调整,用于再同步时延长位时间 1~8 Tq
PBS2 相位缓冲段2 采样后调整,用于再同步时缩短位时间 2~8 Tq

我的经验:配置 STM32 的 CAN FD 时,我习惯把采样点设在 75%~85% 的位置。比如总 Tq 数 16,SS=1,PTS=4,PBS1=7,PBS2=4,采样点就在 (1+4+7)/16 = 75%。这个位置对大多数 500kbps~1Mbps 的 CAN FD 网络都挺稳。

4.3 硬同步与再同步

同步分两种:硬同步和再同步。我刚开始学的时候老搞混,后来在调试一个多节点通信的板子时才彻底分清楚。

4.3.1 硬同步

硬同步发生在总线从空闲状态(隐性)跳变到帧起始(显性)的那一刻。每个节点检测到这个下降沿后,会把自己的位时序计数器清零,重新从 SS 段开始计数。

说白了,硬同步就是一次「强制对齐」。它只在帧起始时发生一次,后面就不管了。

硬同步的特点:

  • 只在总线空闲后的第一个下降沿触发
  • 强制将 SS 段对齐到跳变沿
  • 不调整 PBS1 或 PBS2 的长度
  • 每个帧只发生一次

4.3.2 再同步

再同步就不一样了。它在帧传输过程中持续发生。只要检测到跳变沿没有落在 SS 段内,控制器就会自动调整 PBS1 或 PBS2 的长度,把采样点拉回来。

再同步有两种调整方式:

  • 相位超前(跳变沿来早了): 缩短 PBS2,让下一个位时间提前开始
  • 相位滞后(跳变沿来晚了): 延长 PBS1,让采样点往后推

但调整不是无限的。每个控制器都有一个 SJW(同步跳转宽度),限制了单次调整的最大 Tq 数。SJW 通常设为 1~4 Tq。

我曾经踩过的坑:有次做 8Mbps 的 CAN FD 通信,SJW 设了 1 Tq,结果总线长度一超过 30cm 就丢帧。后来把 SJW 改成 2 Tq,问题解决。SJW 太小,节点跟不上时钟漂移;SJW 太大,又容易误同步。我的建议是:SJW 取 PBS1 和 PBS2 中较小的那个值,一般 2 Tq 比较稳妥。

4.4 采样点位置的计算

采样点位置直接决定了通信的可靠性。计算公式很简单:

采样点位置 = (SS + PTS + PBS1) / (SS + PTS + PBS1 + PBS2) × 100%

我整理了几种常用配置,供你参考:

速率 总 Tq SS PTS PBS1 PBS2 SJW 采样点
500 kbps 16 1 4 7 4 2 75.0%
1 Mbps 10 1 2 4 3 2 70.0%
2 Mbps 8 1 2 3 2 1 75.0%
5 Mbps 8 1 1 3 3 1 62.5%

小技巧:如果你不确定采样点设多少合适,先按 75% 来。CAN 协议规范推荐采样点在 75%~85% 之间。对于 CAN FD 的高速数据段(2Mbps 以上),采样点可以适当往 70% 靠,因为传播延迟的影响更明显。

4.5 位时序配置的实战步骤

在 STM32 上配置 CAN FD 位时序,我一般按这个流程走:

  1. 确定目标速率:比如仲裁段 500kbps,数据段 2Mbps
  2. 计算 Tq 长度:根据系统时钟和分频系数,算出每个 Tq 的时间
  3. 确定总 Tq 数:位时间 ÷ Tq 时间,取整,尽量在 8~25 之间
  4. 分配四个段:SS 固定 1 Tq,PTS 根据总线长度估算,PBS1 和 PBS2 决定采样点
  5. 设置 SJW:取 PBS1 和 PBS2 中较小的值,一般 1~2 Tq
  6. 验证采样点:计算采样点位置,确保在 70%~85% 之间

嗯,这里要注意:CAN FD 的仲裁段和数据段可以配置不同的位时序。仲裁段速率低,Tq 数多;数据段速率高,Tq 数少。STM32 的 FDCAN 外设支持两套独立的时序配置,后面移植的时候我会带你实操。

一句话总结:位时序就是给每个 bit 画格子,同步就是保证大家的格子对齐。SS 负责找起点,PTS 负责等信号传过来,PBS1 和 PBS2 负责微调。采样点卡在 PBS1 和 PBS2 之间,位置选对了,通信就稳了。