STM32 Guide: Timers


This is tutorial is not intended to be a guide for learning C language or about the STM32 platform. It’s primary target is to provide developers a concise guide about integrating peripheral modules and features into active applications.

If you are a beginner, I would recommend you look into an STM32 Project Setup guide like this one.

What is a Timer on a Microcontroller?

A Timer can be said to be a specialized clock, which is used to measure intervals on a microcontroller. In a microcontroller, a timer can be used to tune the processing speed of an operation, set delays and also to synchronize user input and communication between a variety of peripheral devices.

As a result, timers form a very integral component of a microcontroller operations and having the skill to control the timer and its operations become an essential skill for any Embedded Systems developer.

STM32 GPIO and HAL Library


Hardware Abstraction Library(HAL) is a part of developer libraries provided by STMicroelectronics for ease of development. The abstraction library is a set of functions and definitions which make it possible for developers to focus on getting their codes running instead of being bogged down with setting all the plethora of registers and bits to get a simple I/O operation possible. Using the functions in the HAL library, developers can simply call a single function to perform operations like read I/O data, or even perform complex processes like SPI or I2C.


Most STM32 microcontroller have a 16-bit auto reload counter and a 16-bit prescaler. The prescaler is used to modify the incoming signal/clock frequency from the external oscillator and convert it to the frequency that the user requires.

Thus, a user can obtain a processing frequency of 64-MHz even if the crystal on the circuit is 8-MHz. Consequently, prescaler can also step down the frequency from the source clock.

They also act as counters in the microcontrollers and can be used to keep track of operations. A 16-bit timer can count up to 255. Once this is reached, it rolls-over and starts from 0 again.

Timer on STM32F4

Since I have an 32F4 Discovery devkit, I am going to refer to its datasheet to learn more about the available timer options.

According to the datasheet above, the STM32F4 module has 12 16-bit timers and 2 32-bit timers, each of which can clock up to a frequency of 168-MHz.


  1. Initialize the TIM low level resources by implementing the following functions depending from feature used :
     Time Base : HAL_TIM_Base_MspInit()
     Input Capture : HAL_TIM_IC_MspInit()
     Output Compare : HAL_TIM_OC_MspInit()
     PWM generation : HAL_TIM_PWM_MspInit()
     One-pulse mode output : HAL_TIM_OnePulse_MspInit()
     Encoder mode output : HAL_TIM_Encoder_MspInit()

2. Initialize the TIM low level resources :
a. Enable the TIM interface clock using __TIMx_CLK_ENABLE();
b. TIM pins configuration: Enable the clock for the TIM GPIOs using the following function: __GPIOx_CLK_ENABLE();
Configure these TIM pins in Alternate function mode using HAL_GPIO_Init();

3. The external Clock can be configured, if needed (the default clock is the internal clock from the APBx), using the following function: HAL_TIM_ConfigClockSource, the clock configuration should be done before any start function.

4. Configure the TIM in the desired functioning mode using one of the initialization function of this driver:
 HAL_TIM_Base_Init: to use the Timer to generate a simple time base
 HAL_TIM_OC_Init and HAL_TIM_OC_ConfigChannel: to use the Timer to
generate an Output Compare signal.
 HAL_TIM_PWM_Init and HAL_TIM_PWM_ConfigChannel: to use the Timer to generate a PWM signal.
 HAL_TIM_IC_Init and HAL_TIM_IC_ConfigChannel: to use the Timer to measure an external signal.
 HAL_TIM_OnePulse_Init and HAL_TIM_OnePulse_ConfigChannel: to use the Timer in One Pulse Mode.
 HAL_TIM_Encoder_Init: to use the Timer Encoder Interface.

5. Activate the TIM peripheral using one of the start functions depending from the feature used:
 Time Base : HAL_TIM_Base_Start(), HAL_TIM_Base_Start_DMA(),
 Input Capture : HAL_TIM_IC_Start(), HAL_TIM_IC_Start_DMA(),
 Output Compare : HAL_TIM_OC_Start(), HAL_TIM_OC_Start_DMA(),
HAL TIM Generic Driver UM1725
874/1838 DocID025834 Rev 5
 PWM generation : HAL_TIM_PWM_Start(), HAL_TIM_PWM_Start_DMA(),
 One-pulse mode output : HAL_TIM_OnePulse_Start(),
 Encoder mode output : HAL_TIM_Encoder_Start(),
HAL_TIM_Encoder_Start_DMA(), HAL_TIM_Encoder_Start_IT().

6. The DMA Burst is managed with the two following functions:
HAL_TIM_DMABurst_WriteStart() HAL_TIM_DMABurst_ReadStart()


In this tutorial, we discussed the methods for using Timers in our hardware setup. The same code will work of any Timer Configuration or Operation.