在Σ-Δ ADC中频繁出现的说ODR:
image-20250721193322759
在 Σ-Δ ADC 中,“最小过采样率(Minimum Oversampling Ratio,OSR)”是指系统为了达到有效的噪声整形效果、滤除量化噪声而要求的最小采样倍率,当然了这个写的有些绝对了。
最小 OSR 是指调制器输出频谱中量化噪声尚未淹没在有用信号频带中的最小采样倍率。
:Σ-Δ 调制器的时钟频率(也就是它的采样率,称为 调制频率)
:有用信号带宽
分母中的 是 **奈奎斯特率 (Nyquist Rate)**,指带宽为 的信号的最小采样频率
Σ-Δ ADC 的本质是:
用远高于奈奎斯特频率的调制器时钟频率对输入信号进行采样,然后通过数字滤波 + 抽取 (decimation) 降低输出速率,并抑制量化噪声。
OSR 表示:
调制器工作频率与奈奎斯特频率的比值,等价于“每单位信号带宽内采样了多少次”。
量化噪声密度下降 ∝ OSR 的增长
ENOB 提高 ∝ log₂(OSR)
SNR(信噪比)提高 ∝ 3dB × 每倍 OSR
在 AD717x 等 ADC 数据手册中虽然未必明示 OSR,但从内部结构、调制器频率(如 8 MHz)、抽取率、带宽(3 dB BW)等参数可以间接计算:
目的:将量化噪声推到信号带宽之外(即高频);高阶调制器将噪声推到高频;低通数字滤波器将其滤除。
若 OSR 太低:带宽内仍存在大量量化噪声,导致 ENOB 降低、SNR 很差。
(当然数据手册里面是),ODR = 250 kSPS
则 OSR = 8 MHz / (2 × 250k) = 16;在该 OSR 下仍需使用 Sinc5 + Sinc1 才能压制调制器量化噪声;→ 说明在高 ODR(低 OSR)时,对滤波器抑制能力要求极高。
OSR(过采样率) :采样率相对于 Nyquist 频率的倍率,设计中需保证 OSR ≥ 最小值,才能获得预期分辨率。
频谱
在不同 OSR(过采样率)设置下,经过一阶 Σ-Δ 调制器与 FIR 低通滤波器处理后的输出频谱:
OSR = 8:低频量化噪声仍很强,SNR 较差
OSR = 16:噪声整形开始见效,低频干净些
OSR = 32:明显压制了低频噪声,信噪比提升
OSR = 64:低频信号区域基本干净,整形效果最佳
更高的 OSR 能有效压制 Σ-Δ 调制器的量化噪声,从而提升低频信号的质量和分辨率
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import lfilter, firwin, welch
# 模拟一个一阶 Σ-Δ 调制器
def sigma_delta_modulator(signal):
y = np.zeros(len(signal))
integrator = 0
for i in range(len(signal)):
integrator += signal[i] - y[i - 1] if i > 0 else signal[i]
y[i] = 1.0 if integrator >= 0 else -1.0
return y
# 模拟输入信号(低频正弦波)
fs_mod = 1024 * 64 # 调制器频率
duration = 1.0
t = np.arange(0, duration, 1/fs_mod)
input_signal = 0.5 * np.sin(2 * np.pi * 50 * t)
# 设定不同 OSR 对应的信号带宽
osr_list = [8, 16, 32, 64]
fig, axs = plt.subplots(len(osr_list), 1, figsize=(10, 10), sharex=True)
for idx, osr in enumerate(osr_list):
bw = fs_mod / (2 * osr) # 信号带宽
fir_len = 101
fir = firwin(fir_len, cutoff=bw / (fs_mod / 2))
modulated = sigma_delta_modulator(input_signal)
filtered = lfilter(fir, 1.0, modulated)
# FFT 分析
f, Pxx = welch(filtered, fs=fs_mod, nperseg=4096, scaling='spectrum')
axs[idx].semilogx(f, 10 * np.log10(Pxx + 1e-12))
axs[idx].set_title(f'OSR = {osr}, BW = {bw:.1f} Hz')
axs[idx].set_ylabel('dB')
axs[idx].grid(True)
axs[-1].set_xlabel('Frequency (Hz)')
plt.tight_layout()
plt.show()