共计 2262 个字符,预计需要花费 6 分钟才能阅读完成。
为什么需要 ADC?
想象一下用示波器测量温度传感器输出的电压信号,或者用麦克风录制声音——这些连续变化的模拟信号,必须转换成数字量才能被单片机或计算机处理。这就是 ADC(Analog-to-Digital Converter)的核心任务:将连续的电压信号,离散化为二进制数字。比如常见的 12 位 ADC,能把 0 -3.3V 的电压分成 4096(2^12)个台阶,每个台阶代表约 0.8mV 的变化。

采样定理:抓准信号的节奏
Nyquist 采样定理
ADC 的第一步是采样,核心规则来自 Nyquist 定理:采样频率 $f_s$ 必须大于信号最高频率 $f_{max}$ 的 2 倍,即:
$$ f_s > 2f_{max} $$
否则会出现混叠(Aliasing)——高频信号被误认为低频。例如用 40kHz 采样率录制 20.1kHz 的音频,实际会听到 $40-20.1=19.9kHz$ 的错误频率。
过采样技术
工程中常采用 4 - 8 倍过采样,比如音频采集常用 44.1kHz(CD 标准)而非刚好 40kHz。优点包括:
- 降低抗混叠滤波器设计难度
- 通过后续数字滤波提高信噪比
- 公式推导:过采样每增加 4 倍,有效位数增加 1bit
Python 实战:12 位 ADC 量化模拟
生成测试信号
我们先产生一个 1kHz 的正弦波,模拟传感器输出:
import numpy as np
import matplotlib.pyplot as plt
fs = 8000 # 采样率 8kHz
t = np.arange(0, 0.01, 1/fs) # 10ms 时间序列
f_signal = 1000 # 信号频率 1kHz
amplitude = 1.5 # 幅值 1.5V
v_ref = 3.3 # ADC 参考电压
analog_signal = amplitude * np.sin(2 * np.pi * f_signal * t)
量化过程实现
12 位 ADC 的量化台阶数量为 4096,量化步长 (LSB) 计算:
$$ LSB = \frac{V_{ref}}{2^{12}} = \frac{3.3}{4096} \approx 0.000805V $$
量化代码实现:
# 模拟 12 位 ADC 量化
def adc_quantize(signal, v_ref, bits=12):
digital = np.round(signal / v_ref * (2**bits - 1))
analog_reconstructed = digital * v_ref / (2**bits - 1)
return digital, analog_reconstructed
# 执行量化
digital_code, quantized_signal = adc_quantize(analog_signal, v_ref)
# 计算量化误差
quant_error = analog_signal - quantized_signal
结果可视化
plt.figure(figsize=(12, 8))
# 原始信号与量化信号对比
plt.subplot(3, 1, 1)
plt.plot(t, analog_signal, 'b-', label='原始信号')
plt.step(t, quantized_signal, 'r-', where='post', label='量化信号')
plt.ylabel('电压(V)')
plt.legend()
# 量化误差展示
plt.subplot(3, 1, 2)
plt.plot(t, quant_error, 'g-')
plt.ylabel('量化误差(V)')
# 数字码值显示
plt.subplot(3, 1, 3)
plt.stem(t[::20], digital_code[::20], 'k-', markerfmt='ko') # 降采样显示
plt.ylabel('数字码值')
plt.xlabel('时间(s)')
plt.tight_layout()
plt.show()
运行后会看到三张图:蓝色原始信号与红色阶梯状量化信号的对比、绿色量化误差曲线、以及底部 ADC 输出的数字码值。特别注意量化误差在±0.5LSB 范围内的特性。
工程实践关键点
抗混叠滤波器设计
- 截止频率:必须低于 $f_s/2$(奈奎斯特频率)
- 过渡带陡度:根据信号频带与采样率差值确定
- 推荐使用巴特沃斯或切比雪夫滤波器,例如:
from scipy.signal import butter, lfilter
def antialiasing_filter(signal, cutoff, fs, order=4):
nyq = 0.5 * fs
normal_cutoff = cutoff / nyq
b, a = butter(order, normal_cutoff, btype='low')
filtered = lfilter(b, a, signal)
return filtered
有效位数 (ENOB) 测量
实际 ADC 受噪声影响,有效位数通常小于标称值。测量方法:
- 输入满幅正弦波
- 采集足够多周期数据
- 计算信噪比(SNR):
$$ SNR = 6.02 \times ENOB + 1.76 $$ - 反推 ENOB 值
参考电压稳定性
$V_{ref}$ 的波动会直接影响量化精度。建议:
- 使用专用基准电压芯片(如 TL431)
- PCB 布局时远离高频或大电流走线
- 增加 0.1μF 去耦电容
动手实验建议
- 混叠现象实验:尝试用 1kHz 采样率采集 600Hz 和 800Hz 信号,观察频谱变化
- 量化位数对比:修改代码为 8 位 ADC,对比信号保真度差异
- 过采样效果:用 16kHz 采样率采集 1kHz 信号,对比原始频谱与降采样后的频谱
通过这些小实验,你会直观理解采样定理和量化精度的实际意义。建议使用 Python 的 scipy.fft 模块进行频谱分析,观察不同参数下的频率成分变化。
