天天看點

【STM32筆記】HAL庫ADC測量精度提高方案(利用内部參考電壓VREFINT計算VDDA來提高精度)

【STM32筆記】HAL庫ADC測量精度提高方案(利用内部參考電壓VREFINT計算VDDA來提高精度)

多數STM32的MCU 都沒有内部基準電壓 如L496系列

但在外接VDDA時(一般與VCC 3.3V連接配接) 有可能VCC不穩定 導緻參考電壓不确定 進而使ADC測量不準确

STM32内置一個測量VREFINT的ADC通道 且在寄存器VREFINT_CAL中會存儲在3.0V标準電壓的情況下 該VREFINT的ADC測量資料結果(12位精度)

【STM32筆記】HAL庫ADC測量精度提高方案(利用内部參考電壓VREFINT計算VDDA來提高精度)

STM32L496的VREFINT_CAL位址如圖 該值為16位資料

讀取時:

我讀出來是1655

該值表示此晶片在30℃ 3.0V的标準電壓下的VREFINT測量結果

根據手冊:

【STM32筆記】HAL庫ADC測量精度提高方案(利用内部參考電壓VREFINT計算VDDA來提高精度)

由公式3即可校準ADC的測量

比如我對VREFINT的ADC測量出來是1400

我要測的ADC通道是1500

則實際被測ADC通道實測值為:

代碼示例:

【STM32筆記】HAL庫ADC測量精度提高方案(利用内部參考電壓VREFINT計算VDDA來提高精度)

我用ADC1來測量VREFINT 一定要配置為12位精度 友善計算

【STM32筆記】HAL庫ADC測量精度提高方案(利用内部參考電壓VREFINT計算VDDA來提高精度)

另外 ADC2 通道9是我要測的電壓

STM32的ADC最大的轉換速率為1MHz,也就是說最快轉換時間為1us,為了保證ADC轉換結果的準确性,ADC的時鐘最好不超過14M。

其中 T = 采樣時間 + 12.5個周期,其中1周期為1/ADCCLK

例如,當 ADCCLK=14Mhz 的時候,并設定 1.5 個周期的采樣時間,則得到: Tcovn=1.5+12.5=14 個周期=1us。

當ADCCLK=50Mhz的時候,設定37.5個采樣周期 37.5+12.5=50

/*!
 * @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;
}
           

兩個通用函數

調用方式

這樣測出來就不用考慮VDDA電壓是否穩定了 在一定範圍内還是相對來說比較精确的

繼續閱讀