Skip to main content
Graduate II
August 21, 2024
Solved

Create external signal with clock 100 Mhz in STM32H745

  • August 21, 2024
  • 7 replies
  • 4904 views

Hi all, I have already searched on the forms and in general did not find an answer to my problem, I will be very grateful to you for help.
I need to create an output signal with a frequency of 100 Mhz as CLK in  STM32H745. I used the Discovery Boards (STM32H745I-DISCO STM32H750B-DK) for the test. 

 

1. I used timers with PWM and adjusted the ABM timer clock for 220 MHz, set up pre-scaler and counter period

img_1.bmp 

But I achieve only 50 Mhz a clock as a maximum, with settings for 100 Mhz there is nothing at the output for CLK. To detect the clock I use PicOscope6404D (Bandwidth 500 Mhz).

 

2. I used as output ch A8 and adjusted A8 for  RCC_MCO_1

I used the next settings but received the same result as for Timers not more than 50 MHz. Can you explain why I have this limitation (because the device settings show me that I can reach 100 Mhz but in real not )?

img_1.bmp

 

3. Finally I used the PA8  HRTIM_CHB2 timer and received high and very unstable frequency with very low amplitude. Do you how I can make a stable frequency and increase amplitude from HRTIM_CHB2?

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

     

    HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_1);

    replace to

    HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_PLL1QCLK, RCC_MCODIV_5);

     

     

    but timers still don't work for 100 Mhz

    7 replies

    Graduate II
    August 22, 2024

    I'm not sure anything except dividing the internal clock and outputting it via the dedicated RCC MCO pin is a good idea, 100Mhz for GPIO pins seems unrealistic.

     

    Try setting the GPIO drive strength higher via the GPIOx_OSPEEDR registers. Let us know if it works or not.

     

    RonilAuthor
    Graduate II
    August 22, 2024

    Thank you, I will try, I just was wondering if STM Cube showed me that is possible in fact doesnt work 

    Explorer
    August 22, 2024

    Should work, I have H743 running spi at 120 MHz SCLK. 

    Try osciloscope probe with 1:10 divider to minimize capacitance.

    RonilAuthor
    Graduate II
    August 22, 2024

    Hello, thank you, what do you menas should work? timers, RCO,  GPIOx_OSPEEDR registers or just SPI protocol?

    Explorer
    August 22, 2024

    I mean GPIO needs  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

    For RCO there is no GPIO stettings , publish your code so we can see if it's really configured, for ex.:

     HAL_RCC_MCOConfig(RCC_MCO2, RCC_MCO2SOURCE_SYSCLK, RCC_MCODIV_10); 

    Same apply for Timer. print code.

    If you don't know capacitance of oscilloscope probe, use a buffer kind of "active probe"

     

    Technical Moderator
    August 22, 2024

    Hello @Ronil ,

    I kindly requested an internal colleague to do the test on a Nucleo H753 with KEYSIGHT DSO9254A oscilloscope. 100MHz is output on the MCO pin like shown in this oscillo screenshot:

    SofLit_0-1724322673728.png

    So you need to use an adequate oscilloscope and probes for these high frequencies.

     

    RonilAuthor
    Graduate II
    August 22, 2024

    thank you so much, I use PiScope which operates until 500 Mhz, can you watch my script I expect receive 96 Mhz, but  is nothing 

     

     

    /* USER CODE BEGIN Header */
    /**
     ******************************************************************************
     * @file : main.c
     * @brief : Main program body
     ******************************************************************************
     * @attention
     *
     * Copyright (c) 2024 STMicroelectronics.
     * All rights reserved.
     *
     * This software is licensed under terms that can be found in the LICENSE file
     * in the root directory of this software component.
     * If no LICENSE file comes with this software, it is provided AS-IS.
     *
     ******************************************************************************
     */
    /* USER CODE END Header */
    /* Includes ------------------------------------------------------------------*/
    #include "main.h"
    
    /* Private includes ----------------------------------------------------------*/
    /* USER CODE BEGIN Includes */
    
    /* USER CODE END Includes */
    
    /* Private typedef -----------------------------------------------------------*/
    /* USER CODE BEGIN PTD */
    
    /* USER CODE END PTD */
    
    /* Private define ------------------------------------------------------------*/
    /* USER CODE BEGIN PD */
    
    /* USER CODE END PD */
    
    /* Private macro -------------------------------------------------------------*/
    /* USER CODE BEGIN PM */
    
    /* USER CODE END PM */
    
    /* Private variables ---------------------------------------------------------*/
    
    TIM_HandleTypeDef htim13;
    TIM_HandleTypeDef htim15;
    
    /* USER CODE BEGIN PV */
    
    /* USER CODE END PV */
    
    /* Private function prototypes -----------------------------------------------*/
    void SystemClock_Config(void);
    static void MPU_Config(void);
    static void MX_GPIO_Init(void);
    static void MX_TIM15_Init(void);
    static void MX_TIM13_Init(void);
    /* USER CODE BEGIN PFP */
    
    /* USER CODE END PFP */
    
    /* Private user code ---------------------------------------------------------*/
    /* USER CODE BEGIN 0 */
    
    /* USER CODE END 0 */
    
    /**
     * @brief The application entry point.
     * @retval int
     */
    int main(void)
    {
    
     /* USER CODE BEGIN 1 */
    
     /* USER CODE END 1 */
    
     /* MPU Configuration--------------------------------------------------------*/
     MPU_Config();
    
     /* MCU Configuration--------------------------------------------------------*/
    
     /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
     HAL_Init();
    
     /* USER CODE BEGIN Init */
    
     /* USER CODE END Init */
    
     /* Configure the system clock */
     SystemClock_Config();
    
     /* USER CODE BEGIN SysInit */
    
     /* USER CODE END SysInit */
    
     /* Initialize all configured peripherals */
     MX_GPIO_Init();
     MX_TIM15_Init();
     MX_TIM13_Init();
     /* USER CODE BEGIN 2 */
    
     /* USER CODE END 2 */
    
     /* Infinite loop */
     /* USER CODE BEGIN WHILE */
    
     // HAL_TIM_PWM_Start(&htim15, TIM_CHANNEL_2);
    
    // HAL_TIM_PWM_Start(&htim13, TIM_CHANNEL_1);
    
     //HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
    
     // HAL_HRTIM_WaveformOutputStart(&hhrtim, HRTIM_OUTPUT_TB2); // Enable the generation of the waveform signal on the designated output
    // HAL_HRTIM_WaveformCounterStart(&hhrtim, HRTIM_TIMERID_TIMER_B); // Start the counter of the Timer A operating in waveform mode
     // HAL_RCC_MCOConfig(RCC_MCO2, RCC_MCO2SOURCE_SYSCLK, RCC_MCODIV_10);
    
     HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO2SOURCE_SYSCLK, RCC_MCODIV_1);
    
     HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO2SOURCE_SYSCLK, RCC_MCODIV_1);
    
     while (1)
     {
     /* USER CODE END WHILE */
    
     /* USER CODE BEGIN 3 */
     }
     /* USER CODE END 3 */
    }
    
    /**
     * @brief System Clock Configuration
     * @retval None
     */
    void SystemClock_Config(void)
    {
     RCC_OscInitTypeDef RCC_OscInitStruct = {0};
     RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
    
     /** Supply configuration update enable
     */
     HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
    
     /** Configure the main internal regulator output voltage
     */
     __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
    
     while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
    
     __HAL_RCC_SYSCFG_CLK_ENABLE();
     __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);
    
     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_HSI;
     RCC_OscInitStruct.HSIState = RCC_HSI_DIV1;
     RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
     RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
     RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
     RCC_OscInitStruct.PLL.PLLM = 10;
     RCC_OscInitStruct.PLL.PLLN = 150;
     RCC_OscInitStruct.PLL.PLLP = 2;
     RCC_OscInitStruct.PLL.PLLQ = 2;
     RCC_OscInitStruct.PLL.PLLR = 2;
     RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2;
     RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
     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_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
     RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
     RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
     RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
     RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
     RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
     RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
     RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
    
     if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
     {
     Error_Handler();
     }
     __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL1_DIVQ);
     HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_PLL1QCLK, RCC_MCODIV_3);
    }
    
    /**
     * @brief TIM13 Initialization Function
     * @PAram None
     * @retval None
     */
    static void MX_TIM13_Init(void)
    {
    
     /* USER CODE BEGIN TIM13_Init 0 */
    
     /* USER CODE END TIM13_Init 0 */
    
     TIM_OC_InitTypeDef sConfigOC = {0};
    
     /* USER CODE BEGIN TIM13_Init 1 */
    
     /* USER CODE END TIM13_Init 1 */
     htim13.Instance = TIM13;
     htim13.Init.Prescaler = 0;
     htim13.Init.CounterMode = TIM_COUNTERMODE_UP;
     htim13.Init.Period = 2;
     htim13.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
     htim13.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
     if (HAL_TIM_Base_Init(&htim13) != HAL_OK)
     {
     Error_Handler();
     }
     if (HAL_TIM_PWM_Init(&htim13) != HAL_OK)
     {
     Error_Handler();
     }
     sConfigOC.OCMode = TIM_OCMODE_PWM1;
     sConfigOC.Pulse = 1;
     sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
     sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
     if (HAL_TIM_PWM_ConfigChannel(&htim13, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
     {
     Error_Handler();
     }
     /* USER CODE BEGIN TIM13_Init 2 */
    
     /* USER CODE END TIM13_Init 2 */
     HAL_TIM_MspPostInit(&htim13);
    
    }
    
    /**
     * @brief TIM15 Initialization Function
     * @PAram None
     * @retval None
     */
    static void MX_TIM15_Init(void)
    {
    
     /* USER CODE BEGIN TIM15_Init 0 */
    
     /* USER CODE END TIM15_Init 0 */
    
     TIM_MasterConfigTypeDef sMasterConfig = {0};
     TIM_OC_InitTypeDef sConfigOC = {0};
     TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};
    
     /* USER CODE BEGIN TIM15_Init 1 */
    
     /* USER CODE END TIM15_Init 1 */
     htim15.Instance = TIM15;
     htim15.Init.Prescaler = 0;
     htim15.Init.CounterMode = TIM_COUNTERMODE_UP;
     htim15.Init.Period = 65535;
     htim15.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
     htim15.Init.RepetitionCounter = 0;
     htim15.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
     if (HAL_TIM_PWM_Init(&htim15) != HAL_OK)
     {
     Error_Handler();
     }
     sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
     sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
     if (HAL_TIMEx_MasterConfigSynchronization(&htim15, &sMasterConfig) != HAL_OK)
     {
     Error_Handler();
     }
     sConfigOC.OCMode = TIM_OCMODE_PWM1;
     sConfigOC.Pulse = 0;
     sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
     sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
     sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
     sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
     sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
     if (HAL_TIM_PWM_ConfigChannel(&htim15, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
     {
     Error_Handler();
     }
     sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
     sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
     sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
     sBreakDeadTimeConfig.DeadTime = 0;
     sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
     sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
     sBreakDeadTimeConfig.BreakFilter = 0;
     sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
     if (HAL_TIMEx_ConfigBreakDeadTime(&htim15, &sBreakDeadTimeConfig) != HAL_OK)
     {
     Error_Handler();
     }
     /* USER CODE BEGIN TIM15_Init 2 */
    
     /* USER CODE END TIM15_Init 2 */
     HAL_TIM_MspPostInit(&htim15);
    
    }
    
    /**
     * @brief GPIO Initialization Function
     * @PAram None
     * @retval None
     */
    static void MX_GPIO_Init(void)
    {
     GPIO_InitTypeDef GPIO_InitStruct = {0};
    /* USER CODE BEGIN MX_GPIO_Init_1 */
    /* USER CODE END MX_GPIO_Init_1 */
    
     /* GPIO Ports Clock Enable */
     __HAL_RCC_GPIOE_CLK_ENABLE();
     __HAL_RCC_GPIOA_CLK_ENABLE();
     __HAL_RCC_GPIOH_CLK_ENABLE();
     __HAL_RCC_GPIOJ_CLK_ENABLE();
    
     /*Configure GPIO pin Output Level */
     HAL_GPIO_WritePin(GPIOJ, GPIO_PIN_2, GPIO_PIN_RESET);
    
     /*Configure GPIO pin : PA8 */
     GPIO_InitStruct.Pin = GPIO_PIN_8;
     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
     GPIO_InitStruct.Alternate = GPIO_AF0_MCO;
     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
     /*Configure GPIO pin : PJ2 */
     GPIO_InitStruct.Pin = GPIO_PIN_2;
     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
     HAL_GPIO_Init(GPIOJ, &GPIO_InitStruct);
    
    /* USER CODE BEGIN MX_GPIO_Init_2 */
    /* USER CODE END MX_GPIO_Init_2 */
    }
    
    /* USER CODE BEGIN 4 */
    
    /* USER CODE END 4 */
    
     /* MPU Configuration */
    
    void MPU_Config(void)
    {
     MPU_Region_InitTypeDef MPU_InitStruct = {0};
    
     /* Disables the MPU */
     HAL_MPU_Disable();
    
     /** Initializes and configures the Region and the memory to be protected
     */
     MPU_InitStruct.Enable = MPU_REGION_ENABLE;
     MPU_InitStruct.Number = MPU_REGION_NUMBER0;
     MPU_InitStruct.BaseAddress = 0x0;
     MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
     MPU_InitStruct.SubRegionDisable = 0x87;
     MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
     MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
     MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
     MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
     MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
     MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
    
     HAL_MPU_ConfigRegion(&MPU_InitStruct);
     /* Enables the MPU */
     HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
    
    }
    
    /**
     * @brief This function is executed in case of error occurrence.
     * @retval None
     */
    void Error_Handler(void)
    {
     /* USER CODE BEGIN Error_Handler_Debug */
     /* User can add his own implementation to report the HAL error return state */
     __disable_irq();
     while (1)
     {
     }
     /* USER CODE END Error_Handler_Debug */
    }
    
    #ifdef USE_FULL_ASSERT
    /**
     * @brief Reports the name of the source file and the source line number
     * where the assert_param error has occurred.
     * @PAram file: pointer to the source file name
     * @PAram line: assert_param error line source number
     * @retval None
     */
    void assert_failed(uint8_t *file, uint32_t line)
    {
     /* USER CODE BEGIN 6 */
     /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
     /* USER CODE END 6 */
    }
    #endif /* USE_FULL_ASSERT */

     

     

    RonilAuthor
    Graduate II
    August 22, 2024

    Probably I solved the problem! thank you all!

    Graduate II
    August 22, 2024

    If someone provided the critical advice, or just gave you a serious nudge in the right direction, the polite thing is to thank them by accepting their answer. It's fine to accept your own solution if you found it on your own. 

     

    It's not just the bandwidth of your scope that determines the measurement bandwidth, but also the bandwidth of your probes. Good quality 10x passive probes should handle a 100Mhz sine wave.

     

    RonilAuthor
    Graduate II
    August 23, 2024

    I only wonder why my amplitude is only 1 V, can I control the value of the amplitude of the signal?

    I used and another scale but result the same

    __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);  

    from RCC_MCO_1? ?amplitide.jpg

    Graduate II
    August 23, 2024

    Voltage scaling is unrelated to the amplitude of the crystal oscillator's output signal.  

     

    It's normal for the clock oscillator circuit itself (i.e. the chip's XTAL pins) to stabilize at this kind of amplitude. I'm not sure if the MCO output is supposed to be a buffered copy of the signal at the XTAL pins or a proper digital signal (but I note that the scope shows it looks like an analog sine wave). I'm not aware of any way to control the oscillator circuit's steady-state amplitude (It's the combined result of design choices by ST and the crystal used). 

     

    If you need a logic signal, you can try PWM with the GPIO pin set to a higher speed.

    RonilAuthor
    Graduate II
    August 23, 2024

    Thank you

    Do you mean to use PWM without a timer directly via GPIO?

    Because PWM with Timer can create about 20 Mhz, but cant 100 Mhz

    Graduate II
    August 23, 2024

    What does "PWM without a timer" mean? no.

     

    The PWM signal, AFAIK, is sent out through the same output driver, and is affected by the same GPIO speed register setting.

     

    I don't know where you get this 20Mhz figure, your OP said you were able to go as high as 50Mhz. Did you set the GPIO speed registers to a higher speed and retest? 

     

    SoftLit's screenshot shows MCO output is ~3.3 Vpp. Are you sure your measurement equipment is set up properly? 

    Graduate II
    September 4, 2024

    So after I suggested here that he needs to set the GPIO output to a higher strength, and after MasterT also suggested the same, OP started a duplicate thread - in which @TDK suggested that he needs to set the GPIO to a higher strength. Which fixed the problem.

     

    I hate the internet. :raising_hands:

    Super User
    September 4, 2024

    @BarryWhit 

    Yes, frustrating. FWIW, same thing happens to me all the time. Answer the question in the very first response, and OP doesn't read it, or ignores it, or something. Sorry about that.

    A screenshot showing how/where to adjust the setting can sometimes improve your chances here.

    RonilAuthor
    Graduate II
    September 4, 2024

    Hello, actually it is works now, sorry I missed your responses 

    Graduate II
    September 4, 2024

    @TDK, certainly nothing for you to feel sorry about.

     

    Actually, I've probably done the same in the past - It's not malice. But yes quite frustrating for those trying to help. Just venting.

     

    It's also been my experience that when posters get several suggestions, they tend to pick a few (usually the easiest ones) and ignore the others. Then the thread just keeps going as if those suggestions were tested but didn't work.

    RonilAuthor
    Graduate II
    September 4, 2024

    thank you so much, I really appreciate for your support, in the future I will be more attentive to people who helped me