很多人都提到了STM32F407的ADC似乎精度不够。
原子的探索者开发教程里ADC一节最后也用红字提出了STM32F407的ADC精度不怎么好。
实际上STM32F407的ADC精准度真的不够吗?如果其精准度不够,那么其系统误差怎么测试计算?
实际上经过我一系列测试后发现:STM32F407的ADC足够精准,通过设置合理的参数之后,其ADC误差完全可以控制在±0.1%之内
下面先说一下我的测试原理和方法:
电路大概如下图:
上图有一个错误:右上面2K和1K分压之后接入的是STM32F407的Vref引脚,不是ADC
上面采样分压电阻选得比较大,是出于16选1芯片输出负载能力比较低,并且对测试电路有一定影响的考虑。
另外Vref采样分压电阻选的跟AD采样分压电阻不一致,本来想使用一致的值,后来发现STM32F407的Vref的输入阻抗相当低,
使用220K 和100K分压的话,Vref电压远比分压值低,这说明Rref || 100K远小于100K。手头上没有2.2K的电阻,只好用2K的
这也就使得本次测试AD没能达到“满量程”,当然,在经过分压之前,做了个电压跟随。
测试的方法:在STM32F407的main函数while中2分钟内不停的读取16选1的各个通道的AD值,统计其最高值和最低值。
通过设置不同的ADCCLK和采样保持周期,来分析比较,从而选出相对于电路一定的最合理参数。
程序如下
[mw_shl_code=c,true] u8 ucCnt = 0;
u16 uwAdcBtmDrop = 9999;
u16 uwAdcTopDrop = 0;
unAdcTotal = 0;
for(ucAdcAddr = 0; ucAdcAddr < 16; ucAdcAddr++)
{
SetAdcChl(ucAdcAddr); //设置16选1芯片的通道
uwAdcBtmDrop = 9999;
uwAdcTopDrop = 0;
unAdcTotal = 0;
for(ucCnt = 0; ucCnt < 10; ucCnt++)
{
uwAdcRslt = GetAdcData(); //采集AD
if(uwAdcBtmDrop > uwAdcRslt)
{
uwAdcBtmDrop = uwAdcRslt;
}
if(uwAdcTopDrop < uwAdcRslt)
{
uwAdcTopDrop = uwAdcRslt;
}
unAdcTotal += uwAdcRslt;
}
//去掉最小值、最大值,然后求平均
unAdcTotal -= uwAdcBtmDrop;
unAdcTotal -= uwAdcTopDrop;
unAdcTotal /= 8;
if(unAdcTotal > uwAdcTop[ucAdcAddr])
{
uwAdcTop[ucAdcAddr] = unAdcTotal;
}
if(unAdcTotal < uwAdcBtm[ucAdcAddr])
{
uwAdcBtm[ucAdcAddr] = unAdcTotal;
}
}[/mw_shl_code]
最后是采集的结果:
呃,图片被压缩了,将就着看吧。
通过对上述结果做如下分析: 多次采集的最高值和最低值的差足够小的话,那么就能保证STM32F407的ADC足够稳定精准,比如采样保持设置为480个周期时,
多次采集的最高值和最低值的差都不大于3,相对于千分之一(±0.1%)的数值(大约是8),其精度约为0.0366%,远高于千分之一精度。
同时,还有一个现象:0通道的值在采样周期比较短(如3个周期)时,其最大和最小值都远高于0,从而得出如下结论:
1、STM32F407的AD引脚和地之间存在一定的分布电容,该分布电容使得使用220K 和100K分压时,不能将AD引脚的电压“及时地”拉低(因为上一个16选1选择的是16,通道电压最高)
2、STM32F407的AD引脚输入电流有一定要求,或者说AD引脚外部的dv/dt能力要足够高,电流太低将影响AD采集精度或时间。
针对上面第2个结论,我曾经考虑过在STM32F407的AD引脚输入之前添加一个电压跟随,结果电压跟随的dv/dt能力也不够(LM258),后来换成高速运放AD8024,结果使用AD8024后,
整个AD采集结果很差,Max-Min在所有的参数上都高于50,结果方案流产(估计买到假运放或者有哪个地方搞错了,比如运放的使用环境或者理论上出了问题)
最后选择一个合理的参数:通过对整个测量结果的比较,选出一个不影响精度的速度最快设置(也可以处于精度考虑,保留一定预留)
如上述采集结果中ADCCLK=14MHz(6分频),采集保持设置为112个周期时,采集时间最短,并且精度较精准,并且0通道的数值合理(0到2之间).如上面的图中绿色标出部分
那么是不是大家直接使用该参数就一定适合自己的电路呢?肯定不是
因为大家的电路中外部要采集的数据的dv/dt能力与我的测试电路不一样,肯定会有不一样的“最合理”参数,建议大家跟我一样,做整个范围的测试,从中选出最合理的参数来。
至于原子哥提到的将AD引脚接地,读出的AD值也有几十,我估计电路板布线有一定影响。
我的布线是双层版,模拟输入周围接地,模拟线背面使用覆铜层接地,使得模拟输入线周围全部被“地”包围,最大限度减小干扰。
|