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 四个段的划分与作用
一个位时间被切成四段,每段干不同的事。我画了个图,你一看就明白:
四个段各司其职,我一个个讲:
| 段名 | 全称 | 作用 | 典型长度 |
|---|---|---|---|
| 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 位时序,我一般按这个流程走:
- 确定目标速率:比如仲裁段 500kbps,数据段 2Mbps
- 计算 Tq 长度:根据系统时钟和分频系数,算出每个 Tq 的时间
- 确定总 Tq 数:位时间 ÷ Tq 时间,取整,尽量在 8~25 之间
- 分配四个段:SS 固定 1 Tq,PTS 根据总线长度估算,PBS1 和 PBS2 决定采样点
- 设置 SJW:取 PBS1 和 PBS2 中较小的值,一般 1~2 Tq
- 验证采样点:计算采样点位置,确保在 70%~85% 之间
嗯,这里要注意:CAN FD 的仲裁段和数据段可以配置不同的位时序。仲裁段速率低,Tq 数多;数据段速率高,Tq 数少。STM32 的 FDCAN 外设支持两套独立的时序配置,后面移植的时候我会带你实操。
一句话总结:位时序就是给每个 bit 画格子,同步就是保证大家的格子对齐。SS 负责找起点,PTS 负责等信号传过来,PBS1 和 PBS2 负责微调。采样点卡在 PBS1 和 PBS2 之间,位置选对了,通信就稳了。