2. CAN FD终端电阻匹配与信号反射调试

任务目标

在 CAN FD 总线两端接入不同阻值终端电阻,通过采集总线差分波形观察振铃幅度,找出使反射最小的匹配方案。本案例用一段可运行的 Python 脚本模拟“双端终端电阻 + 一段传输线”的反射叠加,输出不同阻值下的振铃峰值,用于确定最佳匹配。

环境与依赖

  • Python 3.8+,仅需标准库 math、csv。
  • 无需真实硬件即可复现;若接入示波器,可将脚本输出的波形与实测对比。

实现思路

总线特性阻抗 Z0 设为 120 Ω。发送端产生一个上升沿阶跃,信号到达远端后按反射系数 Γ=(ZL−Z0)/(ZL+Z0) 反射,多次往返叠加形成振铃。脚本对每个候选终端阻值计算反射序列,取稳态前的最大过冲作为振铃幅度,选出最小者。

发送端 传输线 Z0=120Ω 终端电阻 ZL 入射波 反射波 Γ=(ZL−Z0)/(ZL+Z0) ZL=Z0 时 Γ=0,反射消失,振铃最小

核心代码

import math, csv

Z0 = 120.0          # 总线特性阻抗
VSTEP = 3.3         # 阶跃幅度
TR = 5e-9           # 上升时间
TD = 20e-9          # 单程传播延迟
N = 6               # 往返次数

def ringing_peak(zl):
    """计算给定终端阻值下的最大过冲(振铃幅度)。"""
    gamma = (zl - Z0) / (zl + Z0)
    v = 0.0
    for k in range(N):
        v += VSTEP * (gamma ** k) * (1 if k == 0 else 2)
    return abs(v - VSTEP)

candidates = [90, 100, 110, 120, 130, 150, 180]
results = []
for zl in candidates:
    peak = ringing_peak(zl)
    results.append((zl, peak))
    print(f"ZL={zl:>4}Ω  振铃峰值={peak:.4f} V")

best = min(results, key=lambda r: r[1])
print(f"\n最佳匹配: ZL={best[0]}Ω, 振铃峰值={best[1]:.4f} V")

with open("termination_sweep.csv", "w", newline="") as f:
    w = csv.writer(f)
    w.writerow(["ZL_ohm", "ringing_peak_V"])
    w.writerows(results)

运行与验证

  1. 保存为 termination.py,执行 python termination.py。
  2. 终端会打印各阻值对应的振铃峰值,并生成 termination_sweep.csv。
  3. 判定标准:当 ZL=120 Ω 时 Γ=0,振铃峰值应为 0;偏离 120 Ω 越远,峰值越大。若输出中 120 Ω 的峰值最小,说明匹配逻辑正确。

实测对照建议

若用示波器测量,将探头接总线差分对,分别在两端焊接 90/120/150 Ω 电阻,记录上升沿后的过冲幅度,与脚本输出的趋势对比。趋势一致即说明反射模型与实测吻合,可据此选定 120 Ω 作为最佳匹配。