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控制器为了适应各种波特率,对上面四个段的时间长度,不是使用纳秒(ns)或微秒(us)来度量,而是使用节拍来度量,技术资料中将这个节拍称为时间量子(Time quantum, Tq)。
例如500k的波特率,每个Tbit是 2000ns,如果分为 10 个节拍,则每个 Tq 为 200ns。
工作流程
发送节点在每个bit中主要完成发送和回检。
接收节点在每个Bit中主要完成接收和同步。
传播段时长Tps
传播段PS占据的时间是信号在总线上来回传输的时间。
一次单向传输的延时Tdelay包括3个时间:
- 发送节点从产生信号到发到总线的时间 Td1;
- 信号在总线传输的时间Tbus;
- 接收节点从总线获取信号的时间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
-
计算传输段时长Tps
Tps的长度根据设备性能和总线长度决定,通常总线单位延时可按5.5ns/米估算。单个节点收/发延时按75ns估算。
假定总线长度12米,则Tps = 2 * ( 12 * 5.5 + 75 * 2) = 432ns,然后根据上一步的Q值,计算出 Tq 的时间,再根据 Tq 和延时时间,计算 Tps 需要的节拍数。
例如:当Tq = 125ns时,432ns延时需要的节拍数 = 432 / 125,向上取整得到4。 -
计算相位补偿段1时长 Tpbs1 和 相位补偿段2时长 Tpbs2
将Q值减1,再减掉 Tps 的节拍数,剩余的节拍数由 Tpbs1 和 Tpbs2 平分。如果剩余节拍是奇数,则 Tpbs1 比 Tpbs2 少一拍。 -
计算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的数值初始化驱动的结构体。