过采样提高ADC的信噪比
ADC测量的SNR理论极限基于量化噪声,这是基于在没有过采样和平滑滤波情况下模数转换过程中固有的量化误差所致。而量化误差取决于ADC分辨率的位数,其中N为ADC的位数, 为参考电压。
SNR理论情况下极限值的计算方式是数据转换的有效位数,如下所示:
这个公式没必要去记,用到的时候参考计算一下即可。从公式中可看出,要提升一个模数转换器的理论SNR的一种可行方案可以通过提升采样位数, 但是需要注意的是这里的信噪比是度量模数转换器本身的,就一个真实系统的信噪比还与整个信号链相关!
从上式中不难算出,12位ADC的理论SNR极限值为74dB,而通过过采样提升4位分辨率后,其SNR理论极限提高至96 dB!
到底怎么实现呢?
这里以伪代码的方式给出编程思路:
voidinit_adc( void)
{
/*配置ADC的采样率为过采样率连续中断模式*/
}
voidstart_adc( void)
{
/*控制ADC启动采样*/
}
/*不同的开发平台中断函数写法略有差异,比如51需要指定向量 */
/*OVERSAMPLE_FACTOR=4^RSHIFT_BITS 下面两个宏一起修改 */
# defineRSHIFT_BITS (4)
# defineOVERSAMPLE_FACTOR (256)
staticunsignedshortadc_result= 0U;
voidadc_isr( void)
{
staticunsignedshortadc_index = OVERSAMPLE_FACTOR;
staticunsignedintaccumulator = 0U;
/*ADC_REG ADC转换结果寄存器,不同平台名称不同*/
accumulator += ADC_REG;
adc_index--;
if( adc_index== 0)
{
/* 加和按因子抽取 */
adc_result = accumulator》》RSHIFT_BITS;
accumulator = 0;
adc_index = OVERSAMPLE_FACTOR;
}
}
该方案有一个缺陷,就是每次ADC中断都需要CPU参与,在过采样率很高的情况下,上述方案消耗很多CPU资源,那么如果单片机内存资源足够的情况下可以考虑采用DMA模式,采集很多数据并将数据暂存下来,然后再做累加平均抽取。这是空间换时间的策略的体现。这个编代码也很容易,只需要申请一片内存区,内存区的大小可以定为256的倍数,这是因为在提升4位分辨率情况下,一个16位的输出样本需要256个12位样本。