首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >为什么有斩波前端的 ADC 还是标有一个 1/f 的噪音值?(YUNSWJ 仿真版)

为什么有斩波前端的 ADC 还是标有一个 1/f 的噪音值?(YUNSWJ 仿真版)

作者头像
云深无际
发布2026-01-07 11:18:36
发布2026-01-07 11:18:36
1200
举报
文章被收录于专栏:云深之无迹云深之无迹

本来事情到这里就完事了,但是我觉得还有疑问:

这里写了没有 1/f 噪音
这里写了没有 1/f 噪音

这里写了没有 1/f 噪音

但是 0.1Hz 的时候还有数,是不是写错了?

“No 1/f noise” 的真正含义是什么?

它并不是说:噪声 = 0,或者没有低频噪声,或者低频噪声密度趋近 0

而是说:

输入噪声谱密度在低频不随频率升高;没有出现 1/f 增长;即噪声谱是平坦的。

也就是说:

噪声是白噪声(flat noise)没有 1/f 拐点(corner frequency)没有典型 BJT/CMOS 输入级造成的粉红噪声隆起

所以:

“No 1/f noise” = 这个噪声密度在低频是“平坦的”,不是“为 0”。

而设备的白噪声本底,可以是:

9.5 nV/√Hz

12 nV/√Hz

30 nV/√Hz

…,这些都是“白噪声”而不是“1/f 噪声”。

为什么低频(0.1 Hz)给了一个数值?

因为要证明:0.1 Hz 这种极低频仍然是“白噪声水平”,没有往上飙(没有粉红噪声)

典型有 1/f 噪声的器件,在 0.1 Hz 的噪声密度会变成:

100 nV/√Hz

300 nV/√Hz

1 μV/√Hz

而斩波放大器(CHOP/Auto-zero)会把 1/f 噪声搬移到高频(调制频率),因此在 DC 附近只有白噪声本底;这正是为什么 0.1 Hz 给的就是 9.5 nV/√Hz(和中频几乎一样)。

斩波放大器为何能做到“无 1/f 噪声”?

斩波原理:把输入调制到几十 kHz(斩波频率),在高频处放大,再解调回低频,所有低频噪声(1/f)都被搬移到了高频(调制频率附近),输出端有低通滤波器 → 高频噪声全被滤掉,最后 DC / 低频区域只剩白噪声

因此:0.1 Hz(甚至到 10 mHz)处都不再看到 1/f 噪声上升,噪声密度是“平顶(white)+ 极低”

9.5 nV/√Hz 是否意味着“有低频噪声”?

不是。那是白噪声本底,不是频率相关噪声。

看到的是:噪声的绝对大小(白噪声水平),而1/f 噪声指的是频率依赖型噪声

举例:

噪声类型

是否随频率变化?

例子

白噪声(No 1/f)

不变(flat)

9.5 nV/√Hz @ 0.1 Hz, 1 Hz, 10 Hz…

1/f 噪声(Pink noise)

随 f↓ 而 ↑

100 nV/√Hz @1Hz、1μV/√Hz @0.1Hz

斩波 ADC / INA 告诉你:

“低频只有白噪声,没有 1/f 噪声成分。”

为什么数据手册要同时写“9.5 nV/√Hz @0.1Hz” & “No 1/f”?

这是为了让工程师一眼确认:

“低频噪声密度是多少?”(绝对值)

“有没有 1/f”?(噪声类型)

所以两行一起看才精准:

9.5 nV/√Hz → 白噪声本底很低

No 1/f → 低频噪声不随频率上升

这是测量仪器、称重、压力传感等 24-bit ΔΣ ADC 必须具备的特性。

“No 1/f” 并不是“噪声=0”,而是指“低频噪声保持在白噪声本底,不随频率升高”;9.5 nV/√Hz 是白噪声本底的数值,不是 1/f 噪声;这两者完全不矛盾。

仿真一下

频谱层面:“有 1/f” vs “No 1/f(斩波)”

人为设定的理论噪声谱

代码里先做了一个理论 ASD(幅度谱密度)

代码语言:javascript
复制
f = np.logspace(-3, 3, 1000)   # 1 mHz ~ 1 kHz
en_white = 10e-9               # 10 nV/√Hz 白噪声本底
fc = 1.0                        # 1 Hz 拐点

# 无 1/f:纯白噪声
en_flat = en_white * np.ones_like(f)

# 有 1/f:低频上升 ~ sqrt(fc/f)
en_1f = en_white * np.sqrt(1 + fc / f)

蓝线(无 1/f):从 1 mHz 到 1 kHz 都在 10 nV/√Hz 基本不动。

橙线(有 1/f):在高频(f ≫ 1Hz)≈ 10 nV/√Hz;低于 1Hz 开始往上长,比如 0.01 Hz 处大约 10×,即 ≈ 100 nV/√Hz。

这张图就是平时在运放手册里看到的那种:

右边平、左边翘 → 有 1/f;

全平 → 斩波 / Auto-zero / No 1/f。

“9.5 nV/√Hz @0.1Hz, No 1/f” 的真正含义就是: 在 0.1Hz 这种极低频,噪声谱 STILL ≈ 白噪声本底,没有翘起来。

用 Python 真的生成一段“有 1/f / 无 1/f”的噪声

前面那张只是理论曲线,接下来我在时域做了一个更真实的仿真。

先生成一段白噪声

代码语言:javascript
复制
Fs = 1000.0       # 采样率 1 kS/s
T_total = 200.0   # 总时长 200 s
N = int(Fs * T_total)

np.random.seed(0)
x_white = np.random.normal(0, 1.0, N)   # 纯白噪声

用频域塑形做“带 1/f”噪声

代码语言:javascript
复制
Xw = np.fft.rfft(x_white)
freqs = np.fft.rfftfreq(N, d=1/Fs)
H_1f = np.sqrt(1 + fc / np.maximum(freqs, 1e-6))
H_1f[0] = 0.0  # DC 处避免无穷大
X_1f = Xw * H_1f
x_1f = np.fft.irfft(X_1f, n=N)

先算白噪声的 FFT:Xw

乘上一个 形状函数H_1f(f)=sqrt(1+fc/f) → 低频放大、高频不变

再 IFFT 回时域:得到 x_1f,就是“带 1/f 成分”的噪声

然后用 Welch 方法估 ASD:

代码语言:javascript
复制
freqs_est, asd_white = estimate_asd(x_white, Fs)
_, asd_1f_est = estimate_asd(x_1f, Fs)

第二张频谱图(“仿真得到的噪声谱密度”)就证明:

蓝线(x_white):谱基本平的;

橙线(x_1f):在 1 Hz 以下明显抬起来,符合 1/f 的形状。

这说明我们构造的时域随机序列确实有“1/f 噪声”特征。

平均 10s 时为什么斩波 ADC 的 RMS 噪声超低?

做法:不同平均时间下“平均值的 RMS”

我们对两段噪声序列 x_white / x_1f,用不同的平均时间 做块平均:

代码语言:javascript
复制
def rms_of_averaged(x, Fs, T_avg_list):
    rms_list = []
    for T in T_avg_list:
        L = int(T * Fs)                 # 每块样本数
        nseg = len(x) // L
        segs = x[:nseg*L].reshape(nseg, L)
        means = segs.mean(axis=1)       # 每块的平均值
        rms_list.append(np.sqrt(np.mean(means**2)))  # 这些平均值的 RMS
    return np.array(rms_list)

T_list = np.logspace(-1, 2, 20)  # 0.1s ~ 100s
rms_white = rms_of_averaged(x_white, Fs, T_list)
rms_1f = rms_of_averaged(x_1f, Fs, T_list)

最后画出的图(平均时间 vs RMS 噪声)非常关键:

横轴:平均时间 (0.1 s → 100 s,log 标度)

纵轴:每块平均值的 RMS(log 标度)

蓝线:无 1/f(白噪声)

橙线:有 1/f

从图上你能看到:

白噪声(无 1/f):

RMS 噪声随 几乎理想地按 下降;比如从 0.1s → 10s,时间 ×100 倍,RMS 大约 /√100 = /10;

这就是你在 ΔΣ ADC 手册里看到:

“多做平均(更多码)、更低 ODR,噪声几乎按 带宽 降低。”

换到 ADC 语境就是: 集成 10 秒,等效带宽只有几十分之一 Hz,白噪声被平均得非常低,就能看到几十 nV 级别的总 RMS 噪声。

有 1/f 噪声:

一开始(T < 1s)下降趋势还不错,因为高频部分还是白噪声;但当平均时间拉到几秒、几十秒以后,曲线明显“平起来”,不再按 1/√T 降那么快,甚至趋向于一个平台;这就是典型:

低频 1/f 噪声主导后,平均时间越长,只是在“看更长期的漂移”,噪声不再被充分平均。

你可以直接把它和“精密基准的长期漂移 / 运放的 1/f 噪声”联系起来理解: 放得越久,看到的更多是慢漂,不是随机噪声。

三张图翻译回你关心的斩波 ADC 场景

频谱层面:

斩波 ADC / INA:ASD 在 DC 附近平坦 → “No 1/f noise”。

普通放大器:ASD 在 1 Hz 以下上升 → “有 1/f noise”。

时间域 RMS 噪声 vs 平均时间:

斩波 ADC:只剩白噪声 → 平均 10 秒,噪声 ~ 原来的 1/√(10s·BW),可以轻松压到几十 nV 级。

有 1/f 的系统:长期平均被 1/f 漂移限制,再怎么拉长时间也降不下去。

结合 CS5530 / LHA7530:

数据手册写“9.5 nV/√Hz @0.1Hz, No 1/f noise”,就是在告诉你: 低频只有 9.5 nV/√Hz 的白噪声,没有额外的 1/f “抬升”;所以你在 5~10 SPS(相当于带宽 < 3 Hz)下可以看到极低的 RMS 噪声和 19~20 bit 的 noise-free 分辨率,这是数学上自然的结果,不是“魔法”。

代码语言:javascript
复制
import numpy as np
import matplotlib.pyplot as plt

# =========================
# 1. 频谱对比: 有 1/f vs 无 1/f
# =========================

# 频率轴: 1e-3 Hz ~ 10^3 Hz
f = np.logspace(-3, 3, 1000)
en_white = 10e-9   # 白噪声本底 10 nV/√Hz
fc = 1.0           # 1/f 拐点频率 1 Hz

# 无 1/f: 纯白噪声
en_flat = en_white * np.ones_like(f)

# 有 1/f: 低于 fc 时上升 ~ sqrt(fc/f)
en_1f = en_white * np.sqrt(1 + fc / f)

plt.figure()
plt.loglog(f, en_flat*1e9, label="无 1/f (斩波, 白噪声平坦)")
plt.loglog(f, en_1f*1e9, label="有 1/f (普通放大器)")
plt.axvline(fc, linestyle="--")
plt.xlabel("频率 / Hz")
plt.ylabel("电压噪声谱密度 / nV/√Hz")
plt.title("有 1/f 噪声 vs 无 1/f 噪声 的 ASD 对比")
plt.legend()
plt.grid(True, which="both")

# =========================
# 2. 时间域仿真: 平均 10s 时 RMS 噪声
# =========================

Fs = 1000.0          # 采样率 1 kS/s
T_total = 200.0      # 总时长 200 s
N = int(Fs * T_total)

# 生成一段白噪声
np.random.seed(0)
x_white = np.random.normal(0, 1.0, N)

# 通过频域塑形生成 "带 1/f" 噪声
Xw = np.fft.rfft(x_white)
freqs = np.fft.rfftfreq(N, d=1/Fs)
H_1f = np.sqrt(1 + fc / np.maximum(freqs, 1e-6))
H_1f[0] = 0.0  # DC 分量设 0,避免发散
X_1f = Xw * H_1f
x_1f = np.fft.irfft(X_1f, n=N)

# 验证频谱: 估算两种噪声的 ASD
def estimate_asd(x, Fs, nfft=16384):
    w = np.hanning(nfft)
    step = nfft // 2
    segs = (len(x) - nfft) // step
    psd = np.zeros(nfft//2 + 1)
    for i in range(segs):
        seg = x[i*step:i*step+nfft] * w
        X = np.fft.rfft(seg)
        psd += (np.abs(X)**2) / (Fs * np.sum(w**2))
    psd /= segs
    freqs = np.fft.rfftfreq(nfft, d=1/Fs)
    asd = np.sqrt(psd)
    return freqs, asd

freqs_est, asd_white = estimate_asd(x_white, Fs)
_, asd_1f_est = estimate_asd(x_1f, Fs)

plt.figure()
plt.loglog(freqs_est[1:], asd_white[1:], label="无 1/f (仿真)")
plt.loglog(freqs_est[1:], asd_1f_est[1:], label="有 1/f (仿真)")
plt.axvline(fc, linestyle="--")
plt.xlim(1e-1, 1e3)
plt.xlabel("频率 / Hz")
plt.ylabel("电压噪声谱密度 (任意单位)")
plt.title("仿真得到的噪声谱密度: 有 / 无 1/f")
plt.legend()
plt.grid(True, which="both")

# =========================
# 3. 统计平均时间 vs RMS 噪声
# =========================

def rms_of_averaged(x, Fs, T_avg_list):
    rms_list = []
    for T in T_avg_list:
        L = int(T * Fs)
        nseg = len(x) // L
        if nseg == 0:
            rms_list.append(np.nan)
            continue
        segs = x[:nseg*L].reshape(nseg, L)
        means = segs.mean(axis=1)
        rms_list.append(np.sqrt(np.mean(means**2)))
    return np.array(rms_list)

T_list = np.logspace(-1, 2, 20)  # 0.1 s ~ 100 s
rms_white = rms_of_averaged(x_white, Fs, T_list)
rms_1f = rms_of_averaged(x_1f, Fs, T_list)

plt.figure()
plt.loglog(T_list, rms_white, 'o-', label="无 1/f (白噪声)")
plt.loglog(T_list, rms_1f, 'o-', label="有 1/f")
plt.xlabel("平均时间 T / s")
plt.ylabel("平均值的 RMS 噪声 (任意单位)")
plt.title("平均时间 vs RMS 噪声:有 / 无 1/f")
plt.grid(True, which="both")
plt.legend()
plt.show()
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-11-29,如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • “No 1/f noise” 的真正含义是什么?
    • “No 1/f noise” = 这个噪声密度在低频是“平坦的”,不是“为 0”。
  • 为什么低频(0.1 Hz)给了一个数值?
  • 斩波放大器为何能做到“无 1/f 噪声”?
    • 9.5 nV/√Hz 是否意味着“有低频噪声”?
    • 为什么数据手册要同时写“9.5 nV/√Hz @0.1Hz” & “No 1/f”?
    • 仿真一下
    • 频谱层面:“有 1/f” vs “No 1/f(斩波)”
      • 人为设定的理论噪声谱
    • 用 Python 真的生成一段“有 1/f / 无 1/f”的噪声
      • 先生成一段白噪声
      • 用频域塑形做“带 1/f”噪声
    • 平均 10s 时为什么斩波 ADC 的 RMS 噪声超低?
      • 做法:不同平均时间下“平均值的 RMS”
    • 三张图翻译回你关心的斩波 ADC 场景
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档