I want to measure the RPM of a motor that I am controlling using a STM32 and some driver chip.. My understanding is that I have to measure the time between 2 hall signal and calculate the speed (RPM).

The question is, how can I start a timer and restart it on each hall signal interrupt. I tried to study the timers but the amount of things to learn are huge...

I mean for my case, what mode should I run a timer? I think there are input direct capture, output captures, etc...

Here is my interrupt code:

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
    if(GPIO_Pin == GPIO_PIN_4 || GPIO_Pin == GPIO_PIN_5 || GPIO_Pin == GPIO_PIN_6) {
  • 1
    \$\begingroup\$ I think you should go back to studying the timers. I have no experience with the STM chips but with numerous others. Every decent micro controller has a pulse-width measurement mode. \$\endgroup\$
    – Oldfart
    Commented Jan 18, 2018 at 19:23
  • \$\begingroup\$ Read a bit about encoder mode of the STM32 timers, and generally about quadrature encoders. \$\endgroup\$ Commented Jan 18, 2018 at 21:53

1 Answer 1


The short answer is: you need to use the Timer in input capture mode!

Then Timer_Pin can be configured for external interrupt trigger i.e when an external interrupt occurs then an input time capture(~time stamp) occurs. Similarly, another capture occurs at the next interrupt, you just need to find the difference between the two captures to calculate the time elapsed between two events. But care has to be taken in configuring the Timer so that it can capture at least two consecutive interrupts!

To explain things further, I am assuming that you are using STM32CubeMx to generate the code, even if you are not the similar steps can be followed!

  1. You need to configure a Timer in "Input Capture Direct mode", that assigns a GPIO pin to it. Now, you can use this for your sensor interrupt!

  2. Configure the timer such that it should be able to capture a minimum of two consecutive TIM captures.

The calculation is simple and goes as follows-

The minimum frequency that you measure is

MinPulseFrequency = (2*TIMxPeripheralFrequency)/((Period+1)(Prescaler+1)) 
  1. Go through STM32Cube Examples and look for TIM/Timer_Input_Capture example. It has been explained fairly good.

  2. Even if you don't want to go through complete details on how all Timer modes work, make sure that you understand what is happening in input capture mode! and see how it can be configured properly using this General Purpose Timer Cookbook.

For similar problem in a different context but which works as an example code for you will be this post.


Not the answer you're looking for? Browse other questions tagged or ask your own question.