# Stepper library

## **Purpose**

## **CubeMX**

### 1) PWM

<p class="callout info">**NOTE:**<span style="white-space: pre-wrap;"> If you are new to PWM, first take a look at </span>[Example PWM generation](https://bookstack.roboteamtwente.nl/books/robotic-arm/page/example-pwm-generation "Example PWM generation"), it is more in depth</p>

![afbeelding.png](https://bookstack.roboteamtwente.nl/uploads/images/gallery/2026-05/scaled-1680-/U6dafbeelding.png)**For each stepper**<span style="white-space: pre-wrap;">, enable pwm on channel 1. This is done by setting </span>`<span class="editor-theme-code">Clock Source = Internal Clock</span>`<span style="white-space: pre-wrap;"> and </span>`<span class="editor-theme-code">Channel 1 = PWM Generation CH1</span>`<span style="white-space: pre-wrap;">. </span>

<p class="callout warning">**NOTE:**<span style="white-space: pre-wrap;"> Each pwm output for each stepper needs a </span>**separate timer**<span style="white-space: pre-wrap;">. Right now, it is hardcoded that </span>**PWM uses Channel 1**, so only use Channel 1!</p>

The following parameters are important:

- `<span class="editor-theme-code">prescaler</span>`  
    <span style="white-space: pre-wrap;">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! (On the board right now, the clock speeds is set to 72MHz.) This way we work with </span>**1MHz**<span style="white-space: pre-wrap;"> in calculating the frequency and duty cycle.</span>
- `<span class="editor-theme-code">auto-reload preload</span>`  
    I lowkey don't know what this does, just enable it to be safe.

### 2) DMA

<span style="white-space: pre-wrap;">Now, you have to set up the DMA for the same timer/channel. This is in the </span>`<span class="editor-theme-code">DMA settings</span>`<span style="white-space: pre-wrap;"> tab.</span>

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

Set the following parameters:

- `<span class="editor-theme-code">DMA Request = TIMx_CH1</span>`  
    <span style="white-space: pre-wrap;">This is the timer and channel which will be using DMA. </span>**Make sure this is on channel 1, as stated above!**
- `<span class="editor-theme-code">Stream</span>`  
    This can be any of the available streams.
- `<span class="editor-theme-code">Direction = Memory to Peripheral</span>`  
    **Important!**<span style="white-space: pre-wrap;"> Because we will be using DMA to transfer PWM signals from the code (memory) to the pin (peripheral) it needs to be set this way.</span>
- `<span class="editor-theme-code">Priority</span>`  
    <span style="white-space: pre-wrap;">This can be set to any level, but note that it is advisable to put </span>**all steppers to the same priority**. I don't know (and am not responsible for) what happens if they are different.
- `<span class="editor-theme-code">Mode = Normal</span>`  
    <span style="white-space: pre-wrap;">In normal mode, DMA transfers the buffer from memory </span>**ONCE** <span style="white-space: pre-wrap;">and then remains at the last sent value (remember this, it is important later). See </span>[resource 1](https://controllerstech.com/pwm-in-stm32/).
- `<span class="editor-theme-code">Data width = Word</span>`  
    This is the width of the values we will be sending. Since the values we will be sending are used to fill the CCR register, we will set this to word (uint32\_t size). Half word would be for 16 bit registers.

### 3) GPIO pins

<span style="white-space: pre-wrap;">Set 2 pins to GPIO\_Output by clicking on them in the CubeMX UI. One of these will be used for the direction pin and another for the enable pin. </span>

//TODO: add driver resource

### 4) Clock Configuration

For PWM it really doesn't matter at what speed you set the clock. The only thing that matters is that the prescalar is set to the same amount. So if your clock speed is 72, set it to 72-1, if your clock speed is 84, set it to 84-1.

---

## **Code**

### 1) Public Methods

### 2) Private Methods

### 3) Example

## **Resources**

1. [Controllerstech: STM32 PWM Output: Generate PWM Signal with &amp; without DMA](STM32%20PWM%20Output:%20Generate%20PWM%20Signal%20with%20&%20without%20DMA)