ADC Reading on Vbat Incorrect STM32G051C8T6
The issue I am having is as follows on the STM32G051C8T6. We are using the internal RTC with Vbat pin. On this MCU Vbat can be internally configured to be read by the ADC by diving by 3 Bridge. We have ADC Setup, I am making sure we perform the ADC Calibration before performing any conversions and I get ADC Values of either 4095 or 2047 with no in between. Even with the Vbat pin pulled low to ground or floating we get a reading of 2047. I have played around with setting the sample times slower as well with no change.
Below is function used to initialize ADC
static void MX_ADC1_Init(void)
{
/* USER CODE BEGIN ADC1_Init 0 */
/* USER CODE END ADC1_Init 0 */
ADC_ChannelConfTypeDef sConfig = {0};
/* USER CODE BEGIN ADC1_Init 1 */
/* USER CODE END ADC1_Init 1 */
/** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.LowPowerAutoPowerOff = DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.NbrOfConversion = 1;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.DMAContinuousRequests = DISABLE;
hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc1.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_79CYCLES_5;
hadc1.Init.SamplingTimeCommon2 = ADC_SAMPLETIME_12CYCLES_5;
hadc1.Init.OversamplingMode = DISABLE;
hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_VBAT;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC1_Init 2 */
/* USER CODE END ADC1_Init 2 */
}
And my Polling Code
curMsCnt=HAL_GetTick();
if(curMsCnt - prevMSCount > 5000){
prevMSCount = curMsCnt;
ADC-> CCR |= ADC_CCR_VBATEN;
HAL_ADC_Start(&hadc1);
// Start ADC conversion
if (HAL_ADC_PollForConversion(&hadc1, 1000) == HAL_OK) // Wait for conversion to complete
{
adcValue = HAL_ADC_GetValue(&hadc1); // Read ADC value
// Calculate voltage from ADC value
VbatVoltage = ((float)adcValue / 4095.0) * 3.0 * 1000;
// Do something with the voltage value
}
HAL_Delay(500);
ADC-> CCR &= ~ADC_CCR_VBATEN;
HAL_ADC_Stop(&hadc1);
}
