cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7 ADC clock and conversion rate

tarzan
Associate II

Hello,

I'm using a STM32H427ZI rev Y. 20Mhz crystal and ADC to convert 4 channels in scan mode, using a timer to start the conversions (500kS/s) and the DMA to get the data.

PLL2 is configured to 80MHz (the max undivided ADC clock is 100MHz). I would like to use it, divided by 4 to obtain a 20MHz clock. As recommended in the reference manual, I'm using only even coefficients to get a 50% duty cycle. This 20MHz clock should be ok for the ADC with boost=0.

I can't select any sync clock in cubemx, only async clocks are available. I have modified the adc.c file to set the sync clock /4. This is quite boring, this bug is still present since at least 2019 with various versions of the ST softwares.

Everything is working quite good.

  • The timer is also used to set a GPIO (pwm): 500kS/s confirmed. The 500kS/s sampling is also visible on the analog lines (15mV drop)
  • MCO2 used to check PLL2P signal : 80MHz confirmed
  • DMA data is ok

In the DMA routine (placed in the CCMRAM, with only the necessary code), I'm using a GPIO to check the routine execution time.

The time elapsed between the start of the conversion and the beginning of the DMA interrupt is 850ns. This is 2x too short, I was expecting at least 1600ns : trigger latency + 4*(2.5Tadc for sampling + 5Tadc for 10 bits conversion).

Normally, the DMA IRQ is for "transfer complete", not for "transfert half complete". However I should re-check that.

I was using a old version of cubeMX. Updating the whole project to the latest cubeIDE/MX/packages don't help.

Any suggestion will help :)

Thanks

2 REPLIES 2
AScha.3
Chief III

>This is quite boring

shure.

+ what is the question now ?

agree?

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

(I'm the owner of the original post)

The question is: why are the timing wrong?

hadcx.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4

and

hadcx.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4

Give different conversion timings. So I suppose this line is doing something.

The ADC is configured to take the PLL2 as clock source. However, modifying the PLL2 output frequency don't change the ADC conversion time when using ADC_CLOCK_SYNC_PCLK_DIV4 and this auto-generated code in main.c:

void PeriphCommonClock_Config(void)
{
  RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
 
  /** Initializes the peripherals clock
  */
  PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_ADC;
  PeriphClkInitStruct.PLL2.PLL2M = 8;
  PeriphClkInitStruct.PLL2.PLL2N = 128;
  PeriphClkInitStruct.PLL2.PLL2P = 4;
  PeriphClkInitStruct.PLL2.PLL2Q = 40;
  PeriphClkInitStruct.PLL2.PLL2R = 2;
  PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_1;
  PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE;
  PeriphClkInitStruct.PLL2.PLL2FRACN = 0;
  PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_PLL2;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
}