STM32 ADC测量电池电压(使用内部参考电压)

摘自链接:STM32 ADC测量电池电压(使用内部参考电压) - STM32/STM8单片机论坛 - ST MCU意法半导体官方技术支持论坛 - 21ic电子技术开发论坛

在使用ADC时,通常的用法是Vref+接电源VDD3.3V,然后计算时直接用3.3V做参考电压,但是这种方法忽略了一些情况如供电电压有可能随外部一些其他用电器工作使用的大电流而导致电压不稳定,还有可能MCU供电LDO转换的精度个别偏差较大。这时候依然用3.3V的定值做参考电压计算显然得出的值就会出现与实际电压偏差较大的问题。

【解决方案】
一般 100 脚以上的 STM32 MCU都有 VREF 引脚。对于 100 脚以下的芯片,STM32 没有把 VREF 引脚引出来,而是直接在内部连接到了 VDDA 引脚。这样就导致了 ADC 的供电电源和参考电源实际是一个。通常项目中我们VDDA也是连接到了VDD。
如果有 VREF 引脚,可以在VREF上接一个稳定且精度高的电压作为参考电压。

还有一种方法是启用内部参考电压。
根据STM32f10xCDE数据手册中的数据,这个参照电压的典型值是1.20V,最小值是1.16V,最大值是1.24V(-40~85度)。这个电压基本不随外部供电电压的变化而变化。

很明显,如果以这个为参考电压,我们也得测量其值,因为它对于不同的芯片是一个范围,并不是确定值。 STM32 可以通过配置将 VREFINT 接入到 ADC 内部的通道17,然后我们就可以像测试普通的通道一样测量 VREFINT 到底是多少。注意MCU 不同 具体连接的 ADC 通道也是不同的。


具体方法是在测量某个通道的电压值之前,先读出参照电压的ADC测量数值(即从ADC1_IN17读出的值),记为ADrefint;再读出要测量通道的ADC转换数值,记为ADchx;则要测量的电压为:

Vchx = Vrefint * (ADchx/ADrefint)

其中Vrefint为参照电压=1.20V(STM32F10x)。

推导过程:

Vchx = VREFINT* (((ADchx*(VREF/4096))/(ADre*(VREF/4096)))

注:VREFINT=1.2V(这里取1.20V实际上会有误差),VREF为参考电压值=3.3V
此公式可以理解为:
(ADchx*(VREF/4096)是正常计算的含误差电压值VREFINT/(ADre*(VREF/4096)是修正参数,ADre*(VREF/4096)得到实际的参考电压值比较接近VREFINT,VREFINT是校准电压值,VREFINT/(ADre*(VREF/4096)是约等于1的一个修正值。

公式简化后:

Vchx = VREFINT*(ADchx/ADre)

该式计算得到的值是该通道的实际电压值。
注意:上面的方法针对F1芯片只给了参考电压的范围,没有提供出厂校准值的情况,下面将介绍提供了校准值的情况。

推导过程:
第一个公式VDDA = 3.0V x VREFINT_CAL / VREFINT_DATA 这个公式是怎么来的呢?
ST厂商 通过配置将 VREFINT 连接到 ADC 后,则有:VREFINT = 3.0V * (VREFINT_CAL / 4095); VREFINT_CAL 就是校准条件下的 ADC 采样值(校准条件就是指VDDA=Vref+=3.0V,环境温度30度),采到的VREFINT_CAL值写入到flash。
我们自己通过配置将 VREFINT 连接到 ADC:VREFINT = VDDA * (VREFINT_DATA / 4095);
因此,VDDA * (VREFINT_DATA / 4095) = 3.0 * (VREFINT_CAL / 4095);
VDDA = 3.0V x VREFINT_CAL / VREFINT_DATA


VDDA是这个公式中的重点,我们常规的算法直接用3.3V作为VDDA计算才导致了误差,因为VDDA有误差不是刚好3.3V。

第二个公式Vchannalx=VDDA*(ADCx_DATA/FULL_SCALE)
这个公式很好理解,就是我们常用的计算电压方式,ADCx_DATA是读出的采样值,如:3.3*(1650/4095)


上面两式联立就能得出最后的公式。

前面讲过的 Vchx = Vrefint * (ADchx/ADrefint),Vrefint=1.20V

VREFINT_CAL是芯片出厂时厂家测量出来的参考电压值固化在flash中,U16两个字节,可以作为基准电压。使用时读出即可。该值不是所有系列芯片都有,F103貌似都没有,下图是L475的(注意不同芯片该值保存的地址不一致):

上图表示,厂家在30度左右环境温度下,VDDA和参考电压(Vref+)等于3.0V的状态下,通过ADC通道读出的参考电压(Vrefint=1.2V)值,保存在0x1FFF75AA开始地址的2个字节中。如何读取示例:VREFINT_CAL = *(u16*)0x1FFF75AA,笔者手里的L475读出来是0x067F,换算3.0*(0x067F/4095)=1.218315,接近1.20了。也就是数据手册中的VREFINT=1.2V !!!

Vchx = VREFINT*(ADchx/ADre)=

我们重点关注这个公式:
 



VREFINT_CAL:内部参考电压校准值,直接地址读取。比如该款芯片地址:0x1FFF75AA,那么我们可以这么做:
VREFINT_CAL = *(__IO uint16_t *)(0x1FFF75AA);

FULL_SCALE:根据我们设置的ADC分辨率而定,12位ADC分辨率值:2^12 - 1 = 4096 - 1

VREFINT_DATA:从ADC_17通道读出实际内部参考电压值

ADCx_DATA:需要测试的电压通道读值
注意:公式中的3.0V有时可能是3.3V,取决于厂家给的校准值是在3.0V条件下测试还是3.3V或是其他。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值