In this tutorial, we’ll walk through the steps to create a project for fading an LED using Pulse Width Modulation (PWM) on an STM32 microcontroller. We’ll use the STM32CubeMX tool to generate the initialization code and set up the PWM, and then we will write the code to control the brightness of the LED.
Requirements
- STM32 microcontroller (e.g., STM32F4 Discovery, STM32F0 Nucleo board, etc.)
- STM32CubeMX (for code generation)
- STM32CubeIDE (or any compatible IDE like Keil, IAR, etc.)
- LED (or the onboard LED, if your board has one)
- Resistor (if using an external LED)
- USB cable (for powering and programming the board)
Steps
1. Create a New STM32CubeMX Project
- Open STM32CubeMX and click on New Project.
- Select your microcontroller or board from the available list (e.g., STM32F407VG for STM32F4 Discovery).
- Click Start Project.
2. Configure the PWM Output Pin
To use PWM, we need to configure one of the general-purpose timers (TIM) and assign a pin for the PWM signal output.
- Enable the timer:
- In the Pinout & Configuration tab, locate the Timers section.
- Enable one of the timers capable of PWM (e.g., TIM3 or TIM2). Click the dropdown arrow and select PWM Generation CH1 (or any available channel).
- Assign a pin for PWM:
- Once you select a PWM channel, CubeMX will automatically assign a GPIO pin as the PWM output. For instance, if you select TIM3 CH1, it might assign PA6 as the output pin. You can confirm the pin in the Pinout view.
- Ensure the pin is configured as PWM output.
3. Configure the Timer for PWM
Now we need to configure the timer’s frequency and duty cycle.
- Go to the Configuration tab:
- In the Peripherals tree (on the left), expand Timers and select TIM3 (or your selected timer).
- Set PWM frequency:
Set the Prescaler and Counter Period to achieve your desired PWM frequency. The PWM frequency is calculated using the formula:
PWM frequency = Timer clock / [(Prescaler + 1) * (Period + 1)]
- For example, if the timer clock is 84 MHz, and you want a PWM frequency of 1 kHz, you can set the prescaler to 83 and the period to 999.
- Set the Duty Cycle:
- The duty cycle determines the LED brightness. A duty cycle of 0% (0 in the Compare value register) will turn the LED off, and a duty cycle of 100% (equal to the period value) will turn the LED fully on. You can dynamically adjust this in your code later.
- Enable the Timer:
- In the same configuration window, ensure the timer is set to PWM mode and the Output Compare is enabled for the selected channel (e.g., CH1).
4. Configure the Clock
Ensure the clock configuration is correctly set. Typically, STM32CubeMX will auto-configure the clock based on the default settings, but verify that the APB1/2 timers are enabled and running at the correct frequency for your chosen timer.
5. Generate Code
- Click on Project Manager and give your project a name.
- Choose your preferred toolchain (e.g., STM32CubeIDE).
- Click Generate Code.
6. Writing the Code in STM32CubeIDE
Once you generate the project, open it in STM32CubeIDE (or your chosen IDE). STM32CubeMX has already generated the initialization code, so we’ll focus on adding the logic to adjust the PWM duty cycle.
- Open the main.c file.
- The timer and GPIO initialization should already be done in the MX_TIM3_Init() function.
- Inside the main() function, start the PWM signal generation by adding:
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
This function starts the PWM generation on TIM3 channel 1 (which is linked to PA6 or the pin you configured).
Now, let’s create a simple loop to gradually increase and decrease the LED brightness using the PWM duty cycle:
while (1)
{
// Gradually increase brightness
for (int duty = 0; duty < __HAL_TIM_GET_AUTORELOAD(&htim3); duty++)
{
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, duty); // Set the duty cycle
HAL_Delay(10); // Small delay to see the fade effect
}
// Gradually decrease brightness
for (int duty = __HAL_TIM_GET_AUTORELOAD(&htim3); duty > 0; duty--)
{
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, duty); // Set the duty cycle
HAL_Delay(10); // Small delay to see the fade effect
}
}
7. Build and Flash the Code
- Build the project by clicking the build button (hammer icon).
- Flash the code to your STM32 board by clicking the debug/run button (bug or play icon).
8. Testing
If everything is set up correctly, your LED should start fading in and out as the PWM duty cycle changes from 0% to 100% and back. The LED’s brightness will gradually increase and then decrease, creating a fading effect.
Summary
In this tutorial, we created a project using STM32CubeMX to generate the code for PWM control. We configured a timer to generate PWM signals, wrote code to adjust the duty cycle dynamically, and successfully created a fading effect for an LED.
Key Concepts:
- PWM: Used to control the brightness of an LED by adjusting the duty cycle.
- STM32CubeMX: Simplifies peripheral configuration and code generation.
- Timers: Essential for PWM generation in STM32.
You can modify the frequency, adjust the fade speed, or control multiple LEDs using the same process.