How to Use STM32 TIM2 Interrupt for 1ms Tasks in FreeRTOS

Introduction

In real-time applications using FreeRTOS on STM32 microcontrollers, precise timing is crucial for tasks like sensor sampling and motor control. This tutorial will guide you through using the TIM2 interrupt to create a precise 1ms periodic task in your FreeRTOS application.

Prerequisites

  • Basic knowledge of C programming
  • Familiarity with STM32 microcontrollers
  • STM32CubeIDE or a similar development environment installed
  • Basic understanding of FreeRTOS concepts

Parts/Tools

  • STM32 development board (e.g., STM32F4 Discovery)
  • USB to UART converter (if not built-in)
  • STM32CubeMX
  • STM32CubeIDE

Steps

  1. Create a new STM32 project:
    1. Open STM32CubeIDE and create a new STM32 project.
    2. Select your microcontroller or board (e.g., STM32F407VG).
  2. Configure TIM2:
    1. Open STM32CubeMX within the IDE.
    2. Select the “Timers” tab and enable TIM2.
    3. Set the Prescaler and Counter Period to achieve a 1ms tick rate.
    4. 
                  // Assuming 84MHz clock
                  TIM2->PSC = 84 - 1; // Prescaler
                  TIM2->ARR = 1000 - 1; // 1ms period
                  
    5. Enable the TIM2 interrupt in the NVIC settings.
  3. Generate the code:
    1. Click on “Project” and then “Generate Code”.
    2. Open the project in STM32CubeIDE.
  4. Implement the TIM2 interrupt handler:
    1. Open stm32f4xx_it.c and locate the TIM2 interrupt handler.
    2. Add the following code to handle the TIM2 interrupt:
    3. 
                  void TIM2_IRQHandler(void) {
                      if (TIM2->SR & TIM_SR_UIF) { // Check update interrupt flag
                          TIM2->SR &= ~TIM_SR_UIF; // Clear the flag
                          BaseType_t xHigherPriorityTaskWoken = pdFALSE;
                          // Signal the periodic task
                          xTaskNotifyFromISR(xTaskHandle, 0, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
                          portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
                      }
                  }
                  
  5. Create a periodic task:
    1. Define your task function in your main file:
    2. 
                  void vTaskPeriodic(void *pvParameters) {
                      for (;;) {
                          ulTaskNotifyTake(pdTRUE, portMAX_DELAY); // Wait for notification
                          // Execute periodic task code here
                      }
                  }
                  
    3. Create the task in the main function:
    4. 
                  xTaskCreate(vTaskPeriodic, "PeriodicTask", configMINIMAL_STACK_SIZE, NULL, 1, &xTaskHandle);
                  
  6. Start the scheduler:
    1. Add vTaskStartScheduler(); to the main function to start FreeRTOS.

Troubleshooting

  • Interrupt not firing: Check if TIM2 is correctly configured with the right prescaler and counter values.
  • Task not executing: Ensure the task is created successfully and the scheduler is started.
  • High CPU usage: Verify that the periodic task completes quickly and does not block.
  • Incorrect timing: Use an oscilloscope or logic analyzer to verify timing accuracy.

Conclusion

By following this tutorial, you have successfully configured TIM2 on an STM32 microcontroller to generate precise 1ms periodic tasks in a FreeRTOS application. This setup is essential for applications requiring accurate timing and responsiveness.

Leave a Comment

Your email address will not be published. Required fields are marked *