[CANFD] 高波特率下收发器延时的处理机制-Transceiver delay compensation

博客讨论了CANFD(Controller Area Network with Flexible Data-rate)在面对高波特率数据段时,如何处理收发器的信号延迟问题。CAN2.0时代的采样策略在1Mb/s下可以有效避免错误,但当速率提升到10Mb/s,200ns的延迟可能导致严重采样错误。为解决此问题,CANFD引入了Transceiver Delay Compensation(收发器延时补偿),通过测量仲裁段的延迟并在数据段调整采样点,确保RX能在正确位置采样,从而修复高速波特率下的信号延迟问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CANFD数据段支持可变速率,最高可达12Mb/s。我们知道CAN控制器会将收发器RX pin的数据采样接收,用于判断TX pin的数据是否被成功发送,以便实现冲裁判断和错误处理。RX的回环检测是保证CAN总线可靠性的基础技术。

但是,CAN收发器的信号转换都是有时延的,也就是说从TX出发到达CAN bus,以及从CAN bus返回RX都是延时的,在CAN2.0时代,收发器的延时在适合的采样点设置下被妥当的处理,不会因此造成TX的数据,RX延时采样后出现错误。我们看一下典型的CAN2.0收发器的信号延时参数。

CAN收发器的标准延时测试电路和波形示意如下图

不同的收发器参数略有差异,但是不管是PCA82C251/ TJA1050这类1Mb/s的收发器还是TJA1044可达5Mb/s的型号延时参数差异都不大, tonRXD在50ns左右,toffRXD在90ns左右。按max值算最大可以到200+ns

那么按200ns的延时进行考虑:也就是说TX发出的波形,RX回环接收到会延迟200ns。

首先看看,CAN2.0最高1Mb/s的情况。一个bit时间Tb=1000ns。200ns的延时会导致RX采样的波形落后20%。 按典型的87%的采样率计算,实际上RX loop采样的位置是在67%。所以整个RX采样的裕度还是比较大的,顺便也解释了为什么要选取75%~87%这样靠后的采样位置。这样TX->RX信号延时后,对保证让控制器能够采样到正确的数据非常有帮助。

 

然后来到CANFD,事情发生了变化。

以10Mb/s的数据段高速波特率计算,一个bit位周期Tb=100ns。最高200ns的RX delay将会带来毁灭性的采样错误,TX->RX收到的波形可能已经落后超过一个Tb,无论如何设置采样位置都无返挽回如此大的信号延时。

所以CANFD的标准给出了一个解决办法:Transceiver delay compensation(收发器延时补偿)

给RX定义了一个新的采样点SSP(Secondary Sample Point)。要求控制器需要在仲裁段(<=1Mb/s)段测量FDF下降沿的RX delay时间,然后在发送数据段对RX采样时,对RX采样点进行延时。(下图是ST的FDCAN对延时测量的说明)

也就是说,在CANFD高速波特率发送的情况下,采样RX loop的采样点会推迟一段时间。

具体推迟的时间通过仲裁段的FDF位的下降沿delay来测量。

之后数据段RX采样的情况修可以被修复,如下: 

### CANFD 分频计算方法 对于CANFD分频的计算,主要依赖于几个关键参数:总的时间量子(tq)数量、预分频系数以及所期望达到的目标波特率。具体到S32K144中的应用实例中,当设定目标波特率为250k时,采用的是如下公式来实现这一目的: \[ \text{波特率} = \frac{\text{CAN时钟}}{\left(\text{总tq数}\right)\times\left(\text{预分频系数}+1\right)} \] 例如,在给定条件下,如果CAN时钟频率设置为10MHz,并且选择了20作为总的tq数,则为了得到250kHz的有效波特率,需要选择1作为预分频系数[^1]。 进一步探讨CANFD特有的波形特性,特别是在BRS (Bit Rate Switching) 和 CRC Delimiter bits阶段,这些部分支持不同的数据传输速率。这里涉及到两种不同时间段内的位宽定义——低波特率区间的长度被指定为12个tq单位;而在波特率区间内,该数值减少至6个tq单位。这意味着在同一帧消息内部能够灵活调整比特流的速度,从而优化网络性能和效率[^3]。 针对上述提到的延迟补偿机制(CanControllerTrcvDelayCompensationOffset),它允许开发者通过软件手段微调接收端相对于发送端之间存在的固有传播延时差异,这对于确保准确无误的数据交换至关重要[^2]。 ```python def calculate_baud_rate(can_clock, total_tq, prescaler): baud_rate = can_clock / ((total_tq)*(prescaler + 1)) return baud_rate can_clock_frequency = 10_000_000 # 即10 MHz number_of_time_quanta = 20 # 总tq数 pre_divider_value = 1 # 预分频系数 calculated_baudrate = calculate_baud_rate( can_clock_frequency, number_of_time_quanta, pre_divider_value) print(f"Calculated Baud Rate is {calculated_baudrate:.0f}") ```
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值