Skip to main content
NW.2
Associate II
August 11, 2023
Solved

STM32H743 - ADC wrong sampling rate

  • August 11, 2023
  • 4 replies
  • 2439 views

Hi STM32-Community,

 

I'm using an STM32H743 with ADC3 in circular DMA mode. ADC has a clockfrequency of 48 MHz. I'm using 8 channels within this ADC3 and also configured the DMA with said channels each with a sampling time of 64.5 cyles. I'm using an async prescaler of 6.

Calculating the sampling rate for a single ADC Channel I get:

48 MHz
-----------------                                    =  15,504 Hz ~ 15.5 kHz
(8 Channels* 6 (Prescaler) * 64.5)

I've put a variable within my DMA routine (which does nothing else) and everytime the DMA toggles this variable, I send out the time needed between each DMA interrupt. I consistenly receive 1169 ms with a DMA Size of 65528.

65528
---------------------------------   ~ 7.005 kHz.
(1.169)*8 (ADC-Channels)

Where is my error?

Here are the ADC Config:

/* ADC3 init function */
void MX_ADC3_Init(void)
{

 /* USER CODE BEGIN ADC3_Init 0 */

 /* USER CODE END ADC3_Init 0 */

 ADC_ChannelConfTypeDef sConfig = {0};

 /* USER CODE BEGIN ADC3_Init 1 */

 /* USER CODE END ADC3_Init 1 */

 /** Common config
 */
 hadc3.Instance = ADC3;
 hadc3.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV6;
 hadc3.Init.Resolution = ADC_RESOLUTION_16B;
 hadc3.Init.ScanConvMode = ADC_SCAN_ENABLE;
 hadc3.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
 hadc3.Init.LowPowerAutoWait = DISABLE;
 hadc3.Init.ContinuousConvMode = ENABLE;
 hadc3.Init.NbrOfConversion = 8;
 hadc3.Init.DiscontinuousConvMode = DISABLE;
 hadc3.Init.ExternalTrigConv = ADC_SOFTWARE_START;
 hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
 hadc3.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR;
 hadc3.Init.Overrun = ADC_OVR_DATA_PRESERVED;
 hadc3.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
 hadc3.Init.OversamplingMode = DISABLE;
 if (HAL_ADC_Init(&hadc3) != HAL_OK)
 {
 Error_Handler();
 }

 /** Configure Regular Channel
 */
 sConfig.Channel = ADC_CHANNEL_5;
 sConfig.Rank = ADC_REGULAR_RANK_1;
 sConfig.SamplingTime = ADC_SAMPLETIME_64CYCLES_5;
 sConfig.SingleDiff = ADC_SINGLE_ENDED;
 sConfig.OffsetNumber = ADC_OFFSET_NONE;
 sConfig.Offset = 0;
 sConfig.OffsetSignedSaturation = DISABLE;
 if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
 {
 Error_Handler();
 }

 /** Configure Regular Channel
 */
 sConfig.Channel = ADC_CHANNEL_9;
 sConfig.Rank = ADC_REGULAR_RANK_2;
 if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
 {
 Error_Handler();
 }

 /** Configure Regular Channel
 */
 sConfig.Channel = ADC_CHANNEL_4;
 sConfig.Rank = ADC_REGULAR_RANK_3;
 if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
 {
 Error_Handler();
 }

 /** Configure Regular Channel
 */
 sConfig.Channel = ADC_CHANNEL_8;
 sConfig.Rank = ADC_REGULAR_RANK_4;
 if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
 {
 Error_Handler();
 }

 /** Configure Regular Channel
 */
 sConfig.Channel = ADC_CHANNEL_3;
 sConfig.Rank = ADC_REGULAR_RANK_5;
 if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
 {
 Error_Handler();
 }

 /** Configure Regular Channel
 */
 sConfig.Channel = ADC_CHANNEL_7;
 sConfig.Rank = ADC_REGULAR_RANK_6;
 if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
 {
 Error_Handler();
 }

 /** Configure Regular Channel
 */
 sConfig.Channel = ADC_CHANNEL_2;
 sConfig.Rank = ADC_REGULAR_RANK_7;
 if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
 {
 Error_Handler();
 }

 /** Configure Regular Channel
 */
 sConfig.Channel = ADC_CHANNEL_6;
 sConfig.Rank = ADC_REGULAR_RANK_8;
 if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN ADC3_Init 2 */

 /* USER CODE END ADC3_Init 2 */

}

CubeMX ADC-Frequency:

NW2_0-1691752233265.png

 

I know I'm not 100% correct with my method measuring the sampling frequency, but being that far off left me wondering what I'm doing wrong.

 

Kind regards

 

 

 

 

 

This topic has been closed for replies.
Best answer by TDK

You're missing:

An x2 prescaler on the ADC clock.

TDK_0-1691756637995.png

Extra samples due to the conversion (would be 8.5 for 16-bit conversion).

TDK_1-1691756729905.png

 

4 replies

TDK
TDKBest answer
August 11, 2023

You're missing:

An x2 prescaler on the ADC clock.

TDK_0-1691756637995.png

Extra samples due to the conversion (would be 8.5 for 16-bit conversion).

TDK_1-1691756729905.png

 

"If you feel a post has answered your question, please click ""Accept as Solution""."
NW.2
NW.2Author
Associate II
August 11, 2023

Thank you so much!

Have a nice week end! 

Associate II
January 15, 2024

Query: Using STM32H743XI EVAL BOARD,

ERROR IN READING 2 ADC1 CHANNEL (PA0_C, PA1_C) IN DMA CIRCULAR MODE -

1ST CHANNEL GIVING ACCURATE COUNTS,

2ND CHANNEL SET AT 2V - ALWAYS SHOWING COUNTS SAME AS OF 1ST CHANNEL, WHERE POT IS CONNECTED?

 

ADC CLOCK, CONFIGS AND DMA SETTINGS AS FOLLOWS:

 

Ab1_3-1705299477077.png

 

 

Ab1_0-1705299278242.png

 

Ab1_1-1705299373441.png

 

Ab1_2-1705299413950.png

 

Tried example code also from STM32H7cubmx package (1.11.0), same result? anything missing from above configuration?

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