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!

5 REPLIES 5
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".
Flyback
Associate II

Thanks for replying, but the sampling time is not the issue. I believe there is a fundamental problem.

I have increased the sampling time to maximum anyway.

The ADC pin is going HIGH during conversion. Below is the waveform at 239.5 cycles, which match the timing on the scope considering ADC running at 14MHz.

Flyback_0-1734517756929.png

This pull-up is periodic, of course, I am doing ADC polling at around 20ms.

Flyback_1-1734517784627.png

But the pulling-up level is also consistent: if I put an external pull-down, the peak voltage on the pin consistently gets reduced reducing the pull-down resistance. On this case the resistor is 820R.

Flyback_2-1734517802716.png

So, my conclusion is that there is something pulling up the pin when the conversion is started.

TDK
Guru

Yes, that is abnormal. The ADC on the chip could be damaged. Your setup as described in the first post is okay.

Do the internal ADC channels convert correctly?

Do the converted values match up with what you see on the scope? Looks like 3.3 V in one photo and about 1 V with the 820 Ohm on there.

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

Thanks for your reply.

Good questions.

The ADC converts “correctly” with the 820R resistor. Not accurately, but it does convert. I obtain a conversion around 1.2 – 1.3V for the 1V input. So it is like the VDDA that the ADC sees is around 2.6V.

The other channels are the same.

The key now is I replaced the micro and same problem. So, no damaged.

Maybe in relation with this issue, there is another post, but not sure if same problem:

https://community.st.com/t5/stm32-mcus-products/stm32f070-adc-single-channel-issue/m-p/181017