on
2021-10-21
01:09 AM
- edited on
2024-06-04
04:56 AM
by
Laurids_PETERSE
It is very common that applications require a periodic interrupt that is used as a time-base for triggering tasks, adding delays, keeping track of elapsed time, etc. While this article shows how to configure an STM32 Timer to generate an interrupt every second, it is easy to change some parameters for other periodic rates.
Micro USB cable used to power the Nucleo board from a host machine and to load the code into the STM32.
In this article we will use a general STM32 timer in order to generate an interrupt every second. We could have used the Systick or the RTC (Real Time Clock), but in this article we will use a simple timer, timer 3 (TIM3), in an STM32G0 Microcontroller. TIM3 is one of many timers embedded in the STM32 Microcontrollers.
TIM3 contains many components as shown in the following block diagram. While the timer supports a number of functions and features, only a subset is needed to generate a periodic one second interrupt. The following components of the timer block are used and configured for this example:
In this part we will review the various calculations necessary to configure TIM3 to generate an interrupt every second.
First of all TIM3 input clock (TIM3CLK) is set to APB1 clock (PCLK1),
APB1 prescaler will be set to 1.
So TIM3CLK = PCLK1
And PCLK1 = HCLK
=> TIM3CLK = HCLK = System Core Clock
In this example we will run the STM32G0 at its maximum speed which is 64 MHz.
So SystemCoreClock is set to 64 MHz.
To get TIM3 counter clock at 10 KHz, the Prescaler is computed as following:
Prescaler = (TIM3CLK / TIM3 counter clock) - 1
Prescaler = (SystemCoreClock /10 KHz) – 1 = (64 MHz / 10 KHz)-1 = 6400 -1 = 6399
The TIM3 ARR (Auto-Reload Register) value which is the Period is equal to 10000 - 1,
Update rate = TIM3 counter clock / (Period + 1) = 1 Hz. This results in an interrupt every 1 second.
When the counter value reaches the auto-reload register value, the TIM update interrupt is generated and, in the handler routine, pin PA5 (connected to LED4 on board NUCLEO-G070RB) is toggled.
Now that we have calculated the necessary configuration values, let’s walk through the steps to generate the code to for the timer to trigger an interrupt every second.
/* USER CODE BEGIN 2 */
if (HAL_TIM_Base_Start_IT(&htim3) != HAL_OK)
{
/* Starting Error */
Error_Handler();
}
/* USER CODE END 2 */
In stm32g0xx_it.c, add the following code in TIM3_IRQHandler (Timer 3 Interrupt Service Request) which will toggle the LED:
/* USER CODE BEGIN TIM3_IRQn 1 */
HAL_GPIO_TogglePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin);
/* USER CODE END TIM3_IRQn 1 */
STM32G0x0 advanced Arm®-based 32-bit MCUs - Reference manual
STM32CubeIDE - Integrated Development Environment for STM32 - STMicroelectronics
Great and clear post. Thank you!
Thanks. I did HAL_TIM_Base_Start() instead of HAL_TIM_Base_Start_IT() until I saw this post.
Excellent post, made getting the timer up and running simple. Thank you.