昨天写了这个共模的 OP,如果单纯的写写参数那就有点说不过了,所以我来写点网上没有的东西。先写个滤波器(没错,就会滤波器),在写一个 ADC 的缓冲器。
那就用 GM4500 设计一个有源滤波器,我想做到不泛泛讲原理,而是:
为什么选这种拓扑?
参数怎么算?
噪声 / 带宽 / 稳定性怎么保证?
GM4500 这种“高驱动、低噪声、高 GBW 运放”在这里的优势和坑?
我会给出一个“标准但非常好用”的设计模板,方便读者后续可以直接改参数复用。
设一个典型但很有代表性的需:

运放:GM4500
滤波类型:低通有源滤波
截止频率:fc = 100 kHz
通带增益:G = 1(或 2)
可以用在ADC 前端抗混叠,也可以传感器信号调理;做到既要低噪声,又要相位/幅度平滑
供电使用 OP 舒服的5 V 单电源,可以保证用到 OP 的满轨特性。
在这个前提下,最佳选择不是一阶 RC,也不是多级 RC 堆叠,而是:
二阶 Sallen-Key(SK)低通滤波器
结合 GM4500 的特性:
特性 | GM4500 | 对滤波器的影响 |
|---|---|---|
GBW = 28 MHz | 很高 | 适合 SK(对 GBW 敏感) |
输出电流 ±100 mA | 很强 | 能直接驱动电容网络 |
en ≈ 2.7 nV/√Hz | 低 | 适合做“低噪声滤波” |
相位裕量 69° | 偏激进 | SK 拓扑要控制 Q |
MFB 更适合低 GBW、低驱动运放,那GM4500 这种“硬输出级 + 高 GBW”非常适合 Sallen-Key。


二阶 Sallen-Key(SK)低通滤波器
Vin ──R1──┬── R2 ──┬──→ 运放 + 输入
| |
C1 C2
| |
GND GND
运放配置为非反相(或跟随)


Q = 0.707
设:
R1 = R2 = R
C1 = C2 = C
G = 1(电压跟随)
此时:

Q 不够,通带会下塌
保持:
R1 = R2 = R
C1 = C2 = C
把运放设为 非反相 G = 1.586
此时:


杨老师都说了,没有固定可言,我直接给出
选一个噪声 + 驱动都舒服的阻值:
R = 1.6 kΩ
C = 1 nF

例如:
Rg = 10 kΩ
Rf = 5.9 kΩ
运放电压噪声:2.7 nV/√Hz
电阻热噪声(1.6 kΩ):

这里是电阻热噪声主导
也就是不要用 >10 kΩ 的电阻,1 kΩ~3.3 kΩ 是 GM4500 的“甜区”(我觉得就是内部管子工作最舒服的地方)
GM4500:输出阻抗低,驱动电容很猛;那我强烈建议,在输出端串一个:Rs = 22 ~ 51 Ω;作用是抑制 SK 网络的高频 Q,作用可以防止 >1 MHz 处的寄生峰化,另外对幅频影响可忽略
经验规则:
GBW ≥ 20 × fc × Q
代入:
fc = 100 kHz
Q = 0.707
需要:

而 GM4500:GBW = 28 MHz,余量极大
GM4500:SR = 11 V/µs
100 kHz,1 Vpk 正弦所需:

也完全没压力
我们来用 GM4500 扩展成四阶 / 六阶有源低通滤波器
运放:GM4500
滤波类型:低通
总体响应:Butterworth(通带最平坦)
截止频率:fc = 100 kHz
供电:5 V
用途:ADC 抗混叠 / 传感器信号调理
每级:二阶 Sallen-Key(SK)
原则:每级 Q ≤ 1(稳),电阻 1–3 kΩ 区间(噪声 & 驱动最优)

复制上面的设计目标修改一下就行
四阶 Butterworth = 两个二阶节,Q 不相同:
级数 | Q 值 |
|---|---|
第 1 级 | 0.541 |
第 2 级 | 1.306 |
顺序是:低 Q → 高 Q(防止前级放大噪声 + 振铃)

非反相配置示例:
Rg = 10 kΩ
Rf = 12.4 kΩ
四阶幅频效果,按照道理是说;通带:极平坦;滚降:−80 dB/dec;相位:平滑、无异常峰,灰常非常适合 ADC 抗混叠
级数 | Q |
|---|---|
第 1 级 | 0.518 |
第 2 级 | 0.707 |
第 3 级 | 1.932 |
顺序必须是:低 → 中 → 高 Q
级 | Q | G = 3 − 1/Q |
|---|---|---|
1 | 0.518 | 1.07 |
2 | 0.707 | 1.586 |
3 | 1.932 | 2.48 |
R = 1.6 kΩ
C = 1 nF
fc ≈ 100 kHz(所有级)
六阶幅频效果(工程结论)

可以是比上面几个滤波器猛的,放心吧!
滚降:−120 dB/dec
对 Nyquist 附近抑制极强
ADC 抗混叠能力明显强于四阶。
代价也不大,不过就是:

看看得了,二阶做好了,别人也得夸你靓仔
噪声 ↑功耗 ↑相位延迟 ↑(作者已经有点疯了)
GM4500:2.7 nV/√Hz
电阻噪声 > 运放噪声,这是为什么 R 不要做大

电阻大了你把握不住啊!
对于 未饱和、线性级联:
注意:这是 输入等效噪声,还要乘前级总增益
16 bit LSB ≈ 76 µV;四阶噪声 ≈ 0.034 LSB RMS;六阶噪声 ≈ 0.042 LSB RMS, 完全 OK,不是瓶颈。

22–47 Ω,抑制 SK 对电容负载的 Q 放大
每级输入前可留 100–220 Ω 级间隔离,防止高 Q 级反向“吃前级”
低 Q → 高 Q,电源去耦 0.1 µF + 4.7 µF 就地(电容不要省,扣着二毛钱,难成大事)
把“上面几个滤波器”做了可视化对比仿真,并输出了三类图:

RC:滚降最慢(−20 dB/dec),对抗混叠最弱,但代价最小。
2nd/4th/6th:阶数越高,滚降越陡(分别约 −40/−80/−120 dB/dec),阻带抑制显著增强。
RC + 4th/6th:高频抑制最强,但也会更“重”,对动态建立更不友好。
如果你的 ADC 需要更强的前端抗混叠,阶数是最有效的手段;RC 单独通常不够。

RC 相位最终趋近 −90°
二阶趋近 −180°
四阶趋近 −360°
六阶趋近 −540°
加了 RC 以后相位再多 −90°
对“波形形状/控制回路/瞬态响应”敏感的系统,高阶滤波会引入明显相位滞后。

阶跃响应能直接映射到前面关心的“建立时间”和“ADC 缓冲是否拖慢”:
阶数越高:上升越慢、更容易出现更明显的动态形态变化
RC + 高阶:最慢(这就是你前面看到的“RC 会成为主导慢极点”的另一种体现)
注意:这张阶跃图里曲线最终值不都等于 1,是因为我们用的是每级带增益 G的二阶模型(对应 Sallen-Key 的实现方式)。
现在看到的曲线包含这几组(与我们前面讨论基本上一致):
一阶 RC 抗混叠:R=1 kΩ、C=1 nF(fc≈159 kHz)
二阶(Q=0.707):典型 Butterworth 二阶级
四阶 Butterworth:两级二阶级联(Q=0.541、1.306)
六阶 Butterworth:三级二阶级联(Q=0.518、0.707、1.932)
RC + 四阶 / RC + 六阶:前级 RC + 有源滤波级联
同时我把用于可视化的关键数值打印出来,方便核对与复现:
Stage f0 = 100 kHz
RC fc = 159.2 kHz
四阶各级增益(对应 Sallen-Key equal-RC 的关系 ):1.152、2.234
六阶各级增益:1.069、1.586、2.482
Design summary:
Stage f0 = 100.0 kHz
RC fc = 159.2 kHz (R=1k, C=1nF)
4th-order Qs: 0.541 1.306 Gains: 1.152 2.234
6th-order Qs: 0.518 0.707 1.932 Gains: 1.069 1.586 2.482
import numpy as np
import matplotlib.pyplot as plt
from scipy import signal
# ---------- Helper functions ----------
def lp2_stage_tf(f0_hz: float, Q: float, G: float = 1.0):
"""2nd-order low-pass stage: H(s)=G*w0^2/(s^2 + (w0/Q)s + w0^2)"""
w0 = 2 * np.pi * f0_hz
num = [G * w0**2]
den = [1.0, (w0 / Q), w0**2]
return signal.TransferFunction(num, den)
def lp1_rc_tf(fc_hz: float):
"""1st-order RC low-pass: H(s)=1/(1 + s/wc)"""
wc = 2 * np.pi * fc_hz
return signal.TransferFunction([wc], [1.0, wc])
def cascade(tfs):
"""Cascade a list of TransferFunction objects (continuous-time)."""
num = np.array([1.0])
den = np.array([1.0])
for tf in tfs:
num = np.polymul(num, tf.num)
den = np.polymul(den, tf.den)
return signal.TransferFunction(num, den)
def bode_mag_phase(tf, w):
w_out, mag_db, phase_deg = signal.bode(tf, w=w)
return w_out/(2*np.pi), mag_db, phase_deg
# ---------- Filters to visualize ----------
f0 = 100e3 # stage natural frequency (Hz)
# 2nd-order Butterworth (Q=0.707), SK equal-RC implies gain G=1.586
Q_2 = 0.707
G_2 = 1.586
H_2nd = lp2_stage_tf(f0, Q_2, G_2)
# 4th-order Butterworth via two biquads
Q4_1, Q4_2 = 0.541, 1.306
G4_1, G4_2 = 3 - 1/Q4_1, 3 - 1/Q4_2
H_4th = cascade([lp2_stage_tf(f0, Q4_1, G4_1), lp2_stage_tf(f0, Q4_2, G4_2)])
# 6th-order Butterworth via three biquads
Q6_1, Q6_2, Q6_3 = 0.518, 0.707, 1.932
G6_1, G6_2, G6_3 = 3 - 1/Q6_1, 3 - 1/Q6_2, 3 - 1/Q6_3
H_6th = cascade([lp2_stage_tf(f0, Q6_1, G6_1), lp2_stage_tf(f0, Q6_2, G6_2), lp2_stage_tf(f0, Q6_3, G6_3)])
# Front-end RC anti-alias filter (R=1k, C=1nF)
fc_rc = 1 / (2 * np.pi * 1e3 * 1e-9)
H_RC = lp1_rc_tf(fc_rc)
# Combined
H_RC_4th = cascade([H_RC, H_4th])
H_RC_6th = cascade([H_RC, H_6th])
# ---------- Frequency axis ----------
f = np.logspace(2, 8, 2000) # 100 Hz to 100 MHz
w = 2 * np.pi * f
# ---------- Magnitude ----------
plt.figure()
for name, tf in [
("1st-order RC (fc≈159 kHz)", H_RC),
("2nd-order (Q=0.707)", H_2nd),
("4th-order Butterworth", H_4th),
("6th-order Butterworth", H_6th),
("RC + 4th-order", H_RC_4th),
("RC + 6th-order", H_RC_6th),
]:
ff, mag, _ = bode_mag_phase(tf, w)
plt.semilogx(ff, mag, label=name)
plt.xlabel("Frequency (Hz)")
plt.ylabel("Magnitude (dB)")
plt.title("Magnitude Response Comparison")
plt.grid(True, which="both")
plt.legend()
plt.show()
# ---------- Phase ----------
plt.figure()
for name, tf in [
("1st-order RC (fc≈159 kHz)", H_RC),
("2nd-order (Q=0.707)", H_2nd),
("4th-order Butterworth", H_4th),
("6th-order Butterworth", H_6th),
("RC + 4th-order", H_RC_4th),
("RC + 6th-order", H_RC_6th),
]:
ff, _, ph = bode_mag_phase(tf, w)
plt.semilogx(ff, ph, label=name)
plt.xlabel("Frequency (Hz)")
plt.ylabel("Phase (deg)")
plt.title("Phase Response Comparison")
plt.grid(True, which="both")
plt.legend()
plt.show()
# ---------- Step response ----------
t = np.linspace(0, 20e-6, 4000) # 0..20 us
plt.figure()
for name, tf in [
("2nd-order (Q=0.707)", H_2nd),
("4th-order Butterworth", H_4th),
("6th-order Butterworth", H_6th),
("RC + 4th-order", H_RC_4th),
("RC + 6th-order", H_RC_6th),
]:
tt, y = signal.step(tf, T=t)
plt.plot(tt*1e6, y, label=name)
plt.xlabel("Time (µs)")
plt.ylabel("Step Response (V/Vstep)")
plt.title("Step Response Comparison")
plt.grid(True)
plt.legend()
plt.show()
print("Design summary:")
print(f"Stage f0 = {f0/1e3:.1f} kHz")
print(f"RC fc = {fc_rc/1e3:.1f} kHz (R=1k, C=1nF)")
print("4th-order Qs:", Q4_1, Q4_2, " Gains:", round(G4_1,3), round(G4_2,3))
print("6th-order Qs:", Q6_1, Q6_2, Q6_3, " Gains:", round(G6_1,3), round(G6_2,3), round(G6_3,3))