共计 1427 个字符,预计需要花费 4 分钟才能阅读完成。
从示波器噪声到高精度采集的优化之路
最近在做一个医疗设备项目时,发现 ADC 采集的 ECG 信号总有些毛刺(如图 1)。用示波器 FFT 功能一看,明显存在量化噪声。这促使我系统研究了 ADC 噪声处理方案,最终将有效分辨率从 10 位提升到了 14 位。

量化噪声的信噪比 (SNR) 计算公式为:
SNR = 6.02N + 1.76dB + 10\log_{10}(OSR)
其中 N 是 ADC 位数,OSR 是过采样率。这公式揭示了提升精度的两个关键:硬件位深和软件处理。
一、过采样技术的数学魔法
-
√N 法则的推导
假设噪声均匀分布,过采样 4 倍时噪声功率分散到更宽频带,通过数字滤波保留有效带宽后,噪声电压幅值降低为原来的 1 /2(即分辨率提升 1 位):\Delta ENOB = \frac{1}{2}\log_2(OSR) -
实战中的折衷
虽然理论上 OSR 越高越好,但实际要考虑: - STM32F407 的 ADC 时钟最高 36MHz
- DMA 缓冲区大小限制
- 实时性要求
二、数字滤波器的选型实验
用 Python 快速验证不同窗函数效果:
import scipy.signal as signal
# 设计 128 阶 FIR 滤波器
h_hamming = signal.firwin(128, 0.5, window='hamming')
h_blackman = signal.firwin(128, 0.5, window='blackman')
# 频响对比
f, H1 = signal.freqz(h_hamming)
f, H2 = signal.freqz(h_blackman)
plt.plot(f, 20*np.log10(np.abs(H1)))
实测发现:
– Hamming 窗:过渡带较窄(3.3dB/oct),适合带宽紧张时
– Blackman 窗:阻带衰减更好(58dB),适合严格抑制噪声
三、硬件设计关键点
在 PCB 布局上踩过的坑:
1. 模拟电源必须用 LC 滤波(如 10μH+10μF)
2. ADC 参考引脚要加 0.1μF 陶瓷电容 +1μF 钽电容组合
3. 信号走线远离晶振和数字总线
四、STM32 实战代码
使用 DMA 双缓冲模式避免数据丢失:
// ADC 初始化片段
hadc.Instance = ADC1;
hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc.Init.Resolution = ADC_RESOLUTION_12B;
hadc.Init.ScanConvMode = ENABLE;
HAL_ADC_Start_DMA(&hadc, (uint32_t*)adc_buf, BUF_SIZE);
// CRC 校验示例
__HAL_CRC_DR_RESET(&hcrc);
uint32_t crc = HAL_CRC_Calculate(&hcrc, (uint32_t*)adc_buf, BUF_SIZE/4);
五、性能验证数据
| 采样率 | 原始 ENOB | 处理后 ENOB |
|---|---|---|
| 1kHz | 10.2 位 | 12.8 位 |
| 10kHz | 9.8 位 | 13.5 位 |
| 100kHz | 9.1 位 | 12.3 位 |
六、生产环境建议
- 温度补偿:在固件中存储 ADC 的校准参数,根据板载温度传感器动态调整
- 动态范围优化:对于 ECG 等特定信号,可自动切换 PGA 增益
- OTA 策略:在 Flash 末尾保留 4KB 专用扇区存储校准数据,升级时跳过该区域
经过三个月实际运行,这套方案使我们的血氧仪测量精度达到±1%,比行业标准要求的±3% 提升显著。最关键的是,所有优化都不需要更换硬件,纯靠软件算法实现。下次遇到 ADC 精度问题,不妨试试过采样这把利器。
正文完
