CAN 作为一个不传输时钟的协议,有着比较复杂的时序要求,具体而言,就是在接受和传输每一位的过程中,都进行一次同步:

  1. 收到帧首时,重置同步状态,称为硬同步。当前采样时刻重置到同步段后一时刻。
  2. 其余时刻,收到隐形(单端高电平,无差分电压)到显性(单端低电平,有差分电压)的状态(下降沿)时,进行再同步。

为了具体说明,CAN 协议中把一个位所用的时间分为 8-25 个离散的采样时刻,称为时间量子。同时,还把接收一个位的时间分为了多个片段:

  1. 同步段 SYNC:占一个周期,如果有电平变化,应该在这一段内发生,然后在同步段结束后的时刻观察到变化。
  2. 传输段 PROP:信号从接收到发送节点走一个来回,以及两个节点内部收发延迟所占用的时间。
  3. 相位缓冲段 SEG1/SEG2:为了兼容不同节点间时钟频率偏差,在采样点前后所预留的时间,一般长度相等。
  ▼ 下降沿同步               
┌────┬────────────┬────┬────┐
│SYNC│    PROP    │SEG1│SEG2│
└────┴────────────┴────┴────┘
                       ▲ 采样
https://asciiflow.com

注意,这个划分是根据信号时序参数得来,在实现同步逻辑时,只需要把传输过程根据同步采样分为两个时间段 BS1 和 BS2 即可,其中 BS1 = PROP + SEG1。采样过程固定占用一个时间量子,无须指定。例如 STM32 和 ESP32 都是这么指定的。

再同步

根据信号变化,CAN 的接收端有一个非常灵活的再同步逻辑:

  1. 当收发时钟频率没有偏差时,所有的电平切换都应该在同步段中进行,再经过 BS1 时间后采样,经过 BS2 后回到同步段,整个过程长度为 1(同步段) + BS1 + BS2,再根据每个时间片的长度可以计算出比特率。
  2. 当信号在同步段前发生变化,也就是 BS2 中产生下降沿时,发送钟偏快,因此要提前下一时刻的采样,缩短 BS2 的时间,调整幅度不超过 SJW(同步跳转宽度)。
  3. 当信号在同步段后发生变化,也就是 BS1 中产生下降沿时,发送钟偏慢,因此要延后下一时刻的采样,延长 BS1 的时间,调整幅度不超过 SJW。

时序分析

传输段

在进行仲裁时,节点 A 可能在收到了节点 B 发送的信号后,又进行发送。这个过程中,信号从 B 在同步段开始发出,经过 B 的发送延迟、AB 传输延迟、A 接收延迟后被 A 的控制器进行分析,再经过 A 发送延迟、AB 传输延迟、B 接收延迟后由 B 收到并采样。为了保证 B 能够正确收到 A 的信号,传输段长度应该大于 A、B 各自的收、发延迟与来、回过程的传输延迟之和。

下降沿

注意到,上述同步只对下降沿进行,这用于避免在仲裁段多个节点同时发送 CAN ID 时,多个节点因为延迟而无止境地推迟采样。例如,如果两个节点间延迟 4 个时间量子,即使这两个节点同时发送,信号也只会在 4 个时间量子后到达,使得这两个节点都认为对方的时钟偏慢。而更极端的情况是,一个节点发送后,另一个节点在 4 个时间量子后才接收到,并认为自己与发送端已经保持同步。另一节点的信号再返回到第一个节点,需要经过 8 个时间量子的时间。而由于 CAN 总线是线与逻辑,当一个节点在同步段前发送显性电平后,必定在同步段接收到显性电平。当然,如果远程的节点提前发送,则可能在 BS2 段收到下降沿,此时可以进行再同步。

相位缓冲段

在进行仲裁时,需要多个节点同时发送。根据上述分析,由于延迟较大,很可能无法同步,需要保证两个节点在只进行了硬同步而没有再同步时也可以支撑到仲裁完成后仍然落在相位缓冲区,这要求时钟与标准时钟的偏差 dfdf 满足:

2×df<min(SEG1,SEG2)13SEG22\times df<\frac{\min{(\textrm{SEG1},\textrm{SEG2})}}{13-\textrm{SEG2}}

其中 SEG1/SEG2 指的是占一个比特用时的比例。如将一个比特用时分为 16 个时间量子,相位缓冲区长度均为 2 个时间量子,则df<0.49%df<0.49\%

同步跳转宽度

为了保证同步跳转宽度可以符合不同始终的偏差,需要保证调整一次就能坚持到下一次同步,CAN 保证每 5 位有一次电平变化,也就是每 10 位有一次下降沿。因此 dfdf 满足:

2×df<SJW102\times df<\frac{SJW}{10}

如将一个比特用时分为 16 个时间量子,同步跳转宽度为 1 个时间量子,则df<0.31%\textrm{d}f<0.31\%

位定时设置

由上可见,当传输延迟大时,应该加大传输段,而当时钟不准时,应该加大相位缓冲段。不过,通常的晶振偏差都在万分之一以下,因此可以尽可能多分配时间给传输段,在相位缓冲段和同步跳转宽度留一两个时间量子即可。