STM32 Timer Interrupt HAL Example – Timer Mode LAB

Previous Tutorial Previous Tutorial Tutorial 13 Next Tutorial Next Tutorial
STM32 Timers – Timer Mode LAB
STM32 Course Home Page 🏠

 

STM32 Timers Explained Tutorial - Timer interrupt HAL Example

 

In this LAB, we’ll discuss how to configure the STM32 timer module to operate in the timer mode. And use it to generate a periodic interrupt signal to toggle an LED. You’ll go through step-by-step HAL example configurations to initialize all the required hardware peripherals. Then, we’ll write simple application code to test the hardware functionalities. And also we’ll see how to calculate the timer preload value to get the desired output time interval exactly. without further ado, let’s get started!


   Required Components For LABs   

 

All the example code/LABs/projects in the course are going to be done using those boards below.

QTY Component Name 🛒 Amazon.com 🛒 eBay.com
2 BreadBoard Amazon eBay
1 LEDs Kit Amazon Amazon eBay
1 Resistors Kit Amazon Amazon eBay
1 Capacitors Kit Amazon Amazon eBay & eBay
2 Jumper Wires Pack Amazon Amazon eBay & eBay
1 9v Battery or DC Power Supply Amazon Amazon Amazon eBay
1 Micro USB Cable Amazon eBay
1 Push Buttons Amazon Amazon eBay

★ Check The Full Course Complete Kit List

Some Extremely Useful Test Equipment For Troubleshooting:

Affiliate Disclosure: When you click on links in this section and make a purchase, this can result in this site earning a commission. Affiliate programs and affiliations include, but are not limited to, the eBay Partner Network (EPN) and Amazon.com.


   STM32 Timer Mode LAB Preface   

 

In this LAB, we’ll set up a general-purpose timer module to operate in timer mode. We’ll set the overflow time interval to the desired value using the equation down below. And toggle an LED in the interrupt service routine (ISR) for the timer overflow event.

STM32 Timer HAL Interrupt Formula - Timer Equation

STM32 Timer HAL Interrupt Formula - STM32 Timer Equation

As you can see, the output time interval is determined by the Prescaler value, the clock frequency, and the timer preload register’s value. Given that the blue pill board can run @ up to 72MHz, and let’s set the frequency to 72Mz. Now, we can choose a value for the Prescaler then put in the desired TOUT and solve for the Preload register value.

In LAB7, we’ll set our desired output time interval to be 100mSec. We’ll toggle the LED once each 100mSec and we’d like to set up the timer interrupt to give us this time interval. So, from the above equation, we can assume the FCLK to be 72MHz. And let the Prescaler be 1000. Now, the only unknown is the Preload value. By solving for it, we’ll get 7200.

 


   LAB Objectives   

 

LAB Number 7
LAB Title Timer Mode Periodic Event
  • Configure the general-purpose timer (TIM2) to operate in timer mode
  • Set The Prescaler, and the Preload value so that the output Time interval is 100mSec
  • Toggle an output pin (LED) each 100mSec in the timer overflow ISR
  • Measure and verify the output signal’s timing

 


   STM32 Timer – Timer Mode LAB Config.   

 

Step1: Open CubeMX & Create New Project

STM32 CubeMX Create New Project

Step2: Choose The Target MCU & Double-Click Its Name

STM32 CubeMX Choose The Part Step

Step3: Click On The Pin You Want To Configure As An Output & Select Output Option

Let it be B13 pin for example! (The LED Pin)

Step4: Configure Timer2 Peripheral

As we’ve calculated earlier, the Prescaler will be 1000, and the Preload value will be 7200. And the timer module will be clocked at the internal clock frequency.

STM32 Timer HAL Interrupt Example Tutorial CubeMX

Step5: Enable The Timer Interrupt Signal In NVIC Tab

STM32 Timer HAL Interrupt Example Tutorial - STM32 Timer Explained

Step6: Set The RCC External Clock Source

STM32 RCC External Clock Selection CubeMX

Step7: Go To The Clock Configuration

Step8: Set The System Clock To Be 72MHz Or Whatever You Want

STM32 Clock Tree Configuration CubeMX

Step9: Name & Generate The Project Initialization Code For CubeIDE or The IDE You’re Using

 

Then, open the project in the IDE you’re using. And head over to the main.c file. So we can start writing the application code and have a look at the initialization code generated by the STM32 CubeMX tool.

 


   The Application Code In CubeIDE   

 

Here is the generated initialization code in the main.c file

#include "main.h"

TIM_HandleTypeDef htim2;

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM2_Init(void);

int main(void)
{

  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_TIM2_Init();

  while (1)
  {

  }

}

Now, the application we’re currently developing is a LED toggle in the ISR for the timer module. So, open the stm32f1xx_it.c file to find the timer interrupt handler, which is this function TIM2_IRQHandler(). Hover over the HAL_TIM_IRQHandler() function and right-click to navigate to its implementation.

void TIM2_IRQHandler(void)
{

  HAL_TIM_IRQHandler(&htim2);

}

After navigating to the timer interrupt handler routine, you’ll find the following implementation. In this code, we’re searching for the callback function’s name that gets called when an overflow interrupt occurs. You can notice that all sources share the same interrupt signal output compare match, overflow, input capture, etc.

void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim)
{
  // Other timer interrupts events..
  //..
  //..
  //..
  /* TIM Update event */
  if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_UPDATE) != RESET)
  {
    if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_UPDATE) != RESET)
    {
      __HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE);
      #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
        htim->PeriodElapsedCallback(htim);
      #else
        HAL_TIM_PeriodElapsedCallback(htim);
      #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
    }
  }
  //..
  //..
  // Other timer interrupts events..
}

Now, we’ve got the callback function’s name that gets called whenever timer overflow occurs. It’s HAL_TIM_PeriodElapsedCallback(). So, we’ll write our own implementation for it in the application file (main.c). And a mention-worthy point is that you also have to enable (start) the timer so it gets clocked and starts counting, otherwise it’ll remain IDLE.

Full LAB Code (main.c)

#include "main.h"

TIM_HandleTypeDef htim2;

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM2_Init(void);

int main(void)
{

  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_TIM2_Init();
  HAL_TIM_Base_Start_IT(&htim2);

  while (1)
  {

  }

}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim)
{
    HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_13);
}

Build & Flash The Code And Let’s Test The Results!

 


   Prototyping & Testing   

 

Step0: Refer To The Blue Pill Board Schematic & Pinout

Step1: Connect The ST-Link To The USB Port & SWD Pins On Board

STM32 GPIO HAL Led Blinking

Step2: Click The Debug Button To Compile The Code & Flash It To The Board & Start A Debugging Session

Step3: You Can Stop The Debugging Session Or Keep It Going. But You Need To Restart The MCU Once To Run The New Application At The Booting Process.

Download TimerMode LAB7 Project

The Results For This LAB

Test Video

 

Output Signal On My DSO

It’s a perfect 100msec time interval !

STM32 Timer HAL Interrupt Example


   Other Fine-Timing Experiments   

 

LAB Number 8
LAB Title Timer Mode Periodic Event (in microseconds)

 

I’ve also done a couple of other experiments in which fine output time intervals are desired. First of which was to produce a periodic timer interrupt every 50μSec. Hence the FCLK is 72MHz, and the Prescaler is left as 0 which means 1:1, therefore the preload value is found to be 3600 using the timer formula.

STM32 Timer HAL Interrupt Formula - STM32 Timer Equation

Consequently, I did change these values in code, rebuild & flash it. And the result was a clean 50μSec waveform! As you can see in the screenshot down below

STM32 Timer HAL Interrupt Example Code

Obviously, by changing the Preload value from 3600 to 360, the output time interval should now be 5μSec. So, I did that and rebuild & flashed the code. And the result was as expected a clean 5μSec time interval as you can see in the screenshot down below.

STM32 Timer HAL Interrupt Example Tutorial

However, I do believe that there is a fundamental limitation for the timing resolution that can possibly be enhanced by reducing the usage of HAL library functions and calling multiple functions in the process of handling various tasks.

 

 

Stay tuned for the upcoming tutorials and don’t forget to SHARE these tutorials. And consider SUPPORTING this work to keep publishing free content just like this!

 

Previous Tutorial Previous Tutorial Tutorial 13 Next Tutorial Next Tutorial

 

Share This Page With Your Network!

Khaled Magdy

I'm an embedded systems engineer doing both Software & Hardware. I'm an EE guy who studied Computer Engineering, But I'm also passionate about Computer Science. I love reading, writing, creating projects and Technical training. A reader by day a writer by night, it's my lifestyle. You can view my profile or follow me via contacts.

You may also like...

%d bloggers like this: