CAN总线的位时序与参数设置

CAN总线的位时序与参数设置

CAN的位时序构成

CAN总线的每个位(Bit)的周期 Tbit = 1 / Baudrate。根据CAN规范,每个位的时间内又可细分成4段:

  • 同步段(Synchronization Segment,Tss
  • 传播段(Propagation Segment, Tps
  • 相位缓冲段1(Phase Buffer Segment 1, Tpbs1
  • 相位缓冲段2(Phase Buffer Segment 2, Tpbs2

CAN总线的位时序与参数设置_第1张图片

时序计量单位

CAN控制器为了适应各种波特率,对上面四个段的时间长度,不是使用纳秒(ns)或微秒(us)来度量,而是使用节拍来度量,技术资料中将这个节拍称为时间量子(Time quantum, Tq)。

例如500k的波特率,每个Tbit是 2000ns,如果分为 10 个节拍,则每个 Tq 为 200ns。

工作流程

发送节点在每个bit中主要完成发送和回检。
CAN总线的位时序与参数设置_第2张图片
接收节点在每个Bit中主要完成接收和同步。
CAN总线的位时序与参数设置_第3张图片

传播段时长Tps

传播段PS占据的时间是信号在总线上来回传输的时间。

一次单向传输的延时Tdelay包括3个时间:

  1. 发送节点从产生信号到发到总线的时间 Td1
  2. 信号在总线传输的时间Tbus
  3. 接收节点从总线获取信号的时间Td2

按规范要求,传播段的时间Tps应大于等于2倍Tdelay的时间,即
Tps >= 2 * Tdelay = 2 * (Td1 + Tbus + Td2)

为什么规定是两倍时间呢?

CAN总线是一种允许竞争并自行仲裁的协议。见上面工作流程图可知,每个节点会回读自己发出的信号。

假设极端情况下,节点Node1在总线的一端发出了信号s1,总线另一端的节点Node2在 Tdelay 时间之前由于尚未收到信号s1,所以可能认为总线是空闲的,那就可能往总线上发送信号s2。当然,Node2刚发出s2,总线上就产生了s1和s2的竞争,而这个竞争的情况会又经过 Tdelay 的时间才被Node1感知到。

所以两倍Tdelay的要求就是为了保证每个节点都能正确检测到总线上的竞争。

CAN参数设置

下面以STM32系列CPU为例,具体说明参数设置方法。

STM32 CPU的CAN与位时序相关的参数有4个:

  • BRP (Baud rate prescaler),预分频值,允许的范围是1 ~ 1024。
  • TS1 (Time segment 1), 允许的范围是1 ~ 16。这个参数设置传播段(Tps)与相位缓冲段1(Tpbs1)相加的节拍数。
  • TS2 (Time segement 2), 允许的范围是1 ~ 8。这个参数设置相位缓冲段2(Tpbs2)的节拍数。
  • SJW(Resynchronization jump width), 重同步宽度,允许的范围是1 ~ 4。用于设置Tpbs1和Tpbs2可以调整的节拍数。

1. BRP的参数设置

BRP用于将APB的时钟(其他CPU可能直接使用晶振时钟)分频到CAN时钟。CAN时钟的每个周期就是前面说过的节拍或时间量子(Tq

BRP的值由基频(APB时钟)频率 Fclk、波特率 Baudrate 和每个 Bit 的节拍数 Q 决定。
BRP = Fclk / (Q * Baudrate)

从STM32寄存器参数允许范围来说,Q 的数量可以在 3 ~ 25 之间(见 TS1 和 TS2 的范围),但从同步调整的有效性来说,最好在 6 ~ 25 之间。
例如,APB 时钟 24M,波特率 500k,如果 Q 取 6 ~ 25之间的整数值,则BRP可以使用的值有:2、3、4、6、8。

Q的大小与通讯质量是有关系的。个人觉得只要寄存器 TS1 和 TS2 的数值允许,Q 值应该尽量大一点。Q 值越小,本地在同步调整时的变化就越大(不稳定)。
以 500k 波特率(Tbit = 2000ns)来说,如果 Q = 25,则每拍时长Tq = 80ns,也就是接收侧可以将同步的位置前后最小变动80ns;而如果Q=5,则每拍时长Tq = 400ns,意味着接收侧对同步位置的调整至少是400ns。那很可能这次调快了,而后一次又调慢了,这会导致通讯质量明显下降。
对最极端的 Q = 3来说(TS1=1,TS2=1),这样的时序分配导致几乎不具备重同步的能力。

2. TS1和TS2的参数设置

TS1和TS2的参数设置,就是将 Q 分配给位时序中 3个段:PS、PBS1 和 PBS2 (SS段永远占据一拍,不商量)。
Q = 1 + Tps + Tpbs1 + Tpbs2

  1. 计算传输段时长Tps
    Tps的长度根据设备性能和总线长度决定,通常总线单位延时可按5.5ns/米估算。单个节点收/发延时按75ns估算。
    假定总线长度12米,则Tps = 2 * ( 12 * 5.5 + 75 * 2) = 432ns,然后根据上一步的Q值,计算出 Tq 的时间,再根据 Tq 和延时时间,计算 Tps 需要的节拍数。
    例如:当Tq = 125ns时,432ns延时需要的节拍数 = 432 / 125,向上取整得到4。

  2. 计算相位补偿段1时长 Tpbs1 和 相位补偿段2时长 Tpbs2
    将Q值减1,再减掉 Tps 的节拍数,剩余的节拍数由 Tpbs1 和 Tpbs2 平分。如果剩余节拍是奇数,则 Tpbs1 比 Tpbs2 少一拍。

  3. 计算TS1和TS2的值
    TS1 等于 Tps 和 Tpbs1 的节拍数相加。
    TS2 等于 Tpbs2 的值。

3. SJW的参数设置

SJW比较简单,取 (TS2 - 1) 和 4 两个数字中小的那个。即 SJW = min(TS2-1, 4)。

将上面的例子:基频24M,CAN总线波特率 500k,传输延时 432ns,各种不同Q值下,各参数计算过程列表如下:

BRP Q Tq(ns) SS Tps 剩余 Tpbs1 Tpbs2 TS1 TS2 SJW
2 24 83.3 1 6 17 9 8 15 8 4
3 16 125.0 1 4 11 5 6 9 6 4
4 12 166.7 1 3 8 4 4 7 4 3
6 8 250.0 1 2 5 2 3 4 3 2
8 6 333.3 1 2 3 1 2 3 2 1

最后,很重要的一点
如果直接设置STM32的寄存器,上面BRP、TS1、TS2和SJW的数值,全都需要减1后写入寄存器(见STM32 Reference Manual中相关寄存器的说明);
如果使用STM提供的驱动程序,则直接使用BRP、TS1、TS2和SJW的数值初始化驱动的结构体。

你可能感兴趣的:(嵌入系统)