Detailed explanation of TIM timed interrupt in STM32

 A TIM timed interrupt in STM32 (using a general-purpose timer) is one of the most powerful features in real-time embedded systems. It allows the microcontroller to perform specific tasks at precise time intervals, independent of main code execution.




 What Is a TIM Timed Interrupt?

A TIM interrupt is an event triggered by a timer peripheral (e.g., TIM2, TIM3, etc.) when it counts to a specified value. You can configure this to fire periodically, for example, every 1 ms or every 1 second.


 Use Cases

  • Blinking LEDs at a fixed rate

  • Running a real-time scheduler

  • Sampling sensors at fixed intervals

  • Generating PWM signals (with interrupts)


 Key Registers in TIM

RegisterRole
PSCPrescaler (divides timer clock)
ARRAuto-reload register (sets period)
CNTCurrent counter value
DIERInterrupt enable register
SRStatus register (flags)
CR1Control register (start/stop)

 Basic Timing Formula

To generate an interrupt every T seconds:

ini

T = (PSC + 1) × (ARR + 1) / Timer_Clock_Frequency

So:

c

Timer Frequency = 72 MHz (example on STM32F1) Prescaler (PSC) = 7199 → Clock = 10 kHz ARR = 999 → Overflow every 100 ms

 How to Set Up a TIM Timed Interrupt

Here’s how to configure it step-by-step using STM32CubeIDE:


 1. Enable Timer in STM32CubeMX

  • Open your project in STM32CubeMX or STM32CubeIDE

  • Enable TIM2 (or any general-purpose timer)

  • Mode: Internal Clock

  • Enable Update Event Interrupt (UIE)


 2. Set Timer Prescaler and Period

In the configuration panel:

  • Prescaler (PSC): 7199 (if APB1 clock is 72 MHz)

  • Counter Period (ARR): 999

This gives an interrupt every 100 ms.


 3. Generate Code

Click Project > Generate Code. Now move to main.c.


 4. Enable Timer and Interrupt

In main.c:

c

HAL_TIM_Base_Start_IT(&htim2); // Start timer in interrupt mode

 5. Write Interrupt Callback Function

In stm32f1xx_it.c or stm32xx_it.c:

c

void TIM2_IRQHandler(void) { HAL_TIM_IRQHandler(&htim2); // Handle HAL state // Custom code is inside HAL_TIM_PeriodElapsedCallback }

Now implement the callback in main.c:

c

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim->Instance == TIM2) { // Code to execute on each interrupt HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13); // Blink LED } }

 Bare Metal (Register-Level) Example

c

// Enable TIM2 clock RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // Set prescaler and ARR TIM2->PSC = 7199; // Divide 72 MHz → 10 kHz TIM2->ARR = 999; // 10,000 counts → 1 second // Enable update interrupt TIM2->DIER |= TIM_DIER_UIE; // Enable TIM2 counter TIM2->CR1 |= TIM_CR1_CEN; // Enable NVIC interrupt NVIC_EnableIRQ(TIM2_IRQn);

In interrupt handler:

c

void TIM2_IRQHandler(void) { if (TIM2->SR & TIM_SR_UIF) { TIM2->SR &= ~TIM_SR_UIF; // Clear flag // Your code here (e.g., toggle LED) } }

 Debugging Tips

IssueFix
Timer not countingCheck RCC clocks and prescaler
No interruptCheck NVIC settings and UIE bit
Interrupt too fast/slowAdjust PSC and ARR
ISR not executingConfirm function signature and HAL usage

 Summary

StepAction
1Configure timer (PSC, ARR)
2Enable update interrupt
3Start timer in interrupt mode
4Write ISR or callback
5Place time-dependent code inside ISR

评论

此博客中的热门博文

Detailed Explanation of STM32 HAL Library Clock System

How To Connect Stm32 To PC?

How to add a GPS sensor to ESP32 for Wokwi?