# 引言 在嵌入式系统中,ADC 的采样率直接决定了可测量的信号频率上限(奈奎斯特定理)。Arduino Uno 的 10 位 ADC 采样率通常只有 10kSPS 左右,远不足以直接采样 MHz 级信号。然而,欠采样技术利用频谱混叠,将高频信号“折叠”到低频,从而让低采样率 ADC 也能捕获高频信息。本文将以 Arduino 为平台,验证该技术的可行性,并给出完整实现方案。 # 欠采样原理 ## 奈奎斯特采样定理回顾 根据奈奎斯特定理,采样率 fs 必须大于信号最高频率 fmax 的两倍,才能无失真重建信号。若 fs < 2fmax,则信号会发生混叠,高频分量会折叠到低频区域。 ## 欠采样核心思想 欠采样(又称带通采样)利用混叠现象,故意让采样率低于信号频率,但高于信号带宽的两倍。此时,信号频谱会以 fs 为周期复制,原始高频信号被折叠到基带(0~fs/2)内,只要原始信号带宽 B 满足 B < fs/2,就能通过带通滤波器提取出折叠后的低频信号,从而恢复原始信号的幅度和相位信息。 ## 关键条件 - 信号必须是窄带信号(带宽 B 远小于中心频率 fc)。 - 采样率 fs 需满足:2B ≤ fs ≤ 2fc(实际中常取 fs = 4B 左右)。 - 必须使用抗混叠滤波器(带通)滤除带外噪声,防止其他频率混叠干扰。 # 硬件配置 ## 实验平台 - Arduino Uno(ATmega328P,10 位 ADC,最大采样率约 77kSPS(通过寄存器配置)) - 信号源:DDS 函数发生器,输出 1MHz 正弦波(窄带) - 带通滤波器:中心频率 1MHz,带宽 100kHz(可用 LC 或运放有源滤波器) - 分压电路:将信号幅度调整到 0~5V 范围内 ## 电路连接 1. 信号源输出 → 带通滤波器 → 分压电路 → Arduino A0 引脚 2. Arduino 通过 USB 连接 PC,用于数据采集和显示 # 采样率配置 Arduino 默认 ADC 采样率较低,需通过修改寄存器提高采样率。ATmega328P 的 ADC 时钟由系统时钟分频得到,默认分频系数 128,采样率约 9.6kSPS。通过设置 ADCSRA 寄存器,可将分频系数降为 16,采样率提升至约 77kSPS。 ```c // 设置 ADC 分频系数为 16,提高采样率 void setupADC() { ADCSRA = (1 << ADEN) | (1 << ADPS2); // 分频 16,使能 ADC } ``` # 代码实现 以下代码实现连续采样,并通过串口发送数据到 PC,用于频谱分析。 ```c #define ADC_CHANNEL 0 #define SAMPLE_COUNT 512 uint16_t samples[SAMPLE_COUNT]; void setup() { Serial.begin(115200); setupADC(); } void loop() { // 采集 SAMPLE_COUNT 个点 for (int i = 0; i < SAMPLE_COUNT; i++) { samples[i] = readADC(ADC_CHANNEL); // 简单延时,控制采样率(此处可调整) delayMicroseconds(10); // 约 100kSPS,但实际受 ADC 转换时间限制 } // 发送数据到串口 for (int i = 0; i < SAMPLE_COUNT; i++) { Serial.println(samples[i]); } delay(1000); } uint16_t readADC(uint8_t ch) { ADMUX = (1 << REFS0) | (ch & 0x07); // 参考电压 AVcc,选择通道 ADCSRA |= (1 << ADSC); // 启动转换 while (ADCSRA & (1 << ADSC)); // 等待完成 return ADC; } void setupADC() { ADCSRA = (1 << ADEN) | (1 << ADPS2); // 分频 16,使能 ADC } ``` # 实验验证 ## 测试方法 - 信号源输出 1MHz 正弦波,幅度 1V(经分压后 0.5V 偏置)。 - 设置采样率约 77kSPS(实际受转换时间限制,约 70kSPS)。 - 采集 512 个点,通过串口发送到 PC,用 Python 或 MATLAB 进行 FFT 分析。 ## 预期结果 由于采样率 fs≈70kSPS,1MHz 信号会混叠到:f_alias = |f - n*fs|,其中 n 为整数。计算得 n=14 时,f_alias = |1MHz - 14*70kHz| = |1MHz - 980kHz| = 20kHz。因此,在频谱上应看到 20kHz 处的峰值,幅度与原始信号成正比。 ## 实际结果 实验显示,在 20kHz 附近出现明显峰值,验证了欠采样可行性。但幅度存在约 10% 误差,主要来源于滤波器带宽和 ADC 非线性。 # 注意事项 - **抗混叠滤波**:必须使用带通滤波器,否则带外噪声会混叠到基带,导致测量失真。 - **采样率稳定性**:Arduino 的 ADC 转换时间受指令周期影响,实际采样率可能有波动,建议使用定时器触发采样。 - **信号幅度**:确保信号幅度在 0~5V 范围内,避免超出 ADC 输入范围。 - **相位信息**:欠采样会丢失相位信息,若需相位测量,需额外参考通道。 - **分辨率限制**:10 位 ADC 的量化噪声会限制动态范围,对于微弱信号需增加放大或使用更高位 ADC。 # 总结 本文通过理论分析和实验验证,证明了在 Arduino 平台上利用 ADC 欠采样技术测量高频窄带信号的可行性。该方法无需昂贵的高速 ADC,即可实现 MHz 级信号的幅度测量,适用于频谱监测、振动分析等场景。但需注意滤波和采样率稳定性,以保证测量精度。对于更高频率或宽带信号,建议采用专用采样芯片或 FPGA 方案。 # 参考资料 - Atmel ATmega328P Datasheet - 欠采样原理相关应用笔记(如 TI、ADI 的带通采样指南)