Measure input Frequency using STM32

ARM, Embedded, STM32


In this tutorial today, I will show you guys How to measure input frequency using STM32. I know there are methods like input capture and compare etc.. but the method I am using is possibly the simplest and easiest to understand and can measure a very high range of frequencies.


The process is pretty straight forward. We will set the data pin as input and count the number of times it goes high and low in 1 second and that will be the input frequency. I am using NE555 to generate different frequencies and DSO138 to compare the results to. 

The main problem is setting a 1 second interval for the measurement. For this purpose I will use TIMERx (x is your choice) and set the counter (CNT) as 0 and wait for it to reach max value(stored in ARR), which it will do in 1 second and within that time we will count the number of pulses.


Okay this is the crucial part, so follow the steps below:-

1.) Check that maximum frequency, your TIMx can operate on. For eg I am using TIM2 of STM32F446RE and according to the datasheet, it is connected to the APB1 bus.

2.) Select the TIMx and choose clock source as internal clock.

3.) While setting up the clock, look at the APBx TIM clock. Also make sure this value is below 65000 to make the calculations more simpler.

4.) Now my TIM2 is running at 45 MHz. So I will set my prescalar value at 45000 and I will get a frequency of 1 KHz (1 ms time period) from this setup. Also set the value of ARR to maximum possible value. As my ARR is 32 bit so I will set it to 0xffffffff.

This setup will ensure that the Timer will count from 0 to 0xffffffff in 1 ms and it will increment the count by 1 in the CNT register.

Insight into the CODE

void read_freq (void)
	htim2.Instance->CNT = 0;  // set the count to 0

	while ((htim2.Instance->CNT) < 1000)  // while the count is less than 1000 ms
		while (!(HAL_GPIO_ReadPin (GPIOA, GPIO_PIN_1)));  // wait for the pin to go high

		while ((HAL_GPIO_ReadPin (GPIOA, GPIO_PIN_1)));  // wait for the pin to go low

		increment++;  // increment the variable

	freq = increment;  // freq = number of times pin goes high and low in  second

	increment = 0;  






You can buy me a coffee sensor 🙂

download the CODE below

, , , , ,

Leave a Reply

5 Comment threads
2 Thread replies
Most reacted comment
Hottest comment thread
6 Comment authors
AlexGeorge PapageorgeJose Javiervarun vadmin Recent comment authors
newest oldest most voted
Notify of

I was wondering since,the oscilloscope that you are using is also based upon stm32. Could you please make a tutorial on displaying custom static images( like the background grid on the oscilloscope).The source code of this oscilloscope is already available on GitHub. It would immensely help students as there are not many tutorials on graphics for arm processors.

varun v
varun v

hi can u show the 555 timer ckt setup and conection to the board. i’m using the stm32 f407 discovery and trying to calculate rpm: which is nothing but the frequency of the input pulses. Could you shed some light on this?

Jose Javier
Jose Javier

If i want in us, it’s possible?

George Papageorge
George Papageorge

Code gets stuck as soon it goes into “void read_freq (void)”. Any ideas as to what could be wrong?
I am feeding to the input a pwm signal from the same microcontroller.


I have copied the code from your download link, but it tells me there are lots of unresolved symbols such as GPIOA, CNT, RCC_PLLSOURCE_HSE, etc