简介
STM32G030系列MCU,内部有一个12位的,0.4us的ADC ,最多支持16通道,0-3.6V的电压采样应用,用户开发时,经常用到ADC采样,同时经常遇到的问题有:
如何获取MCU内部基准电压?
如何获取通道管脚的电压?
如何获取电源VBAT电压?
如何获取基准ADC值、通道ADC值、VBAT电压?
以上特别是最后一个问题,同时获得值已经包括所用的应用,内部只有一个ADC值,需要切换通道并计算,工程师调试的时候往往切换通道时候出现异常。
如何获取MCU内部基准电压?
从数据手册获取的内部基准电压为1.212V,只要获取其ADC值就可以。基准电压和ADC值就可以其它通道的电压值。

如何获取电源VBAT电压?
切换到VBAT通道,获取ADC值,跟Vcc其3倍关系,所以获取后需要x3
vcc_VREF = 1214; // 基准电压 1.212mV
adc_VREF = GetAdcTemp(LL_ADC_CHANNEL_VREFINT);
adc_BATT = GetAdcTemp(LL_ADC_CHANNEL_VBAT)*3;//3 // 3倍的ADC
计算电池电压vcc_BATT = vcc_VREF * adc_BATT /adc_VREF;
如何获取通道管脚的电压?
切换到某个通道的,获取ADC值,计算此通道的电压值:如PA0为通道0,PA1为通道1,以此类推:
vcc_VREF = 1214; // 基准电压 1.212mV
adc_VREF = GetAdcTemp(LL_ADC_CHANNEL_VREFINT);
adc_PA0 = GetAdcTemp(LL_ADC_CHANNEL_0);
计算电池电压 vcc_PA0 = vcc_VREF * adc_PA0 /adc_VREF;
ADC模块怎样构建?
先设计文档app_adc.c和app_adc.h
初始化配置ADC:初始化有例程,直接拷贝例程就可以。
void APP_ConfigAdc(void)
设计通过切换通道,获取ADC值的函数
uint16_t GetAdcTemp(uint32_t Channel),该函数实体结构如下:提供参考
uint16_t GetAdcTemp(uint32_t Channel)
{
uint16_t ADCxData;
uint16_t ADCxData_Voltage;
uint32_t wait_loop_index = 0;
//Activate_ADC();
/* 设置ADC组常规序列通道上选择的序列 */
LL_ADC_REG_SetSequencerRanks(ADC1, ADC_REG_RANK, Channel);
if(Channel == LL_ADC_CHANNEL_VREFINT)
{ /* 设定ADC的采样通道*/
LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(ADC1),LL_ADC_PATH_INTERNAL_VREFINT);
}
else if(Channel == LL_ADC_CHANNEL_TEMPSENSOR)
{
LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(ADC1),LL_ADC_PATH_INTERNAL_TEMPSENSOR);
}
else if(Channel == LL_ADC_CHANNEL_VBAT)
{
LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(ADC1),LL_ADC_PATH_INTERNAL_VBAT);
}
else
{
LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(ADC1),LL_ADC_PATH_INTERNAL_NONE);
}
// 等待通道切换通道完成
while (LL_ADC_IsActiveFlag_CCRDY(ADC1) == 0)
{
#if (USE_TIMEOUT == 1)
/* Check Systick counter flag to decrement the time-out value */
if (LL_SYSTICK_IsActiveCounterFlag())
{
if(Timeout-- == 0)
{
/* Time-out occurred. Set LED to blinking mode */
//LED_Blinking(LED_BLINK_ERROR);
}
}
#endif /* USE_TIMEOUT */
}
/* 清除ADC通道配置就绪 */
LL_ADC_ClearFlag_CCRDY(ADC1);
/* Perform ADC group regular conversion start, poll for conversion */
/* completion. */
ConversionStartPoll_ADC_GrpRegular();
ADCxData = LL_ADC_REG_ReadConversionData12(ADC1);
return ADCxData;
}