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,你会怎么配?
我的做法是这样的:
- 先确定Tq。一般一个位时间用8~25个Tq。我习惯用16个Tq,这样采样点好算。
- 位时间 = 1/500k = 2μs。每个Tq = 2μs / 16 = 125ns。
- 分频系数 = 125ns × 40MHz = 5。所以预分频器设为5-1=4。
- 分配各段长度:同步段1 Tq,传播段3 Tq,相位缓冲段1 8 Tq,相位缓冲段2 4 Tq。
- 采样点 = (1+3+8)/16 = 75%。嗯,有点靠前,调整一下:传播段2 Tq,相位缓冲段1 9 Tq,相位缓冲段2 4 Tq。采样点 = (1+2+9)/16 = 75%。还是75%。
- 再调:传播段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的帧格式——数据帧、远程帧、错误帧、过载帧,看看这些帧到底长什么样。