4、CAN位时序与同步:位时间组成、同步段、传播段、相位缓冲段、硬同步与重同步

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

说实话,我刚开始接触CAN协议时,觉得这东西不就是两根线发数据嘛,能有多复杂?直到有一次,我在一个车载项目里,总线老是丢帧,示波器一抓,波形乱七八糟。折腾了两天,最后发现是位时序配置出了问题。嗯,从那以后,我再也不敢小看这个“位时间”了。

4.1 位时间的基本组成

先说说位时间是什么。说白了,就是一个CAN数据位在总线上持续的时间。比如你总线速率是500kbps,那一个位的时间就是2微秒。

但CAN协议没这么简单。它把一个位时间切成了四段:

  • 同步段(Sync_Seg)
  • 传播段(Prop_Seg)
  • 相位缓冲段1(Phase_Seg1)
  • 相位缓冲段2(Phase_Seg2)

你想想看,为什么非要切成四段?直接发不行吗?

答案在于——CAN总线是多主通信,没有单独的时钟线。所有节点得靠自己的晶振来“猜”什么时候该采样。这四段就是为了让大家的“猜”能尽量准。

段名称 作用 典型长度(Tq)
同步段 检测总线上的跳变沿 1 Tq
传播段 补偿物理延迟 1~8 Tq
相位缓冲段1 采样点前调整 1~8 Tq
相位缓冲段2 采样点后调整 1~8 Tq

这里有个关键概念——时间量子(Tq)。它是CAN控制器内部的最小时间单位。一个位时间由若干个Tq组成,比如8个、16个、25个,取决于你的分频配置。

核心公式:

位时间 = 同步段 + 传播段 + 相位缓冲段1 + 相位缓冲段2

采样点位置 = (同步段 + 传播段 + 相位缓冲段1) / 总位时间

4.2 同步段——时钟对齐的起点

同步段固定为1个Tq。它的任务很简单:等待总线上的下降沿(从显性到隐性或反之)。

为什么是下降沿?因为CAN总线是“线与”逻辑,显性位(0)会覆盖隐性位(1)。所以从隐性到显性的跳变最可靠,也最容易检测。

我个人习惯把同步段想象成“起跑线”。所有节点看到这个跳变沿,就知道该重新对齐自己的时钟了。

4.3 传播段——补偿物理延迟

传播段是用来补偿信号在总线上的传输延迟的。这个延迟包括:

  • 信号在铜线上的传播时间(约5ns/m)
  • 收发器的延迟(通常几十纳秒)
  • 控制器的内部处理延迟

我在项目中遇到过一个问题:总线长度只有2米,按理说传播延迟很小。但我把传播段设成了1个Tq,结果总线在高温下频繁出错。后来发现,收发器在85°C时延迟会翻倍。嗯,温度效应不能忽略。

经验公式:

传播段长度 ≥ 2 × (总线延迟 + 收发器延迟 + 控制器延迟)

乘以2是因为信号要来回——发送方发出,接收方应答。

4.4 相位缓冲段——采样点的守护者

相位缓冲段1和相位缓冲段2,是CAN位时序里最灵活的部分。它们的作用是:

  • 相位缓冲段1:在采样点之前,允许重同步延长
  • 相位缓冲段2:在采样点之后,允许重同步缩短

说白了,这两个段就是“缓冲区”。当某个节点的时钟有偏差时,通过调整这两个段的长度,让采样点仍然落在正确的位置。

采样点一般设置在什么位置?我个人推荐87.5%左右。也就是相位缓冲段1比相位缓冲段2长一些。为什么?因为总线上的信号需要时间稳定,采样点靠后一些,采到的数据更可靠。

注意:

采样点太靠前(比如50%),信号还没稳定就采样,容易误判。

采样点太靠后(比如95%),留给相位缓冲段2的调整空间太小,同步能力下降。

我一般控制在80%~90%之间,具体看总线速率和长度。

4.5 硬同步——从零开始的强制对齐

硬同步发生在总线从空闲状态(隐性)变为开始传输(显性)的那一刻。也就是SOF(帧起始)的下降沿。

硬同步的规则很简单:

  • 每个节点检测到SOF的下降沿
  • 立即将自己的位时间计数器清零
  • 从同步段重新开始计时

这就好比所有运动员听到发令枪,同时起跑。硬同步保证了每个节点在帧开始时是同步的。

但问题来了——如果每个节点的晶振精度不一样,跑着跑着就会偏离。这时候就需要重同步了。

4.6 重同步——跑偏了拉回来

重同步发生在帧传输过程中。当节点检测到总线上的跳变沿不在预期的同步段内时,就会触发重同步。

重同步有两种调整方式:

  • 延长相位缓冲段1:如果跳变沿来晚了,说明对方的时钟比自己的慢。那就把相位缓冲段1拉长,让采样点往后移。
  • 缩短相位缓冲段2:如果跳变沿来早了,说明对方的时钟比自己的快。那就把相位缓冲段2缩短,让采样点往前移。

这里有个关键参数——同步跳转宽度(SJW)。它限制了每次重同步最多能调整多少个Tq。

我曾经犯过一个错误:把SJW设成了4个Tq,觉得调整范围大一点好。结果总线在噪声环境下频繁出现同步错误。后来才明白,SJW太大,系统对噪声太敏感,一点小抖动就大幅调整,反而更不稳定。

我的建议:

SJW一般设为1~2个Tq就够了。

除非你的总线特别长(比如超过40米),或者节点晶振精度很差(超过1%),才考虑加大SJW。

4.7 位时序配置实战

说了这么多理论,咱们来点实际的。假设你要配置一个500kbps的CAN总线,系统时钟是40MHz,你会怎么配?

我的做法是这样的:

  1. 先确定Tq。一般一个位时间用8~25个Tq。我习惯用16个Tq,这样采样点好算。
  2. 位时间 = 1/500k = 2μs。每个Tq = 2μs / 16 = 125ns。
  3. 分频系数 = 125ns × 40MHz = 5。所以预分频器设为5-1=4。
  4. 分配各段长度:同步段1 Tq,传播段3 Tq,相位缓冲段1 8 Tq,相位缓冲段2 4 Tq。
  5. 采样点 = (1+3+8)/16 = 75%。嗯,有点靠前,调整一下:传播段2 Tq,相位缓冲段1 9 Tq,相位缓冲段2 4 Tq。采样点 = (1+2+9)/16 = 75%。还是75%。
  6. 再调:传播段1 Tq,相位缓冲段1 10 Tq,相位缓冲段2 4 Tq。采样点 = (1+1+10)/16 = 75%。

你看,不管怎么调,采样点都是75%。因为总Tq数固定了。所以如果你想调整采样点,就得改变总Tq数。

我一般用20个Tq:同步段1,传播段3,相位缓冲段1 13,相位缓冲段2 3。采样点 = (1+3+13)/20 = 85%。这个配置我用过很多项目,效果不错。

避坑指南:

我曾经在一个项目里,直接把别人的配置抄过来用。结果总线速率不一样,采样点完全不对。记住:位时序配置必须根据你的系统时钟和总线速率重新计算,不能直接复制粘贴。

4.8 总结一下

CAN的位时序与同步,说白了就是解决一个问题:没有时钟线,大家怎么对齐?

答案就是:

  • 用同步段检测跳变沿
  • 用传播段补偿延迟
  • 用相位缓冲段提供调整空间
  • 用硬同步在帧开始时强制对齐
  • 用重同步在帧过程中微调

你想想看,这个设计是不是很巧妙?没有额外的时钟线,只靠一根数据线上的跳变沿,就能让几十个节点协同工作。这也是CAN总线在汽车和工业领域经久不衰的原因之一。

下一章,咱们聊聊CAN的帧格式——数据帧、远程帧、错误帧、过载帧,看看这些帧到底长什么样。