2024-04-22 12:18 AM
Hi,
I have a PCB with F411 as MCU.
MCU VBAT pin is directly connected to battery positive pin.
I try to use ADC1 to read the VBAT value.
Here is the ADC1 init code:
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.ScanConvMode = ENABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
hadc1.Init.DMAContinuousRequests = ENABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_VBAT;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
Here is the ADC reading code:
adc_read_complete = 0;
HAL_ADC_Start_DMA(&hadc1, (uint32_t *)adc_reading, adc_ch_cnt);
while(adc_read_complete == 0);
float v1 = (float)adc_reading[0] / 4096.0 * 4 * 3.3;
My issue is that the reading value is higher than the measured one; and the difference is quite constant as showed below:
ADC reading right after boot-up * Similar to Measured Value | Reading 1 | Reading 2 |
4.119 | 4.863 | 4.844 |
3.609 | 4.122 | 4.141 |
The first reading after boot-up is almost same as measured value; however, subsequent reading values are constantly higher.
For the measured value: we remove battery from PCB and use multi-meter to measure.
Can anyone have any idea on why this could happen, what I have done wrongly?
Solved! Go to Solution.
2024-04-22 12:41 AM
Hi,
did you set sampling time , long enough :
You didnt show the adc clock/setting, but i assume 15 cycles time is too short. (set 387 cycles , for test).
2024-04-22 12:21 AM
Forgot the add the DMA for ADC1 code:
/* DMA controller clock enable */
__HAL_RCC_DMA2_CLK_ENABLE();
/* DMA interrupt init */
/* DMA2_Stream0_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
DMA handler
void DMA2_Stream0_IRQHandler(void)
{
/* USER CODE BEGIN DMA2_Stream0_IRQn 0 */
/* USER CODE END DMA2_Stream0_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_adc1);
/* USER CODE BEGIN DMA2_Stream0_IRQn 1 */
adc_read_complete = 1;
/* USER CODE END DMA2_Stream0_IRQn 1 */
}
2024-04-22 12:41 AM
Hi,
did you set sampling time , long enough :
You didnt show the adc clock/setting, but i assume 15 cycles time is too short. (set 387 cycles , for test).
2024-04-22 01:46 AM - edited 2024-04-22 01:47 AM
yes, you're right. @AScha.3
Once sampling time is changed to maximum: for F411, it's 480 cycles.
The reading becomes accurately close to measured value.