0
0
Cnc-programmingHow-ToBeginner · 4 min read

How to Configure Timer on STM32: Step-by-Step Guide

To configure a timer on STM32, you first enable the timer clock, set the timer's prescaler and auto-reload values to control timing, and then start the timer by enabling it. This setup is done by writing to the timer's registers or using STM32 HAL library functions like HAL_TIM_Base_Init() and HAL_TIM_Base_Start().
📐

Syntax

Configuring a timer on STM32 involves these main steps:

  • Enable Timer Clock: Turn on the clock for the timer peripheral.
  • Set Prescaler: Divides the timer clock to slow down the timer count.
  • Set Auto-Reload Register (ARR): Defines the timer period before it resets.
  • Enable Timer: Start the timer counting.

Using STM32 HAL library, the key functions are:

  • HAL_TIM_Base_Init(): Initializes timer with settings.
  • HAL_TIM_Base_Start(): Starts the timer counting.
c
TIM_HandleTypeDef htim2;

__HAL_RCC_TIM2_CLK_ENABLE(); // Enable timer 2 clock
htim2.Instance = TIM2; // Select timer 2
htim2.Init.Prescaler = 7999; // Divide clock by 8000
htim2.Init.CounterMode = TIM_COUNTERMODE_UP; // Count up
htim2.Init.Period = 9999; // Count up to 10000
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; // No clock division

HAL_TIM_Base_Init(&htim2); // Initialize timer
HAL_TIM_Base_Start(&htim2); // Start timer
💻

Example

This example configures TIM2 to generate an update event every 1 second assuming the system clock is 8 MHz. It sets the prescaler and period to achieve this timing and starts the timer.

c
#include "stm32f1xx_hal.h"

TIM_HandleTypeDef htim2;

void SystemClock_Config(void);
void MX_TIM2_Init(void);

int main(void) {
  HAL_Init();
  SystemClock_Config();
  MX_TIM2_Init();

  HAL_TIM_Base_Start(&htim2); // Start timer

  while (1) {
    if (__HAL_TIM_GET_FLAG(&htim2, TIM_FLAG_UPDATE)) {
      __HAL_TIM_CLEAR_FLAG(&htim2, TIM_FLAG_UPDATE);
      // Timer event every 1 second
      // Place your code here
    }
  }
}

void MX_TIM2_Init(void) {
  __HAL_RCC_TIM2_CLK_ENABLE();

  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 7999; // 8 MHz / 8000 = 1 kHz
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 999; // 1 kHz / 1000 = 1 Hz (1 second)
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  HAL_TIM_Base_Init(&htim2);
}

void SystemClock_Config(void) {
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  HAL_RCC_OscConfig(&RCC_OscInitStruct);

  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
}
Output
Timer TIM2 generates an update event every 1 second triggering the update flag.
⚠️

Common Pitfalls

Common mistakes when configuring STM32 timers include:

  • Not enabling the timer clock before configuration, causing the timer not to work.
  • Incorrect prescaler or period values leading to wrong timing intervals.
  • Forgetting to start the timer after initialization.
  • Not clearing the update interrupt flag, causing repeated triggers.

Always check the clock frequency and calculate prescaler and period accordingly.

c
/* Wrong: Missing clock enable */
// HAL_TIM_Base_Init(&htim2); // Timer not clocked, won't work

/* Correct: Enable clock before init */
__HAL_RCC_TIM2_CLK_ENABLE();
HAL_TIM_Base_Init(&htim2);
HAL_TIM_Base_Start(&htim2);
📊

Quick Reference

Summary tips for STM32 timer configuration:

  • Enable timer peripheral clock first.
  • Calculate prescaler and period based on timer clock and desired time.
  • Initialize timer with HAL_TIM_Base_Init().
  • Start timer with HAL_TIM_Base_Start().
  • Use update interrupt flag to detect timer events.

Key Takeaways

Always enable the timer clock before configuring the timer registers.
Set prescaler and auto-reload values to control the timer frequency precisely.
Use HAL library functions like HAL_TIM_Base_Init and HAL_TIM_Base_Start for easier setup.
Remember to start the timer after initialization to begin counting.
Clear update flags to avoid repeated interrupts or events.