100% found this document useful (1 vote)
43 views7 pages

PWM Nucleo

This tutorial provides a step-by-step guide on using Timers and Pulse Width Modulation (PWM) on the STM32F767 Nucleo board to control LED brightness. It covers hardware setup, STM32CubeIDE project configuration, application code implementation, and testing the PWM control. The LED fades in and out based on the duty cycle adjustments made in the code, demonstrating effective power control in embedded systems.

Uploaded by

Gizem Ateş
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
43 views7 pages

PWM Nucleo

This tutorial provides a step-by-step guide on using Timers and Pulse Width Modulation (PWM) on the STM32F767 Nucleo board to control LED brightness. It covers hardware setup, STM32CubeIDE project configuration, application code implementation, and testing the PWM control. The LED fades in and out based on the duty cycle adjustments made in the code, demonstrating effective power control in embedded systems.

Uploaded by

Gizem Ateş
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 7

Here's a short tutorial on using Timers and Pulse Width Modulation

(PWM) on the STM32F767 Nucleo board. PWM is a powerful technique for


controlling the average power delivered to a load by varying the duty cycle
of a square wave, commonly used for dimming LEDs, controlling motor
speed, generating audio, and more.

Tutorial: LED Brightness Control with PWM

Objective: Control the brightness of an LED connected to a GPIO pin using a


Timer in PWM mode.

Components:

 STM32F767 Nucleo-144 board

 LED (any color)

 Current-limiting resistor (e.g., 220 Ohm to 1k Ohm)

 Jumper wires

1. Hardware Setup:

We'll use Timer 2, Channel 1, which is typically mapped to pin PA0 on the
Nucleo-144 board.

 Connect the long leg (anode) of the LED to one end of the current-
limiting resistor.

 Connect the other end of the resistor to pin PA0 on the STM32F767
Nucleo board.

 Connect the short leg (cathode) of the LED to a GND pin on the
Nucleo board.

(Resistor value: For a typical 3.3V power supply and a red LED with
~2V forward voltage and 20mA current, a 68-75 Ohm resistor would
be ideal. However, 220 Ohm to 1k Ohm is a safer starting point to
prevent damaging the LED or microcontroller pin and will still allow
visible brightness.)

2. STM32CubeIDE Project Setup:

1. Create a New Project:

o Open STM32CubeIDE and go to File > New > STM32 Project.


o Select Board Selector and search for NUCLEO-F767ZI. Select it
and click Next.

o Give your project a name (e.g., PWM_LED_Control) and click


Finish.

2. Configure Clock System:

o In the Pinout & Configuration tab, navigate to System Core >


RCC.

o For High Speed Clock (HSE), select Crystal/Ceramic Resonator.

o For Low Speed Clock (LSE), select Crystal/Ceramic Resonator.

o Go to Clock Configuration tab. The tool will automatically suggest


optimal clock settings. Click Resolve Clock Issues if prompted,
and ensure the HCLK is set to 216 MHz.

3. Configure Timer 2 for PWM:

o In the Pinout & Configuration tab, navigate to Timers > TIM2.

o Set Clock Source to Internal Clock.

o Under Channel1, set Mode to PWM Generation Channel 1.

o Observe that pin PA0 is now configured as TIM2_CH1.

o In the Parameter Settings tab for TIM2:

 Prescaler: Set to 107. (This will divide the APB1 Timer


clock (108MHz) by 108, resulting in a 1MHz counter clock,
meaning 1 tick per microsecond).

 Counter Period (ARR): Set to 999. (The counter will


count from 0 to 999, so 1000 ticks. With a 1MHz counter
clock, this gives a PWM frequency of 1MHz / 1000 = 1
kHz).

 Pulse (CCR1): Set an initial value, e.g., 500. (This means


the output will be high for 500 out of 1000 ticks, giving a
50% duty cycle).

4. Configure USART (for Debugging - Optional):

o Navigate to Connectivity > USART3.

o Set Mode to Asynchronous.


o In Parameter Settings, set Baud Rate to 115200.

o In Advanced Settings, enable Global Interrupt for USART3 global


interrupt.

o Enable printf redirection: In Project Manager tab, under Code


Generator, check Enable Trace and Debug (SWV). (Alternatively,
if you prefer printf over UART, you'll need to enable _write in
Core/Src/syscalls.c and ensure it uses HAL_UART_Transmit).

5. Generate Code: Save your .ioc file (Ctrl+S). STM32CubeIDE will


prompt you to generate code. Click Yes.

3. Application Code (main.c):

Open Core/Src/main.c. Add the following code snippets.

For printf redirection (if using UART method, not SWV):

/* USER CODE BEGIN Includes */

#include <stdio.h> // For printf

/* USER CODE END Includes */

/* USER CODE BEGIN 0 */

// Redirect printf to UART

#ifdef __GNUC__

#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)

#else

#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)

#endif /* __GNUC__ */

PUTCHAR_PROTOTYPE

HAL_UART_Transmit(&huart3, (uint8_t *)&ch, 1, 0xFFFF);


return ch;

/* USER CODE END 0 */

Inside main() function:

int main(void)

/* USER CODE BEGIN 1 */

uint16_t pwm_duty_cycle = 0; // Variable to control LED brightness

int8_t duty_cycle_direction = 1; // 1 for increasing, -1 for decreasing

/* USER CODE END 1 */

/* 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_TIM2_Init();

MX_USART3_UART_Init(); // Initialize UART for printf

/* USER CODE BEGIN 2 */

printf("Starting PWM LED Control...\r\n");

// Start the PWM signal on TIM2 Channel 1

HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);

/* USER CODE END 2 */

/* Infinite loop */

/* USER CODE BEGIN WHILE */

while (1)

/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */

// Change the duty cycle to fade the LED

__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, pwm_duty_cycle);

// Update duty cycle

pwm_duty_cycle += duty_cycle_direction * 10; // Change by 10 units each


step

// Reverse direction if limits are reached


if (pwm_duty_cycle >= 999) // Max duty cycle (Counter Period value)

duty_cycle_direction = -1;

pwm_duty_cycle = 999; // Ensure it doesn't go over

printf("Fading down...\r\n");

else if (pwm_duty_cycle <= 0) // Min duty cycle

duty_cycle_direction = 1;

pwm_duty_cycle = 0; // Ensure it doesn't go under

printf("Fading up...\r\n");

HAL_Delay(50); // Delay for a smooth fade effect

/* USER CODE END 3 */

Code Explanation:

 uint16_t pwm_duty_cycle: This variable will hold the current pulse


value for the PWM signal. It ranges from 0 (0% duty cycle, LED off) to
999 (100% duty cycle, LED full brightness).

 HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);: This function call


(placed in USER CODE BEGIN 2) starts the PWM generation on the
specified timer and channel. htim2 is the handle for Timer 2,
automatically generated by CubeIDE.

 __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1,
pwm_duty_cycle);: This macro is the core of controlling the PWM. It
sets the Pulse value (also known as the Compare Register value, CCR)
for TIM2_CH1 to pwm_duty_cycle. This directly changes the duty cycle
of the generated PWM signal.
 pwm_duty_cycle += duty_cycle_direction * 10;: This line
increments or decrements the pwm_duty_cycle by 10 in each loop
iteration, creating a fading effect.

 if (pwm_duty_cycle >= 999) ... else if (pwm_duty_cycle <=


0) ...: These if statements check if the duty cycle has reached its
maximum or minimum limits and reverse the duty_cycle_direction
accordingly, causing the LED to fade up and down continuously.

 HAL_Delay(50);: A 50ms delay between updates makes the fading


effect visible to the human eye.

4. Build and Flash:

1. Build your project (Project > Build Project or Ctrl+B).

2. Flash the code to your Nucleo board (Run > Debug then Run or Run >
Run directly).

5. Testing the PWM Control:

After flashing, you should observe the LED connected to PA0 continuously
fading up and down in brightness. If you enabled printf over UART, you'll also
see "Fading up..." and "Fading down..." messages in your serial terminal as
the fade direction changes.

This simple example demonstrates the power of hardware timers for precise
control in embedded systems. You can extend this concept to control
multiple LEDs, motors, or other devices requiring variable power.

You might also like