2024-12-17 02:07 PM
Hi there,
I have a custom board with an STM32F070. The VDD and VDDA are connected together. System runs at 48 MHz from a 8 MHz crystal. Each VDD has a 100nF cap. VDD is 3.3V, from a 1% LDO.
The code uses UART1, UART2, USB and I2C2. Also, many I/O pins. All works correctly.
I have a single channel (ADC_IN5) conversion, with a simple polling. Result of conversion fluctuates by several hundreds even at 0V (ie. from 0 up to 300).
The initialitation code is below:
/**
* @brief ADC Initialization Function
* @PAram None
* @retval None
*/
static void MX_ADC_Init(void)
{
/* USER CODE BEGIN ADC_Init 0 */
/* USER CODE END ADC_Init 0 */
ADC_ChannelConfTypeDef sConfig = {0};
/* USER CODE BEGIN ADC_Init 1 */
/* USER CODE END ADC_Init 1 */
/** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
hadc.Instance = ADC1;
hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
hadc.Init.Resolution = ADC_RESOLUTION_12B;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc.Init.LowPowerAutoWait = DISABLE;
hadc.Init.LowPowerAutoPowerOff = DISABLE;
hadc.Init.ContinuousConvMode = DISABLE;
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.DMAContinuousRequests = DISABLE;
hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
if (HAL_ADC_Init(&hadc) != HAL_OK)
{
Error_Handler();
}
/** Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_5;
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC_Init 2 */
// ADC Initialization
HAL_ADCEx_Calibration_Start(&hadc);
/* USER CODE END ADC_Init 2 */
}
The polling code is below:
// Perform ADC conversion
HAL_ADC_Start(&hadc); // Enables ADC and starts conversion
// Waits for a conversion to be performed with a 10 ms timeout
if(HAL_ADC_PollForConversion(&hadc,10) == HAL_OK)
{
value = HAL_ADC_GetValue(&hadc);
}
HAL_ADC_Stop(&hadc); // Stops conversion
And the config:
What am I missing? Thank you!
2024-12-17 03:34 PM
Try adjusting your sampling time.
1.5 Cycles maybe too short and/or a noisy signal.
2024-12-17 05:39 PM
Increasing sampling time will yield the biggest improvement. Other sources of error are discussed here:
How to optimize the ADC accuracy in the STM32 MCUs - Application note