cancel
Showing results for 
Search instead for 
Did you mean: 

NUCLEO-H563ZI - ADC reading noise when input grounded

Iatik.1
Associate II

Hello, I’m trying to perform ADC measurements with the STM32H563ZIT. I’ve shared my configuration settings from the .ioc file below. The ADC reading fluctuates by about ±40. When I short the ADC pin to GND, the reading varies between 0 and 30 instead of staying stable. I can’t get a constant value. What could be causing this issue?

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 */

  /** Common config
  */
  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV10;
  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 = ENABLE;
  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.SamplingMode = ADC_SAMPLING_MODE_NORMAL;
  hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  hadc1.Init.OversamplingMode = ENABLE;
  hadc1.Init.Oversampling.Ratio = ADC_OVERSAMPLING_RATIO_16;
  hadc1.Init.Oversampling.RightBitShift = ADC_RIGHTBITSHIFT_4;
  hadc1.Init.Oversampling.TriggeredMode = ADC_TRIGGEREDMODE_SINGLE_TRIGGER;
  hadc1.Init.Oversampling.OversamplingStopReset = ADC_REGOVERSAMPLING_CONTINUED_MODE;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_10;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  sConfig.Offset = 0;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC1_Init 2 */

  /* USER CODE END ADC1_Init 2 */

}

 

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);

  while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE|RCC_OSCILLATORTYPE_CSI;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.CSIState = RCC_CSI_ON;
  RCC_OscInitStruct.CSICalibrationValue = RCC_CSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLL1_SOURCE_CSI;
  RCC_OscInitStruct.PLL.PLLM = 1;
  RCC_OscInitStruct.PLL.PLLN = 50;
  RCC_OscInitStruct.PLL.PLLP = 2;
  RCC_OscInitStruct.PLL.PLLQ = 2;
  RCC_OscInitStruct.PLL.PLLR = 2;
  RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1_VCIRANGE_2;
  RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1_VCORANGE_WIDE;
  RCC_OscInitStruct.PLL.PLLFRACN = 0;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
                              |RCC_CLOCKTYPE_PCLK3;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV4;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB3CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure the programming delay
  */
  __HAL_FLASH_SET_PROGRAM_DELAY(FLASH_PROGRAMMING_DELAY_2);
}
18 REPLIES 18

Which Discovery board - I don't see an H563 Discovery ?

Showing photos of both setups could help ...

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.
LCE
Principal II

Check the Nucleo's PCB layout and try some other ADC input.

There are many signals going loooong ways to the connectors and other hardware via solder bridges.
If you ground such a "bad" line without a capacitor close to the MCU input, there'll probably be some interference noise from the PCB.

I remove the cables from the nucleo and connect them to the discovery board.

I just got my Nucleo card. I don't think there's a problem.

 

photo_2025-10-27_20-24-45.jpg

So that's an STM32F4-Discovery - very different to an STM32H563 !

And, as has been said by many, long wires and breadboards are very prone to picking up interference

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

How is this setup grounding the pin exactly? Jumper from the pin to GND directly. Looks like it's connected to a potentiometer, not grounded.

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

I'm getting the ground connection directly from the board. There are no problems with the connections. Long cables don't cause any problems on the Discovery board. I don't think it's the cable either. Do you have any real suggestions for a solution?

No real suggestions, just wild unfounded theories about long wires being able to pick up noise I suppose. As you said, there are no problems with the hardware setup, so I'll move along.

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

Share your project so others can look deep in other stuff you didn't share ..

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
mƎALLEm
ST Employee

Meanwhile, you didn't confirm which discovery you are using: STM32F4-Discoevery or STM32H573I-DK there is is big difference between both: note the same product, not the same architecture, not even the same ADC!

Another hypothesis, it could be due to the Ethernet PHY on the Nucleo board. 

Read this article: ADC value affected by ETH PHY 50 MHz from RMII interface

From my side, I tested the following channels:

- CH10 (PC0): worst case 5LSB

- CH3 (PA6): worst case 2LSB

- CH2 (PF11): worst case 2LSB

- CH6 (PF12): worst case 2LSB

So try channels far from ethernet signals. Try for example: CH6 (PF12).

Attached the project I used for my tests. If you are still getting 40LSB, you need to remove all the non needed stuff including the potentiometer that we are seeing in the photo and keep only one wire to ground the ADC. Please use short wire. 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.