cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F070 ADC single channel fluctuation

Flyback
Associate II

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:

Flyback_0-1734472984077.png

What am I missing? Thank you!

2 REPLIES 2
Karl Yamashita
Lead III

Try adjusting your sampling time.

1.5 Cycles maybe too short and/or a noisy signal. 

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.
TDK
Guru

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

If you feel a post has answered your question, please click "Accept as Solution".