Library 48- Measure PWM input signal with STM32F4

First library in 2015 is here. With it, you will be able to measure PWM input signal from “other world”. STM32F4’s timers have capability to make an interrupt on edge, when signal is active on input pin for specific timer. This allows us, to measure signal in input. With a simple calculations, we can detect frequency of signal and duty cycle.

Of course, this is not veery accurate, but with 168MHz F407 device, using 32bit TIM2 (high resolution) I got pretty good results. Input PWM was set to random value 2545Hz with 23% duty cycle. Results from TIM2 were:

  • Frequency: 2545.13Hz
  • Duty cycle: 22.97%

Result’s quality depends on frequency you measure and also on timer’s performance (prescaler, max period value).

In library below, everything you have to set are:

  • Timer you will use for measuring signals
  • Timer’s IRQ for NVIC interrupt request
  • Create timer’s IRQ for interrupt handler
  • Call defined function in this handler
  • Call function to get results
  • More in example..



  • Measure PWM input signal on all available timers with input pin possibility
  • Measure frequency and duty cycle


    • STM32F4xx
    • STM32F4xx RCC
    • STM32F4xx GPIO
    • STM32F4xx TIM
  • TM
    • defines.h

Table below shows all possible pins for each timer and channel. You can select any of max 3 pins for each input channel.

Timer Channel 1 Channel 2
TIM 1 PA8 PE9 PA9 PE10
TIM 2 PA0 PA5 PA15 PA1 PB3
TIM 4 PB6 PD12 PB7 PD13
TIM 5 PA0 PH10 PA1 PH11
TIM 10 PB8 PF6
TIM 11 PB9 PF7
TIM 12 PB14 PH6 PB15 PH9
TIM 13 PA6 PF8
TIM 14 PA7 PF9
  • PPx: Pins Pack 1 to 3, for 3 possible channel outputs on timer.

Notes on table above

  • Not all timers are available on all STM32F4xx devices
  • Not all timers works with same tick frequency
  • All timers have 16bit prescaler
  • TIM6 and TIM7 don’t have PWM feature, they are only basic timers
  • TIM2 and TIM5 are 32bit timers
  • TIM10, TIM11, TIM13 and TIM14 have only one PWM channel
  • Only 1 channel can be selected on 1 timer

Other notes

  • If you don’t know which frequency you can expect on your input, then set initialization function to 1, which means that you want to measure minimal frequency of 1Hz. If you want to go even lower, you can basically go to a value of
    • This can be very low value, but if you have then signal in 10kHz spectrum, your result can veery very fail from real. I suggest you that you set this value to 1 if you don’t know what you can expect, if you know, then set it to a little bit smaller value.
      • Example: if you expect signal of 1000Hz, then set value to 950 in initialization function or something like that
  • I suggest you to use 32-bit timer (TIM2, TIM5) to measure input PWM, you got better result and better accuracy
  • Expected frequency is just some kind of reference, how to set timer with prescaler, so you will be able to measure entire PWM period with one timer’s period value for valid result!

Default NVIC priority for all timers is set to 0x01. If you need to set another value, then use define in defines.h file:

Sub priority for timers is generated in a way that which timer you initialize first, this timer has higher sub priority.

Functions and enumerations


  • Example and results are based on STM32F4-Discovery board.
  • TIM4 makes PWM on pin PD12 with 3251Hz.
  • TIM2 and TIM3 are measuring timers
    • TIM2 is 32-bit, TIM3 is 16-bit.
  • Results in pictures below
    • First has capture timers set to 1000Hz expected frequency, second with 1Hz
      • TIM3 starts failing with result
TIM2 and TIM3 measuring results with 1Hz input frequency expection

TIM2 and TIM3 measured results with 1Hz input frequency expection

TIM2 and TIM3 measuring results with 1000Hz input frequency expection

TIM2 and TIM3 measured results with 1000Hz input frequency expection

Project available at my Github account, download library below.


Owner of this site. Application engineer, currently employed by STMicroelectronics. Exploring latest technologies and owner of different libraries posted on Github.

You may also like...

Read before commenting!

Before you make a new comment, make sure you agree with things listed below:

  • - Read post to make sure if it is already posted what you are asking for,
  • - Make sure you have the latest version of libraries used in your project,
  • - Make a clean and grammatically correct written message,
  • - Report as many details as possible, including what have you done so far,
  • - Do NOT post any code here. Use Pastebin,
  • - Do NOT post any error codes here. Use Pastebin,
  • - Specify STM32Fxxx family and used Discovery/EVAL/Nucleo or custom made board,
  • - Make sure your clock is set correct for PLL,
  • - If you are using my HAL drivers, please check this post how to start.
Comment will be deleted on breaking these rules without notification!