pwm-timer-led.c

STM32H7 Nucleo-144 (flagship: NUCLEO-H743ZI) · File : pwm-timer-led.c · Language : C · Use case : Variation de luminosité par PWM matériel (timer + canal)

A hardware PWM from an STM32 timer makes an LED breathe with no CPU cost: the channel compares against the counter and generates the waveform on its own. Duty cycle is expressed as a percentage of the CubeMX-configured period.

Hardware

A Nucleo H7 board (STM32H743ZI, Cortex-M7 @ 480 MHz) programmed via ST-LINK (USB), 3.3 V pins. 1 LED + 330 Ω resistor (3.3 V) on the PWM channel output pin.

Wiring

LED + 330 Ω between the channel pin (chosen in the .ioc, e.g. PA0 for TIM2_CH1) and GND. Check the pin supports that timer.

How it works

HAL_TIM_PWM_Start runs the channel; __HAL_TIM_SET_COMPARE sets the next compare value. The timer counts in hardware; the loop only updates the setpoint every 10 ms.

Running it

STM32CubeIDE project based on the Nucleo-H743ZI: drop the code into main.c, declare peripherals in the .ioc, then Run over ST-LINK. The ST-LINK serial monitor shows printf at 115200.

Variants

Change the frequency via the CubeMX configuration (ARR/PSC), or drive 4 channels for 4 LEDs with one timer.

pwm-timer-led.c

// PWM sur TIMx/CHx genere par CubeMX : respiration de LED.
#include "main.h"

extern TIM_HandleTypeDef htim2; // PWM 20 kHz, periode = ARR

#define PWM_CANAL TIM_CHANNEL_1

uint32_t t0 = 0;
int16_t niveau = 0;
int8_t pas = 1;

int main(void) {
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_TIM2_Init();   // broche en mode PWM dans CubeMX + LED externe

  HAL_TIM_PWM_Start(&htim2, PWM_CANAL);
  uint32_t periode = __HAL_TIM_GET_AUTORELOAD(&htim2);

  for (;;) {
    if (HAL_GetTick() - t0 >= 10) {
      t0 = HAL_GetTick();
      niveau += pas;
      if (niveau >= 100) pas = -1;
      if (niveau <= 0)   pas = 1;
      // Rapport cyclique 0..100 % de la periode du timer.
      __HAL_TIM_SET_COMPARE(&htim2, PWM_CANAL,
                            periode * niveau / 100);
    }
  }
}

← Back to the board