【STM32笔记】HAL库ADC测量精度提高方案(利用内部参考电压VREFINT计算VDDA来提高精度)
多数STM32的MCU 都没有内部基准电压 如L496系列
 但在外接VDDA时(一般与VCC 3.3V连接) 有可能VCC不稳定 导致参考电压不确定 从而使ADC测量不准确
STM32内置一个测量VREFINT的ADC通道 且在寄存器VREFINT_CAL中会存储在3.0V标准电压的情况下 该VREFINT的ADC测量数据结果(12位精度)

 STM32L496的VREFINT_CAL地址如图 该值为16位数据
读取时:
#define VREFINT_CAL						(uint16_t)(*(__I uint16_t *)(0x1FFF75AA))
我读出来是1655
该值表示此芯片在30℃ 3.0V的标准电压下的VREFINT测量结果
根据手册:
 
 由公式3即可校准ADC的测量
比如我对VREFINT的ADC测量出来是1400
 我要测的ADC通道是1500
 则实际被测ADC通道实测值为:
3.0f*1655*1500/1400/4095
代码示例:
 
 我用ADC1来测量VREFINT 一定要配置为12位精度 方便计算

 另外 ADC2 通道9是我要测的电压
/*!
 * @brief       	开启ADC通道,返回ADC值	
 *
 * @param 	[in]	hadc: ADC_HandleTypeDef 变量地址
 *
 * @return				ADC_Value: ADC平均值结果
 */
uint16_t Get_ADC_Value(ADC_HandleTypeDef *hadc)
{
	uint16_t ADC_Value=0;
	HAL_ADCEx_Calibration_Start(hadc,ADC_SINGLE_ENDED);
	HAL_ADC_Start(hadc);     //启动ADC转换
	HAL_ADC_PollForConversion(hadc, 5); //等待转换完成,5为最大等待时间,单位为ms
	if(HAL_IS_BIT_SET(HAL_ADC_GetState(hadc), HAL_ADC_STATE_REG_EOC))
	{
		ADC_Value = HAL_ADC_GetValue(hadc);   //获取AD值
	}
	return ADC_Value;
}
/*!
 * @brief       	计算ADC的真实值,包含VREFINT校准后的结果
 *
 * @param 	[in]	hadc: ADC_HandleTypeDef 变量地址
 *
 * @return				ADC_Real_Value: ADC校准后的真实值
 */
float Get_Real_ADC_Value(ADC_HandleTypeDef *hadc)
{
	uint16_t VREFINT_DATA = Get_ADC_Value(&hadc1);
	uint16_t ADC_DATA = Get_ADC_Value(hadc);
	float ADC_Real_Value = 3.0f*VREFINT_CAL*ADC_DATA/VREFINT_DATA/4095.0f;
	
	return ADC_Real_Value;
}
两个通用函数
float ADC = Get_Real_ADC_Value(&hadc2);
调用方式
这样测出来就不用考虑VDDA电压是否稳定了 在一定范围内还是相对来说比较精确的



















