ADC behavior abnormal after wake up from STOP mode
Hello,
I'm using STM32L071RBT6 MCU, encounter a strange issue. when MCU power on, using ADC channel 0 to monitor external battery voltage, the result is OK. but once system waked up from STOP mode, ADC converter behavior is abnormal, the sampling value random varied from 0 ~ 2000. following is my STOP method, can give me some hint?


/* ADC init function */
static void MX_ADC_Init(void){ADC_ChannelConfTypeDef sConfig;
HAL_ADCEx_EnableVREFINT();/**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/ hadc.Instance = ADC1; hadc.Init.OversamplingMode = DISABLE; hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV16; hadc.Init.Resolution = ADC_RESOLUTION_12B; hadc.Init.SamplingTime = ADC_SAMPLETIME_79CYCLES_5; hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD; hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc.Init.ContinuousConvMode = ENABLE; hadc.Init.DiscontinuousConvMode = DISABLE; hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START; hadc.Init.DMAContinuousRequests = ENABLE; hadc.Init.EOCSelection = ADC_EOC_SEQ_CONV; hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED; hadc.Init.LowPowerAutoWait = DISABLE; hadc.Init.LowPowerFrequencyMode = DISABLE; hadc.Init.LowPowerAutoPowerOff = DISABLE; if (HAL_ADC_Init(&hadc) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); }/**Configure for the selected ADC regular channel to be converted.
*/ sConfig.Channel = ADC_CHANNEL_0; sConfig.Rank = ADC_RANK_CHANNEL_NUMBER; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); }/**Configure for the selected ADC regular channel to be converted.
*/ sConfig.Channel = ADC_CHANNEL_1; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); }}
/***********************************************************************
* trigger MCU enter stop mode
*/
void powerSaving(void){
//config GPIO to analog mode (zero consumption for every analog GPIO)
lightLed(LED_GREEN, false);
//HAL_ADC_DeInit(&hadc);
//clear wakeup flag
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
//call power function to enter ''STOP'' mode
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
//after stop, program continue run from here
//config RCC
SystemClock_Config();
//sysclkConfig_after_stop();
//adc init
HAL_ADC_DeInit(&hadc);
MX_ADC_Init();
HAL_ADCEx_Calibration_Start(&hadc, ADC_SINGLE_ENDED);
//config GPIO
}
// following is ADC sampling methods:static volatile uint16_t adcValue[5][2];
/**************************************************************************************** Get battery voltage*/static void handleBattVoltageFetch(void){ if (ADC_IS_CONVERSION_ONGOING_REGULAR(&hadc) == SET) return; //enable MOSFET HAL_GPIO_WritePin(BATT_ADC_EN_GPIO_Port, BATT_ADC_EN_Pin, GPIO_PIN_SET); osDelay(100); //start timer osTimerStart(myMotoTimerHandle, 500); //set batt vol ADC enable flag setAdcControlFlag(BATT_VOL_ADC_EN); //start ADC HAL_ADC_Start_DMA(&hadc, (uint32_t*)adcValue, sizeof(adcValue)/sizeof(uint16_t));}/***************************************************************************************
* ADC completed, calculate voltage value*/static void handleBattVolAdcAvail(void){ HAL_ADC_Stop_DMA(&hadc); //disable MOSFET HAL_GPIO_WritePin(BATT_ADC_EN_GPIO_Port, BATT_ADC_EN_Pin, GPIO_PIN_RESET); if (xTimerIsTimerActive(myMotoTimerHandle)){ osTimerStop(myMotoTimerHandle); }uint32_t vol = 0;
for (int i=0;i<5;i++){ vol += adcValue[i][1] & 0xfff;#ifdef DEBUG_LOG_LEVEL_1 printf(''val[%d][0] = %d, val[%d][1] = %d\n'', i, adcValue[i][0], i, adcValue[i][1]); osDelay(10);#endif } vol = (vol * 67 * VDDA_VOLTAGE) / (20 * 5 * 4096); sensorData.voltageData.batteryVoltage = vol; if (vol > BATTERY_VOLTAGE_WARNING) sensorData.voltageData.flag = (uint8_t)BATT_INFO; else if (vol >= BATTERY_VOLTAGE_LOW) sensorData.voltageData.flag = (uint8_t)BATT_WARNING; else sensorData.voltageData.flag = (uint8_t)BATT_LOW; sensorData.flag |= DATA_UPDATE_VOLTAGE; //inform mainApp that vol data is ready osSignalSet(mainAppTaskHandle, SIG_MAINAPP_VOL_DATA_OK);}/****************************************************************************************
* ADC DMA convert completed callback*/void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* AdcHandle){ uint32_t val; if (isVolAdcEn()){ //check Voltage HAL_ADC_Stop_DMA(&hadc); osSignalSet(sensorTaskHandle, SIG_SENSOR_VOL_AVAIL); }}