首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >为Σ-Δ ADC 设计 RC 滤波器前端

为Σ-Δ ADC 设计 RC 滤波器前端

作者头像
云深无际
发布2026-01-07 14:08:00
发布2026-01-07 14:08:00
3030
举报
文章被收录于专栏:云深之无迹云深之无迹

因为 ADC 已经把可以做的都做了,那就是前面的滤波器还可以设计一下了。

设计目标和边界条件

先把 MS53115 的边界条件列出来:

额定精度范围:±10 V 差分输入

功能保证绝对输入范围:-20 V ~ +20 V(不损坏、但精度可能受损)。

绝对最大输入电压(相对 AVSS):-65 V ~ +65 V(再往上就可能永久损坏)。

输入阻抗:约 1.5 MΩ

内部前端有 1:10 精密分压网络,可在 5 V 单电源下实现 ±20 V 输入范围。

我们要设计的是:前端一阶 RC 低通,限制高频噪声和干扰,减轻混叠 + EMC 压力;外接串联电阻 + 钳位器件,保证在±10 V 量程内高精度,但即使现场有 ±30 V、±60 V 的浪涌,也不会炸芯片。

在仿真里假设:

传感器源阻抗:R_source ≈ 100 Ω

串联保护电阻:R_series = 10 kΩ

ADC 输入电阻:R_in_adc = 1.5 MΩ

因为 1.5 MΩ ≫ 10 kΩ,所以在工作带宽内可以把 R_in 当成“几乎开路”,RC 截止频率主要由 (R_source + R_series) 和 C 决定。

前端 RC 的设计方法

截止频率公式

一阶 RC 低通(考虑高阻输入):

拓扑:Vin — R_source — R_series — (节点 Vadc) —||— C_f — 地;Vadc 再接入 ADC(1.5MΩ)

截止频率近似:

在代码里我用:

代码语言:javascript
复制
R_source = 100.0        # 传感器源阻抗
R_series = 10_000.0     # 外接串联电阻
R_eq = R_source + R_series

然后根据目标带宽反推 C:

代码语言:javascript
复制
def calc_C_for_fc(R_eq, fc):
    return 1.0 / (2.0 * np.pi * R_eq * fc)

两个典型工作点(和 C 选择)

我假设了两个典型工作模式,只是示例,后面可以改:

ODR = 10 kSPS,目标测量带宽 ~ 2 kHz

Nyquist = 5 kHz;希望模拟 RC 在 2 kHz 附近开始明显滚降,减轻 5 kHz 附近的高频能量;对应 f_target1 = 2 kHz

ODR = 1 kSPS,目标测量带宽 ~ 200 Hz

Nyquist = 500 Hz;希望 200 Hz 内响应平坦,500 Hz 附近已经明显衰减;对应 f_target2 = 200 Hz

计算得到 C(近似值):

对 2 kHz:

对 200 Hz:

在代码里我写了方便理解的标准值:

代码语言:javascript
复制
C1 = 8.2e-9   # ≈ 8.2 nF,对应 fc ≈ 1.9 kHz
C2 = 82e-9    # ≈ 82 nF,对应 fc ≈ 190 Hz
C3 = 1.0e-8   # 10 nF,用来对比
Bode 幅频曲线(单极 RC + 1.5M 并联)
Bode 幅频曲线(单极 RC + 1.5M 并联)

Bode 幅频曲线(单极 RC + 1.5M 并联)

第一张图是 Bode 幅频曲线(单极 RC + 1.5M 并联)

横轴:频率 1 Hz ~ 100 kHz(对数);

纵轴:增益(dB);

三条曲线分别对应 C1、C2、C3 三个电容值;

两条竖线:

虚线:fs1/2 = 10 kSPS / 2 = 5 kHz

点划线:fs2/2 = 1 kSPS / 2 = 500 Hz

会看到:

C1 ≈8.2nF(fc ~1.9 kHz):2 kHz 附近开始明显下降,5 kHz 已经有不错的衰减(大约 -10~-15 dB 级别);对 0~1 kHz 基本是平坦的(<1 dB 波动),适合 2 kHz 带宽的测量。

C2 ≈82nF(fc ~190 Hz):200 Hz 附近就开始强烈衰减,500 Hz 时已经跌很多;对 0~50~80 Hz 非常平坦,适合 50 Hz 以内的高精度慢速测量。同时对 50/60 Hz 以外的高频干扰更狠。

C3 =10nF(fc ~1.6 kHz):在 C1 和 C2 之间,相当于 10 kSPS、1.6 kHz 带宽用的一个折中。

时域仿真
时域仿真

时域仿真

“前端 RC 对高频成分的抑制效果”。

设定:

代码语言:javascript
复制
fs_sim = 100_000.0   # 仿真采样 100 kHz
t = np.arange(0, 2e-3, 1/fs_sim)  # 仿真 2 ms

f_sig = 1_000.0      # 1 kHz 有效信号
f_noise = 20_000.0   # 20 kHz 高频干扰
vin = 10*sin(2π*1k*t) + 0.3*10*sin(2π*20k*t)

蓝线:Vin(1 kHz 主信号 + 0.3×幅度的 20 kHz 高频分量);

橙线:Vout(经过 RC 之后);

使用的是 C1 ≈ 8.2 nF,fc ~1.9 kHz。

离散一阶 RC 模型:

代码语言:javascript
复制
def rc_lowpass_discrete(x, R_eq, C, fs):
    dt = 1.0 / fs
    tau = R_eq * C
    alpha = dt / (tau + dt)
    y = np.zeros_like(x)
    for n in range(1, len(x)):
        y[n] = y[n-1] + alpha*(x[n] - y[n-1])
    return y

会看到:Vin 波形有明显的“快速振铃”(20 kHz 高频叠加在 1 kHz 上);Vout 的高频边毛糙被压掉,波形更接近纯 1 kHz 正弦,只剩缓慢变化成分;这就是 RC 对高频噪声/干扰的抑制效果。

过压保护怎么接?

结合 datasheet 的极限参数,我们希望做到:

额定范围内:±10 V,全精度;不小心接到了 ±30 V、±40 V,甚至 ±60 V:对芯片:不超过 ±65 V 极限;对保护件:电流在可承受范围内(比如几 mA~十几 mA)。

串联电阻限流

我们已经选了 R_series = 10 kΩ,配合 R_source ≈ 100 Ω

假设瞬时有 ±60 V 脉冲打到输入端(相对 AVSS),我们在节点 Vadc 之后加一个双向 TVS 或钳位到 AVDD/AVSS 的保护二极管,使 Vadc 被钳在 ±12 V 左右:

串联电阻上压降约 = 60 V - 12 V = 48 V

串联电阻电流 ≈ 48 V / 10 kΩ = 4.8 mA

这个电流:对一般小封装 TVS/钳位二极管来说是很安全的;对 MS53115 内部分压网络来说,输入端最多看到 ±12~±20 V,远低于 ±65 V 极限。

一种典型连接结构

单端输入对 VCM 的情形,例如 AIN0(+)对 VCM(-):

代码语言:javascript
复制
传感器输出 (+10V…-10V)
      |
      R_source (≈100 Ω 或传感器内阻)
      |
      R_series (10 kΩ)
      |
      +-------------------+-----> AIN0 (MS53115)
      |                   |
     C_f                 TVS
    (8.2 nF 或 82 nF)   双向钳位到 AVSS
      |                   |
     AVSS                AVSS

VCM 管脚外接到 AVSS(单端模式推荐)→ AIN0 相对 VCM 测量

差分输入时,可以对每个输入脚都做对称保护:

代码语言:javascript
复制
Vin+ -- R_source+ -- R_series+ --+-- AIN0
                                  |
                                 C_f+
                                  |
                                 AVSS

Vin- -- R_source- -- R_series- --+-- AIN1
                                  |
                                 C_f-
                                  |
                                 AVSS

钳位件可以:用双向 TVS(比如 18 V 或 12 V 等级,具体看系统电源和信号幅度);或用“到 AVDD/AVSS 的肖特基二极管阵列 + 合适的 R_series”。

如何根据自己应用改参数?

先定测量带宽f_max_signal,和 ODR:对 Σ-Δ,一般 ODR ≥ 4~6×信号带宽;比如需要 1 kHz 带宽 → ODR 至少 5~10 kSPS。

选 R_series:要兼顾:限流能力(越大越安全);热噪声与源阻抗(越大噪声越大,但 10 kΩ 在 ±10V 模拟量场合一般没问题);10 kΩ 在这个芯片上是比较温和的起点。

算 C_f:选

;用 C = 1/(2π(R_source+R_series)f_c) 算出 C,再选最近的标准值。

在 Python 里改参数再看 Bode 和时域图

把代码里 f_target1, f_target2, R_series, C1,C2,C3 换成你实际目标;

看幅频图里:0~f_max 内曲线是否平坦(<0.5~1 dB);Nyquist 附近是否有足够衰减(至少 10~20 dB);

看时域图:高频干扰是否被压到可以接受的程度。

代码语言:javascript
复制
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = 'SimHei'# 替换为你选择的字体
plt.rcParams['axes.unicode_minus']=False
# ---------- 1. 设计参数 ----------

# 模拟一个 ±10V 传感器输出,经前端 RC + 保护后进入 MS53115
V_fullscale = 10.0          # ±10 V 量程
R_source = 100.0            # 假设传感器输出阻抗 100 Ω
R_series = 10_000.0         # 外接串联保护电阻 10 kΩ
R_in_adc = 1.5e6            # MS53115 典型输入阻抗 1.5 MΩ

# 设计目标:
# 1) 例子 1:适配 ODR = 10 kSPS,目标测量带宽 ~ 2 kHz
# 2) 例子 2:适配 ODR = 1 kSPS,目标测量带宽 ~ 200 Hz
f_target1 = 2_000.0
f_target2 = 200.0

def calc_C_for_fc(R_eq, fc):
    """
    根据等效电阻 R_eq 与目标截止频率 fc 计算 C。
    fc = 1 / (2π R_eq C)
    """
    return 1.0 / (2.0 * np.pi * R_eq * fc)

# 等效串联电阻(R_source + R_series),因为 R_in_adc >> (R_source + R_series)
R_eq = R_source + R_series

C_target1 = calc_C_for_fc(R_eq, f_target1)   # 适配 2 kHz 带宽
C_target2 = calc_C_for_fc(R_eq, f_target2)   # 适配 200 Hz 带宽

# 取实际标准值(近似):
# 例 1: ~8.2 nF ; 例 2: ~82 nF (这里只是演示,实际选型可用 E12/E24 系列)
C1 = 8.2e-9
C2 = 82e-9
C3 = 1.0e-8  # 再补一个 10 nF 做对比

Cf_list = [C1, C2, C3]
Cf_labels = [f"C ≈ {C1*1e9:.1f} nF (fc≈{1/(2*np.pi*R_eq*C1)/1e3:.1f} kHz)",
             f"C ≈ {C2*1e9:.1f} nF (fc≈{1/(2*np.pi*R_eq*C2):.1f} Hz)",
             f"C = {C3*1e9:.1f} nF (fc≈{1/(2*np.pi*R_eq*C3)/1e3:.1f} kHz)"]

# ---------- 2. 频率响应仿真(Bode 幅频特性) ----------

f = np.logspace(0, 5, 1000)  # 1 Hz ~ 100 kHz
w = 2.0 * np.pi * f

def H_mag(Rs, Rser, Rload, C, w):
    """
    一阶 RC + 高阻 ADC 输入的幅度响应。
    结构:Vin -- Rs -- Rser --(节点 Vadc)-- [Rload || C_to_GND]
    """
    Zc = 1.0 / (1j * w * C)
    # 并联阻抗
    Zload = 1.0 / (1.0 / Rload + 1.0 / Zc)
    Zseries = Rs + Rser
    H = Zload / (Zseries + Zload)
    return np.abs(H)

plt.figure()
for Cf, lab in zip(Cf_list, Cf_labels):
    mag = H_mag(R_source, R_series, R_in_adc, Cf, w)
    plt.semilogx(f, 20.0*np.log10(mag), label=lab)

# 标记示例 ODR 和 Nyquist 位置
fs1 = 10_000.0  # 例 1: ODR = 10 kSPS
fs2 = 1_000.0   # 例 2: ODR = 1 kSPS

plt.axvline(fs1/2, linestyle='--')
plt.axvline(fs2/2, linestyle=':')

plt.xlabel("Frequency (Hz)")
plt.ylabel("Magnitude (dB)")
plt.title("前端 RC + ADC 输入阻抗 的幅频响应")
plt.grid(True, which="both")
plt.legend()
plt.tight_layout()
plt.show()

# ---------- 3. 时域仿真:高频噪声抑制效果 ----------

# 使用连续 RC 的离散近似: y[n] = y[n-1] + alpha * (x[n] - y[n-1])
def rc_lowpass_discrete(x, R_eq, C, fs):
    dt = 1.0 / fs
    tau = R_eq * C
    alpha = dt / (tau + dt)  # 等效一阶滤波系数
    y = np.zeros_like(x)
    for n in range(1, len(x)):
        y[n] = y[n-1] + alpha * (x[n] - y[n-1])
    return y

# 仿真参数
fs_sim = 100_000.0           # 仿真采样频率(足够高)
t = np.arange(0, 2e-3, 1.0/fs_sim)  # 仿真 2 ms
f_sig = 1_000.0              # 1 kHz 有效信号
f_noise = 20_000.0           # 20 kHz 高频噪声

# 输入信号:1 kHz 正弦 + 0.3 倍幅度的 20 kHz 噪声分量
vin = V_fullscale * np.sin(2.0*np.pi*f_sig*t) + \
      0.3 * V_fullscale * np.sin(2.0*np.pi*f_noise*t)

# 使用 C1 (≈8.2 nF) 进行 RC 滤波
vout = rc_lowpass_discrete(vin, R_eq, C1, fs_sim)

# 只截取前 1 ms 数据用于绘图
idx = t <= 1e-3
t_plot = t[idx]
vin_plot = vin[idx]
vout_plot = vout[idx]

plt.figure()
plt.plot(t_plot*1e3, vin_plot, label="Vin: 1 kHz + 20 kHz 分量")
plt.plot(t_plot*1e3, vout_plot, label="Vout: 经过 RC 滤波")
plt.xlabel("Time (ms)")
plt.ylabel("Voltage (V)")
plt.title("前端 RC 滤波对高频分量的抑制(时域)")
plt.grid(True)
plt.legend()
plt.tight_layout()
plt.show()
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-12-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 云深之无迹 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 设计目标和边界条件
  • 前端 RC 的设计方法
    • 截止频率公式
    • 两个典型工作点(和 C 选择)
  • 过压保护怎么接?
    • 串联电阻限流
    • 一种典型连接结构
  • 如何根据自己应用改参数?
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档