4、ADC采样基础:ADC工作原理、采样定理、量化误差、采样率选择

各位同学,咱们今天聊聊ADC。说白了,ADC就是把模拟世界里的连续信号,翻译成数字芯片能听懂的0和1。做电动牙刷,你肯定得知道刷头碰到牙齿时,电机负载怎么变,电池电压掉没掉。这些都得靠ADC来感知。

我个人习惯,拿到一个新项目,第一件事就是先把ADC的采样率和分辨率定下来。为什么?因为这直接决定了你后面做滤波、做算法时,手里有多少「好牌」可以打。

4.1 ADC工作原理:它到底在干什么?

ADC,全称模数转换器。你可以把它想象成一个「测量员」。它每隔一小段时间,就去量一下输入电压是多少,然后报出一个数字。

常见的ADC类型有好几种,咱们嵌入式里最常用的是逐次逼近型(SAR ADC)。

  • 采样保持:先把当前时刻的电压「拍个照」,存起来。因为转换需要时间,电压不能变。
  • 逐次比较:内部有个DAC,从最高位开始猜。比如参考电压是3.3V,它先猜1.65V,比输入大?那这一位就是0。再猜0.825V……直到猜出所有位。
  • 输出数字码:最终得到一个二进制数,比如0x3FF(10位ADC的最大值)。

关键点:ADC的转换时间决定了它能跑多快。我见过有人用STM32的ADC,没配好时钟,结果转换时间比采样周期还长,数据全是乱的。

4.2 采样定理:别让信号「骗」了你

采样定理,也叫奈奎斯特定理。内容很简单:采样频率必须大于信号最高频率的两倍

为什么会这样?你想想看,如果你采样太慢,高频信号会伪装成低频信号混进来。这叫「混叠」。我在项目中遇到过,采集电机电流时,没加前置低通滤波器,结果100kHz的开关噪声被采样成了10kHz的波动,害我查了三天电路。

公式很简单:

fs > 2 * f_max

其中fs是采样率,f_max是信号里最高的频率成分。

我的建议:工程上一般取3~5倍。比如信号最高1kHz,采样率设5kHz比较稳妥。留点余量,心里踏实。

4.3 量化误差:ADC天生的「近视眼」

ADC输出的数字是离散的,但模拟信号是连续的。这就好比用一把只有厘米刻度的尺子去量毫米级的长度——你总会差那么一点点。

这个误差叫量化误差。对于N位的ADC,量化步长(LSB)是:

LSB = V_ref / (2^N)

比如10位ADC,参考电压3.3V,那么LSB = 3.3 / 1024 ≈ 3.22mV。也就是说,你测到的电压,真实值和读数之间最多差半个LSB,约1.6mV。

ADC位数 量化步长(3.3V参考) 最大量化误差
8位 12.9 mV ±6.45 mV
10位 3.22 mV ±1.61 mV
12位 0.806 mV ±0.403 mV
16位 0.050 mV ±0.025 mV

注意:量化误差是原理性的,没法消除。但你可以通过提高位数来减小它。不过位数高了,转换时间也长了,这是个取舍。

4.4 采样率选择:快还是慢?这是个问题

采样率选多少,得看你的信号长什么样。

  • 电池电压监测:变化很慢,几Hz就够了。我一般设10Hz,省电。
  • 电机电流检测:PWM开关频率可能是20kHz,但你想看的是平均电流,那采样率可以低一些,但前面必须加滤波。
  • 振动传感器:电动牙刷的振动频率大概在200~300Hz,采样率设1kHz以上比较靠谱。

我曾经犯过一个错:为了省电,把采样率设得很低,结果牙刷的振动波形完全失真,算法根本识别不出刷头是否压到了牙齿。后来老老实实把采样率提到2kHz,问题就解决了。

经验法则:先估算信号最高频率,然后采样率取3~5倍。如果MCU性能允许,稍微高一点没坏处。数据多了可以软件降采样,但数据少了,神仙也救不了。

4.5 实际配置示例(STM32)

拿STM32F103举例,配置ADC采样一个通道:

// 配置ADC1,12位分辨率,采样时间1.5个周期
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;  // 开启ADC时钟
ADC1->CR2 |= ADC_CR2_ADON;            // 使能ADC
ADC1->SMPR2 |= ADC_SMPR2_SMP0_0;      // 通道0采样时间:1.5周期
ADC1->SQR3 |= 0;                       // 规则序列1:通道0

// 启动转换
ADC1->CR2 |= ADC_CR2_SWSTART;
while(!(ADC1->SR & ADC_SR_EOC));       // 等待转换完成
uint16_t value = ADC1->DR;             // 读取结果

嗯,这里要注意:采样时间不能太短。如果信号源阻抗高,采样电容充不满,结果会偏小。我一般设7.5个周期以上,稳妥。

4.6 避坑指南

最后,分享几个我踩过的坑:

  • 参考电压要稳:ADC的精度直接取决于V_ref。如果V_ref是电源电压,而电源有纹波,那ADC结果也会跟着抖。我习惯用外部基准或LDO单独供电。
  • 输入阻抗匹配:ADC输入引脚有采样电容,如果信号源输出阻抗太高,需要加运放缓冲。
  • 别忘了抗混叠滤波:采样前一定要加RC低通滤波,截止频率设在采样率的1/3左右。这是硬道理。

我曾经在一个项目里,ADC读数总是跳来跳去。查了半天,发现是PCB走线太长,耦合了高频噪声。后来在ADC引脚旁边加了个100nF电容,世界清净了。

好了,ADC的基础就聊到这儿。下一节咱们讲具体的传感器接口电路设计,到时候会用到今天讲的知识。记住:采样率选对了,后面滤波就轻松;采样率选错了,后面全是坑。