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

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采样的情况修可以被修复,如下: 

  • 12
    点赞
  • 67
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
好的,我可以回答你的问题。以下是用Verilog语言编写CAN收发的代码示例: module can_transceiver( input clk, //钟信号 input rst_n, //复位信号 input can_rx, //CAN接收信号 output reg can_tx //CAN发送信号 ); reg [11:0] can_id; //CAN标识符 reg [7:0] can_data[7:0]; //CAN数据 //定义状态机 localparam IDLE = 2'b00; //空闲状态 localparam RX = 2'b01; //接收状态 localparam TX = 2'b10; //发送状态 reg [1:0] state = IDLE; //初始状态为IDLE always @(posedge clk or negedge rst_n) begin if (!rst_n) begin state <= IDLE; //复位回到IDLE状态 can_tx <= 1'b0; //CAN发送信号置为0 end else begin case (state) IDLE: begin if (!can_rx) begin //接收到CAN信号 state <= RX; //进入接收状态 can_id <= 0; //初始化CAN标识符 can_data <= 0; //初始化CAN数据 end else if (can_data != 0) begin //有CAN数据需要发送 state <= TX; //进入发送状态 end end RX: begin can_id <= {can_id[0:7], can_rx}; //更新CAN标识符 for (i = 0; i < 8; i = i + 1) begin if (!can_rx) begin can_data[i] <= 1'b0; //接收CAN数据 end else begin can_data[i] <= can_rx; //更新CAN数据 end end if (can_rx) begin state <= IDLE; //接收完毕,回到IDLE状态 end end TX: begin can_tx <= 1'b1; //置CAN发送信号为1 for (i = 0; i < 8; i = i + 1) begin can_tx <= can_data[i]; //发送CAN数据 end state <= IDLE; //发送完毕,回到IDLE状态 end default: state <= IDLE; //默认回到IDLE状态 endcase end end endmodule 请注意,这只是一个简单的示例代码,并不能完全符合您的实际需求。具体实现需要根据您的具体需求进行修改和调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值