STM32F446 - Which timers are used by simpleFOC?


I would like to trigger loopFOC() and move() by Timers. Which ones are used already for the PWM and ADC by simpleFOC? Is there a way to find out which timers are used by default, maybe some general approach? I am not so familiar yet with STM32duino :slight_smile:

I am programing in PlatformIO and its a Nucleo-64 board.

Thanks for any hints.


Assuming 6pwm.

You need to find the complementory timers. For example, TIM1 CH1 / TIM1 CH1N will drive high/low of one of the phases. Read the documentation.

For 3pwm, any three on the same timer will work.


PS For example, PE2 (TIM1_CH1) and PA7 (TIM1_CH1N) would form one such pair on the 64 pin stm32f446re. Page 64 and onwards. All must be on the same timer, so look for TIM1_CHx and TIM1_CHxN and match the channel numbers for the same timer. N means “negative”, or they also call it “complementary”. These types of complementary timers are specifically designed for motor control with centrally aligned PWM timer. This is done to guarantee dead-time between the high and low signals.

For in-depth treatment of the motor control timers, please read Page 29 onwards from the one below.

Thanks for the answer Valentine.

Maybe my questions was not specific enough. I know that the driver class of simplefoc will use some timers, depending on whether its 6PWM or 3PWM. Thats fine. I just want to know which ones are used, so I dont mess those up with my code.

For example: 3PWM uses TIM1, TIM2, TIM3. That means my added functionality shall not use, or reconfigure those timers. I could use for example TIM4 and would not interfere with the PWM generation. So i just need the information which timers I shall not touch :slight_smile:

I tried to read it from the source code in stm32_mcu.cpp of simplefoc. Unfortunately there is no explicit use of TIM. Instead pinmap_peripheral() is used to get a suitable Timer.


That’s incorrect. For 3PWm you must use TIM1_CH1, TIM1_CH2 and TIM1_CH3, or any other TIMn. Using PWM on different timers is incorrect.

Please read the documentation first, it will be of great help.

The code just takes the pins you specify, there are no hard-coded pins there, don’t look for those in the code.

You MUST use the same timer with the attached timer channels for all signals. In other words, your 3 or 6 PWM signals MUST be generated by the SAME timer on three different channels for 3PWM or 6PWM you need 3 channel/complementary matching channel pairs. Channel is not the same as timer. The timer is a physical oscillator. The channel is a wire connecting the oscillator to a pin with some extra logic to it. You could have up to 7 pins attached to an oscillator, with 4 of them main channels and another 3 complementary logic channels. Not all timers have complementary pairs, so you need to read very carefully the pin assignments. Also, not all pins are exposed on different packages, so you need to again read and create a list for what’s available for the package you use.

One more thing, STM32 does channel multiplexing, so you may have the same channel exposed on different pins, and you have the option of selecting which pin to use for a particular channel or channel/complementary channel pair.

okay so that means simplefoc uses TIM1 only? According to the doc one could also use TIM8 as they both have the same features (Advanced-control timers). How could I check in the source code which timers are used by simple foc?

I dont want to generate a PWM signal. I just want to add a new timer triggered function that will do something different and is not related or a replacement to the simplefoc PWM generation. I understand that depending on what I want to do, i have to choose a specific TIM. But before that I wanted to know which TIM I should not use, because it is already used by simplefoc driver.

You can use ANY timer as long as it is the SAME timer for 3PM and as long as it has 3 complementary channels for 6PWM. It is up to you to choose the timers. SimpleFOC does not choose the timers. You specify the channels in the code when you write the code to initialize the motor control.

The MCU you used, stm32f446re, has 17 timers: 2x watchdog, 1x SysTick timer and up to
twelve 16-bit and two 32-bit timers up to 180 MHz, each with up to four IC/OC/PWM or pulse counter.

That’s a lot of timers to choose from.


You specify the channels in the code when you write the code to initialize the motor control.

Could you hint me where this is happening? Looking at one of the provided examples I dont see any Timer specific setup.

Thanks a lot for the help!

BLDCDriver3PWM driver = BLDCDriver3PWM(9, 5, 6, 8);

For STM32F103 this will look like

BLDCDriver6PWM driver = BLDCDriver6PWM(PA8, PA7, PA9, PB0, PA10, PB1);

You may need to also add enable pin if you wish so, at the end, if your driver has enable pin , e.g.

BLDCDriver6PWM driver = BLDCDriver6PWM(PA8, PA7, PA9, PB0, PA10, PB1, PC13);

So the pin selection is entirely up to you. SimpleFOC has no pre-mapped pins. Please read the documentation for your board and select the correct pins, in High/Low matching complementary pairs.

For 3PM the code will look like this:

BLDCDriver3PWM driver = BLDCDriver3PWM(PA7, PA8, PA9, PC13);

PC13 is your enable pin, which could be any I/O pin, not attached to a timer.


okay, that means PIN selection is coupled to TIM selection? Is this process somewhere described? I would like to know more about that.

Yes, please read Page 29 and Page 30.

Then read the pin assignment from pages 44 to 64, find your package, and create pins assignments and put them in the Arduino function call.

What I usually do, I use an Excel spreadsheet, and put the pins and the packages, to help me.

It’s a lot of work but there is no other way.


PS This is an example of one of my spreadsheets mapping STM32F031

I used this to design one of my hardware driver boards:

1 Like

Thanks a lot Valentine for guiding me to the correct docs! I will read the relevant parts for sure. STM32 has a lot of documents and its not easy to navigate around them :smiley:

Good luck with your project. Please, come back and post some pictures and share your story, there will be more people willing to learn from your experience.