单片机外围模块漫谈之二,如何提高ADC转换精度这篇文章,介绍过如何提高ADC的转换精度。关于ADC的参考电压,我发现有不少工程师了解的并不是很清楚。尤其是对于比如电池直接给MCU供电,用到ADC的场景。本篇文章对此做个简单总结。
以经典的STM32F103为例,ADC的参考电压是通过外部引脚VREF+/VREF-输入的。对于部分64pin及以下型号,VREF+在芯片内部与VDDA信号线相连,没有引出到片外,此时ADC参考电压就是VDDA。
当ADC参考电压稳定不变时,正常采集和计算就可以。但是当参考电压发生变化时,由于无法直接获取变化后的参考电压值,如果还使用之前的参考电压就会引起测量误差。
这种情况下该怎么办?可以利用芯片内部参考电压VREFINT,它是一个相对固定的电压,典型值为1.20V。
它内部连接着ADC通道17,如果对ADC测量精度要求不是很高,可认为VREFINT就是固定的1.2V。这时可通过读取该通道的值REFINT_DATA,反推出当前ADC的参考电压值。因为1.2V=VREF_ADC*REFINT_DATA/FULL_SCALE
所以VREF_ADC=1.2V* FULL_SCALE/ REFINT_DATA,其中FULL_SCALE为4095(ADC分辨率12bit)
利用反推出的这个参考电压值,再去计算实际ADC测量值。
Vchx = VREF_ADC*ADCHX_DATA/ FULL_SCALE =1.2V * (ADCHX_DATA/REFINT_DATA)。
但实际上每个芯片个体之间VREFINT会有差异,若需更高精度,可采用校准的方法:
在VDDA稳定为3.3V时,通过ADC采集VREFINT通道的值,记为REFINT_CAL。这样就可以得到每一颗芯片的准确VREFINT电压。实际使用中需要将REFINT_CAL保存在MCU Flash里,以供后续使用。之后再按照上述方法(即先读取ADC通道17反推出当前ADC实际参考电压,再读取实际需要采集的通道值)去计算ADC测量值。
Vchx =(3.3V *REFINT_CAL/ FULL_SCALE) *(ADCHX_DATA/REFINT_DATA)。
该方法对于用户来说增加了一定的工作量,因为STM32F103是很多年前的老产品,没有做出厂校准,后面出的产品如STM32F030,出厂时其实已经做了上述校准的工作,用户直接使用即可。
说到这里大家可能会好奇这个内部的参考电压到底是什么,它其实叫Bandgap电压。MCU的 Bandgap 电压(带隙基准电压)是一种高度稳定的电压基准源,通常由集成电路内部的 带隙基准电路(Bandgap Reference Circuit)生成。Bandgap电路利用双极性晶体管的正负温度系数相互抵消,生成一个几乎不随温度变化的电压(典型值约为 1.2V,具体值因工艺和设计而异)。
说了这么多,内部的这个Bandgap电压其实并不是ADC的直接参考电压源。只不过利用了它去反推出实际的参考电压值。使用这个方法也是有一定的局限性,因为它需要ADC先采集Bandgap通道电压,后采集实际通道电压,如果恰好在这个采集过程中参考电压出现了剧烈的变化,那么转换出来的值也是不准确的,因为反推出的参考电压已经变了,当然这种情况出现的几率相对较小,对于大部分场景这么用是没问题的。
还有一些MCU,内部是带有电压基准源的,比如STM32L5,叫做VREFBUF。
它可以支持2种电压2.048V和2.5V,这个电压是可以直接作为ADC参考电压的。
其基准源仍来自Bandgap电压,通过分压电路生成不同档位输出。从下图框图可以看到因运放的虚短特性,运放的负向输入端与正向输入端(Bandgap基准电压)电压相等,通过右侧分压电阻调节分压比例使 VREFBUF 输出电压达到设定档位。使用这个功能时注意要占用Vref+引脚,并且要接对地的电容,否则是产生不了这个参考电压的。
VREFBUF的偏差是比较小的,手册中有描述:
使用VREFBUF就方便很多了,只需要采集需要的通道即可,需要注意采集的电压值不能超过VREFBUF电压值,比如采集的电压值是3V,那么就需要做分压后采集。
当然如果系统里ADC的外部参考电压本身就很稳定,以上介绍的这些就都用不到了。
关注公众号:
扫码加入嵌入式交流群: