# Example PWM generation

***This page:** *what does the configuration look like for my board, specifically regarding PWM.**

<p class="callout danger"><span style="white-space: pre-wrap;">Make sure you have set up Ethernet according to the following page </span>**FIRST**<span style="white-space: pre-wrap;">: </span>[Introduction and initial setup of embedded ethernet](https://bookstack.roboteamtwente.nl/books/communication-system/page/setup-of-embedded-ethernet "Introduction and initial setup of embedded ethernet")</p>

---

## **PWM**

> **Pulse Width Modulation** <span style="white-space: pre-wrap;">(PWM) is a technique for generating a continuous HIGH/LOW alternating digital signal and programmatically controlling its pulse width and frequency. Certain loads like (LEDs, Motors, etc) will respond to the </span>**average voltage**<span style="white-space: pre-wrap;"> of the signal which gets higher as the PWM signal’s pulse width is increased. This technique is widely used in embedded systems to control LEDs brightness, motor speed, and other applications. </span>  
> <span style="white-space: pre-wrap;">&gt; </span>[DeepblueMbedded.com](https://deepbluembedded.com/stm32-pwm-example-timer-pwm-mode-tutorial/)

<span style="white-space: pre-wrap;">On the embedded subteam, we use PWM to control the motors for the Robotic arm and </span>[Drive system](https://bookstack.roboteamtwente.nl/books/drive-system "Drive system")<span style="white-space: pre-wrap;">. In the world of PWM, two metrics are most important: </span>**duty cycle** <span style="white-space: pre-wrap;">and </span>**frequency**. The duty cycle is determined by the percentage of high/low signal, for example a 75% duty cycle means that the signal is HIGH 75% of the time. How long this total time is, is determined by the frequency. The frequency is to determine motor speed.

[![afbeelding.png](https://bookstack.roboteamtwente.nl/uploads/images/gallery/2026-04/scaled-1680-/NaAafbeelding.png)](https://bookstack.roboteamtwente.nl/uploads/images/gallery/2026-04/NaAafbeelding.png)

---

## **CubeMX**

<p class="callout danger"><span style="white-space: pre-wrap;">Make sure you have set up Ethernet according to the following page </span>**FIRST**<span style="white-space: pre-wrap;">: </span>[Introduction and initial setup of embedded ethernet](https://bookstack.roboteamtwente.nl/books/communication-system/page/setup-of-embedded-ethernet "Introduction and initial setup of embedded ethernet")</p>

### 1) Setting Pins

<span style="white-space: pre-wrap;">The only pin that is set at the moment (except for defaults) is </span>**PA0**. It is set to TIM2\_CH1, this means it uses Timer 2 Channel 1 for something, in this case it is PWM generation.

[![afbeelding.png](https://bookstack.roboteamtwente.nl/uploads/images/gallery/2026-04/scaled-1680-/ze1afbeelding.png)](https://bookstack.roboteamtwente.nl/uploads/images/gallery/2026-04/ze1afbeelding.png)

<span style="white-space: pre-wrap;">If we want to set more pins to generate PWM signals, we can use a workflow similar to what will be described below. Of course, you will need to choose a </span>**separate timer**<span style="white-space: pre-wrap;"> for each pin. Also make sure that the pin is </span>**suitable** for PWM!

##### **TIM2 &gt; Mode** 

<span style="white-space: pre-wrap;">After you have set the pin, you need to enable the timer and channel to do something. We set </span>`<span class="editor-theme-code">Clock Source: Internal Clock</span>`<span style="white-space: pre-wrap;"> to enable the timer and </span>`<span class="editor-theme-code">Channel1: PWM Generation CH1 </span>`to use PWM on pin PA0.

[![afbeelding.png](https://bookstack.roboteamtwente.nl/uploads/images/gallery/2026-04/scaled-1680-/a8Xafbeelding.png)](https://bookstack.roboteamtwente.nl/uploads/images/gallery/2026-04/a8Xafbeelding.png)

##### **TIM2 &gt; Configuration &gt; NVIC settings** 

Enable global interrupt.

[![afbeelding.png](https://bookstack.roboteamtwente.nl/uploads/images/gallery/2026-04/scaled-1680-/phDafbeelding.png)](https://bookstack.roboteamtwente.nl/uploads/images/gallery/2026-04/phDafbeelding.png)

##### **TIM2 &gt; Configuration &gt; Parameter settings &gt; Counter settings**

[![afbeelding.png](https://bookstack.roboteamtwente.nl/uploads/images/gallery/2026-04/scaled-1680-/lTKafbeelding.png)](https://bookstack.roboteamtwente.nl/uploads/images/gallery/2026-04/lTKafbeelding.png)<p class="callout info">**NOTE:** -1 for prescaler and counter period because of 0 index counting</p>

<span style="white-space: pre-wrap;">To fully configure the PWM generation, we have to set the above parameters. The </span>**prescaler** <span style="white-space: pre-wrap;">has to do with the clock configuration. You want to set the prescaler </span>**equal to the amount of MHz in the clock configuration**<span style="white-space: pre-wrap;">, because we will divide the clock frequency by the prescaler! Here, we have set the </span>**clock speed to 84 MHz** <span style="white-space: pre-wrap;">(see </span>[Clock configuration](#bkmrk-clock-configuration "Clock configuration")<span style="white-space: pre-wrap;">), so we set the prescaler to 84 (-1) as well. This way we work with </span>**1MHz**<span style="white-space: pre-wrap;"> in calculating the counter period for the wished for PWM frequency (see below). </span>

[![afbeelding.png](https://bookstack.roboteamtwente.nl/uploads/images/gallery/2026-04/scaled-1680-/xC5afbeelding.png)](https://bookstack.roboteamtwente.nl/uploads/images/gallery/2026-04/xC5afbeelding.png)

<p class="callout info">**NOTE:**<span style="white-space: pre-wrap;"> the counter period parameter uses the ARR (AutoReload Register). Those terms are used interchangeably in online sources.</span></p>

<span style="white-space: pre-wrap;">As of now, the counter period is at </span>**65535**<span style="white-space: pre-wrap;">, which is the maximum value for an unsigned 16bit integer. This results in a PWM frequency of </span><span style="color: rgb(0, 0, 0);">1098Hz</span><span style="white-space: pre-wrap;">. The </span>**frequency** <span style="white-space: pre-wrap;">of PWM should be suitable for the motor you are using. We can change this value later. For more information on PWM see </span>[resource 1](https://deepbluembedded.com/stm32-pwm-example-timer-pwm-mode-tutorial/).

### 2) Clock configuration

<span style="white-space: pre-wrap;">The board can be optimized to run at a higher frequency than is preconfigured. You can set the system clock to work at </span>**84 MHz**<span style="white-space: pre-wrap;"> by setting any of the right-hand clocks in the clock configuration menu to 84. The program then auto calculates the settings for the system, also see </span>[resource 2](https://youtu.be/zHWvFchXhvw?si=nGj-vzkVCszjHonW)<span style="white-space: pre-wrap;">. </span>

[![afbeelding.png](https://bookstack.roboteamtwente.nl/uploads/images/gallery/2026-04/scaled-1680-/oysafbeelding.png)](https://bookstack.roboteamtwente.nl/uploads/images/gallery/2026-04/oysafbeelding.png)

---

## **Resources**

1. [Deepbluembedded.com: STM32 PWM Output Example Code (PWM Generation Tutorial)](https://deepbluembedded.com/stm32-pwm-example-timer-pwm-mode-tutorial/)
2. [YouTube: STM32 Beginners Guide Part3: PWM, TIMERS, Frequency and Duty Cycle. LED Dimming with PWM example.](https://youtu.be/zHWvFchXhvw?si=nGj-vzkVCszjHonW)