STM32H7 minimal PWM output example using ST HAL

The following example is the minimal code to use the ST HAL library to output a PWM signal on a pin of an STM32H7 microcontroller. In this example, we use the Nucleo-H753ZI board with a STM32H753ZI microcontroller.

We use TIM2 to generate the PWM signal and the compare channel TIM2_CH1 which is output on pin PA5.

#include <stm32h7xx_hal.h>

/**
 * Initialize PWM output for generating test pulses.
 */
TIM_HandleTypeDef pwmOutputTimer;
TIM_OC_InitTypeDef pwmOutputConfig = {0};

void PWM_Output_Init() {
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_TIM2_CLK_ENABLE();

    /**
     * Parameters for measurement:
     *   Prescaler = 9,
     *   Period = 48,
     *   Pulse = (Period + 1) / 8
     * Measured values (average over 5k measurements, DSO-X 3024A):
     *   On time: 234.36ns
     *   Frequency: 495.34 kHz
     */

    pwmOutputTimer.Instance = TIM2;
    pwmOutputTimer.Init.Prescaler = 9;  // TIM2 clock prescaler (PSC)
    pwmOutputTimer.Init.CounterMode = TIM_COUNTERMODE_UP;
    pwmOutputTimer.Init.Period = 48;    // Auto-reload value (ARR) for 10 kHz
    pwmOutputTimer.Init.ClockDivision = TIM_CLOCKDIVISION_DIV2;
    pwmOutputTimer.Init.RepetitionCounter = 0;
    if (HAL_TIM_PWM_Init(&pwmOutputTimer) != HAL_OK)
    {
        SendLogMessage("PWM output Timer Initialization Error");
    }

    // PWM configuration for TIM2 Channel 1
    pwmOutputConfig.OCMode = TIM_OCMODE_PWM1;
    pwmOutputConfig.Pulse = (pwmOutputTimer.Init.Period + 1) / 8; // 50% duty cycle
    pwmOutputConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
    pwmOutputConfig.OCFastMode = TIM_OCFAST_DISABLE;
    if (HAL_TIM_PWM_ConfigChannel(&pwmOutputTimer, &pwmOutputConfig, TIM_CHANNEL_1) != HAL_OK)
    {
        // PWM Configuration Error
        SendLogMessage("PWM output Configuration Error");
    }

    // Configure GPIO:
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    // Enable GPIOA clock
    __HAL_RCC_GPIOA_CLK_ENABLE();

    // Configure PA5 as alternate function for TIM2_CH1
    GPIO_InitStruct.Pin = GPIO_PIN_5;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;  // TIM2 AF on PA5
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    HAL_TIM_PWM_Start(&pwmOutputTimer, TIM_CHANNEL_1);
}

The signal looks like this for my board

STM32H7 PWM signal measurement