Skip to main content
Visitor II
July 9, 2024
Question

ADC Conversion Time STM32H563

  • July 9, 2024
  • 13 replies
  • 2860 views

ADC1 clocked @ 65 MHz, pre-scaler of 8, 7 channels active, 640.5 cycles/conversion, 256 oversampling, interrupts, scan mode. The numbers suggest all channels will be converted 1x in (8/65000000) * 640.5 * 7 * 256 = 141 ms. But when I look at uwTick before HAL_ADC_Start_IT() and after 7 conversions complete, I get 37 ms. Why the discrepancy?

    This topic has been closed for replies.

    13 replies

    mccabehmAuthor
    Visitor II
    July 12, 2024

    HAL_ADC_MspInit() follows

     

    /**
    * @brief ADC MSP Initialization
    * This function configures the hardware resources used in this example
    * hadc: ADC handle pointer
    * @retval None
    */
    void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
    {
     GPIO_InitTypeDef GPIO_InitStruct = {0};
     if(hadc->Instance==ADC1)
     {
     /* USER CODE BEGIN ADC1_MspInit 0 */
    
     /* USER CODE END ADC1_MspInit 0 */
     /* Peripheral clock enable */
     HAL_RCC_ADC_CLK_ENABLED++;
     if(HAL_RCC_ADC_CLK_ENABLED==1){
     __HAL_RCC_ADC_CLK_ENABLE();
     }
    
     __HAL_RCC_GPIOC_CLK_ENABLE();
     __HAL_RCC_GPIOA_CLK_ENABLE();
     __HAL_RCC_GPIOB_CLK_ENABLE();
     /**ADC1 GPIO Configuration
     PC0 ------> ADC1_INP10
     PC1 ------> ADC1_INP11
     PC2 ------> ADC1_INP12
     PC3 ------> ADC1_INP13
     PA6 ------> ADC1_INP3
     PC4 ------> ADC1_INP4
     PB1 ------> ADC1_INP5
     */
     GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
     |GPIO_PIN_4;
     GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
    
     GPIO_InitStruct.Pin = GPIO_PIN_6;
     GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
     GPIO_InitStruct.Pin = GPIO_PIN_1;
     GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    
     /* ADC1 interrupt Init */
     HAL_NVIC_SetPriority(ADC1_IRQn, 0, 0);
     HAL_NVIC_EnableIRQ(ADC1_IRQn);
     /* USER CODE BEGIN ADC1_MspInit 1 */
    
     /* USER CODE END ADC1_MspInit 1 */
     }
     else if(hadc->Instance==ADC2)
     {
     /* USER CODE BEGIN ADC2_MspInit 0 */
    
     /* USER CODE END ADC2_MspInit 0 */
     /* Peripheral clock enable */
     HAL_RCC_ADC_CLK_ENABLED++;
     if(HAL_RCC_ADC_CLK_ENABLED==1){
     __HAL_RCC_ADC_CLK_ENABLE();
     }
    
     __HAL_RCC_GPIOC_CLK_ENABLE();
     __HAL_RCC_GPIOA_CLK_ENABLE();
     /**ADC2 GPIO Configuration
     PC3 ------> ADC2_INP13
     PA6 ------> ADC2_INP3
     PA7 ------> ADC2_INP7
     PC5 ------> ADC2_INP8
     */
     GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_5;
     GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
    
     GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
     GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
     /* ADC2 interrupt Init */
     HAL_NVIC_SetPriority(ADC2_IRQn, 0, 0);
     HAL_NVIC_EnableIRQ(ADC2_IRQn);
     /* USER CODE BEGIN ADC2_MspInit 1 */
    
     /* USER CODE END ADC2_MspInit 1 */
     }
    
    }

     

     

    Graduate II
    July 12, 2024

    Whoa, that's one busy little chip you have there. I'm sorry, everything looks OK to me. You do know that it's something that has to do with async vs. sync (PLL vs. HCLK), but I don't have an idea on what the next stop for debugging is.

     

    You can un-accept the solution using the little down-arrow menu button at the top-right of the accepted solution. I hope someone else can offer more help.

     

    (Turns out HAL_ADC_MspInit is irrelevant on this family. On other familes that's where PLL2 conf code is generated)

    Graduate II
    July 12, 2024

    One weak test that comes to mind, use RCC Master Clock Oot (MCO) to route out the generate PLL clock and check the frequency with scope. You can't route PLL2R out to MCO, but you can duplicate its PLL config to whatever PLL can be sent out to MCO and check. If the freq is wrong, you've learned something, if it's OK you've learned nothing.

     

    For that matter, sending HCLK out through MCO (use the MCO divider for easier measurement) and verifying that its frequency matches what you expect is also a worthwhile test. You've already measured it indirectly using the ADC tick measurement, but using the MCO is a direct test and therefore preferred.