pwm-timer-led.c

STM32F4DISCOVERY (STM32F407VGT6 Discovery kit) · 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 STM32F407G-DISC1 (Discovery F4, Cortex-M4 @ 168 MHz) with built-in ST-LINK, 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 « STM32F407G-DISC1 »: paste the code into main.c, configure the .ioc, Run. The board has 4 LEDs (PD12-PD15) and the USER button on PA0.

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