第四节:CAN总线位时序——位时间组成、同步段、传播段、相位缓冲段、采样点配置

各位同学,咱们今天聊点硬核的——CAN总线的位时序。

说实话,我刚入行那会儿,觉得这东西就是个理论概念。不就是发个0和1嘛,有啥好研究的?直到我在一个项目里,因为采样点配置差了那么一点点,整条CAN总线在高温下疯狂丢帧……嗯,从那以后,我再也不敢小看位时序了。

4.1 位时间到底是个啥?

先搞清楚一个基本概念:位时间,就是一个bit在总线上持续的时间。

比如你配置CAN总线波特率为500kbps,那一个位时间就是2微秒。这个很好理解,对吧?

但问题来了——这2微秒里,CAN控制器在干什么?

它不是在傻等。它把这2微秒切成了好几段,每一段都有特定的任务。这就是位时序的核心思想。

4.2 位时间的四个段

一个完整的位时间,被分成四个段。我习惯用一张表来记它们:

段名称 英文缩写 作用 典型长度(Tq)
同步段 SS 同步总线上的所有节点 1 Tq
传播段 PTS 补偿物理延迟 1-8 Tq
相位缓冲段1 PS1 补偿边沿相位误差 1-8 Tq
相位缓冲段2 PS2 补偿边沿相位误差 1-8 Tq

注意,这里的Tq是时间量子,它是CAN控制器的最小时间单位。一个位时间由若干个Tq组成,通常8到25个Tq。

4.3 同步段(SS)—— 大家对齐的起点

同步段固定为1个Tq。它的作用很简单:所有节点在这个段的下降沿对齐

你想想看,总线上那么多节点,各自有各自的时钟,怎么保证大家步调一致?

靠的就是这个同步段。每个节点检测到总线上的下降沿时,就认为这是一个位时间的开始。说白了,这就是个“对表”的动作。

4.4 传播段(PTS)—— 给信号传输留点余量

传播段,我个人觉得这个名字有点误导。它补偿的不是“传播”,而是物理延迟

物理延迟包括两部分:

  • 信号在总线上的传输延迟(跟线长有关)
  • 收发器的内部延迟

我在一个分布式BMS项目里,电池包分布在车底,CAN总线长度接近10米。当时我按常规配置了传播段,结果高温下总出现位错误。后来一算,传播段设短了,信号还没传到远端节点,采样点就到了。

避坑指南: 传播段长度必须大于2倍的物理延迟。我曾经因为忽略收发器延迟,导致总线在40米线长下完全无法通信。记住公式:传播段 ≥ 2 × (总线延迟 + 收发器延迟)。

4.5 相位缓冲段(PS1和PS2)—— 容错的关键

这两个段,才是位时序里最灵活的部分。

相位缓冲段1(PS1)在采样点之前,相位缓冲段2(PS2)在采样点之后。它们的作用是吸收时钟偏差

为什么会需要这个?

因为每个节点的晶振都有误差。假设你的晶振是20ppm,我的晶振是-20ppm,时间长了,我们的位时间就会产生偏差。相位缓冲段就是用来“吃掉”这个偏差的。

CAN协议通过硬同步重同步机制,动态调整PS1和PS2的长度。说白了,就是发现偏差了,就拉长或缩短一下缓冲段,让采样点始终落在正确的位置。

4.6 采样点配置—— 最容易被忽视的坑

采样点,就是CAN控制器读取总线电平的那个时刻。它位于PS1和PS2之间。

采样点的位置,通常用百分比表示:

采样点位置 = (SS + PTS + PS1) / 位时间 × 100%

比如一个位时间由16个Tq组成,SS=1,PTS=3,PS1=6,PS2=6,那么采样点位置就是 (1+3+6)/16 = 62.5%。

那么问题来了:采样点设多少合适?

我个人的经验是:

  • 低速CAN(125kbps以下):采样点可以靠后,80%-90%都行
  • 高速CAN(500kbps以上):采样点建议在70%-80%之间
  • 极端环境(高温、长线):我习惯设在75%左右,留足余量
重要提醒: 同一个CAN网络上的所有节点,采样点必须一致。我曾经在一个项目里,两个ECU的采样点差了5%,常温下没问题,一到-20℃就疯狂报错。查了三天才找到原因。

4.7 实际配置示例

拿STM32的bxCAN模块举个例子。假设我们要配置500kbps,时钟频率36MHz:

// 位时间 = 36MHz / 500kbps = 72 Tq
// 但我们通常用8-25个Tq,所以需要分频
// 预分频器 = 4,则Tq = 4/36MHz ≈ 111ns
// 位时间 = 72 / 4 = 18 Tq

// 配置如下:
// SS = 1 Tq
// PTS = 3 Tq
// PS1 = 6 Tq
// PS2 = 8 Tq
// 采样点 = (1+3+6)/18 = 55.6%

// 实际代码:
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
CAN_InitStructure.CAN_Prescaler = 4;

嗯,这里要注意,我故意把采样点设在了55.6%,偏低。为什么?因为这个项目总线很长,传播延迟大,我需要给传播段留更多空间。采样点低一点,PS2长一点,重同步的余量就大。

小技巧: 如果你不确定采样点怎么配,可以用CAN计算器工具。我习惯先算理论值,再在实际板子上用示波器抓波形,看采样点是否落在位的稳定区域。记住,理论计算只是起点,实测才是王道。

4.8 总结一下

位时序这东西,说白了就是在时间轴上精确控制采样时刻。四个段各有分工:

  • 同步段:对齐起点
  • 传播段:补偿延迟
  • 相位缓冲段1和2:吸收偏差

采样点配置,是位时序设计的核心。我见过太多工程师,随便配个参数就跑,结果现场出问题。记住:采样点不是拍脑袋定的,是根据总线长度、节点数量、晶振精度算出来的

下一节,咱们聊聊CAN的同步机制——硬同步和重同步到底怎么工作的。到时候我会分享一个我当年调试同步失败的案例,保证让你印象深刻。