In this tutorial, I will share how to generate interrupt every given interval using timer on STM32F4 Discovery board. For example project, we will make orange LED toggle every 500ms interval using TIM2. In the main program we will toggle blue LED every 2500ms (blue LED toggling will not using timer interrupt, but just use delay function).
First, we write code for initialize timer. We will use TIM2. This is the block diagram for configuring the timer clock:
void TIM_INT_Init() { // Enable clock for TIM2 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // TIM2 initialization overflow every 500ms // TIM2 by default has clock of 84MHz // Here, we must set value of prescaler and period, // so update event is 0.5Hz or 500ms // Update Event (Hz) = timer_clock / ((TIM_Prescaler + 1) * // (TIM_Period + 1)) // Update Event (Hz) = 84MHz / ((4199 + 1) * (9999 + 1)) = 2 Hz TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; TIM_TimeBaseInitStruct.TIM_Prescaler = 4199; TIM_TimeBaseInitStruct.TIM_Period = 9999; TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; // TIM2 initialize TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct); // Enable TIM2 interrupt TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); // Start TIM2 TIM_Cmd(TIM2, ENABLE); // Nested vectored interrupt settings // TIM2 interrupt is most important (PreemptionPriority and // SubPriority = 0) NVIC_InitTypeDef NVIC_InitStruct; NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStruct); }
After that, we must write code for interrupt handler that will be call every timer interrupt (500ms). In this handler, we write code for toggle orange LED.
void TIM2_IRQHandler() { // Checks whether the TIM2 interrupt has occurred or not if (TIM_GetITStatus(TIM2, TIM_IT_Update)) { // Toggle orange LED (GPIO13) GPIO_ToggleBits(GPIOD, GPIO_Pin_13); // Clears the TIM2 interrupt pending bit TIM_ClearITPendingBit(TIM2, TIM_IT_Update); } }
Finally, in the main function we can write code for toggle blue LED using delay function. The blue LED will toggle every 2500ms.
#include "stm32f4xx.h" #include "stm32f4xx_rcc.h" #include "stm32f4xx_gpio.h" #include "stm32f4xx_tim.h" #include "misc.h" #include "clock.h" #include "delay.h" int main(void) { // Set clock to 168MHz CLOCK_SetClockTo168MHz(); // Delay initialization DELAY_Init(); // Timer interrupt initialization TIM_INT_Init(); // Clock for GPIOD RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); // GPIOD initialization as an output for orange LED (GPIOD13) // and blue LED (GPIOD15) GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOD, &GPIO_InitStruct); while (1) { // Toggle blue LED (GPIO15) GPIO_ToggleBits(GPIOD, GPIO_Pin_15); // Delay 2.5s DELAY_Ms(2500); } }This is the link for download these clock, delay library if you need.
I am new to stm32, i can't understand this can you explain this in detail.
ReplyDelete// Update Event (Hz) = timer_clock / ((TIM_Prescaler + 1) *
11
// (TIM_Period + 1))
12
// Update Event (Hz) = 84MHz / ((4199 + 1) * (9999 + 1)) = 0.5 Hz
I'm sorry, I think there is a mistake here, it should be 2Hz not 0.5Hz, because the LED is blinking every 500ms (1/2Hz=0.5s=500ms)
DeleteThis formula is used for calculating how fast the interrupt is generated.
Update Event (Hz) = timer_clock / ((TIM_Prescaler + 1) * (TIM_Period + 1)) = 2Hz
For example, 2Hz means that the interrupt will be called every 500ms.
The timer clock is 84MHz, the prescaler is used for slowing the timer clock from 84MHz to 20kHz (84MHz/4200).
With 20kHz the period is 0.05ms, then we set the period value(ARR) to 10000, so 0.05*10000 is 500ms. I have added the illustration in the article.
Thanks erwin for your reply, now i understand the concept.
DeleteCan I generate 5 different pulses by this?
ReplyDeleteIf possible then how? Please reply soon.
how where to add clock.c/.h and delay.c/.h in the atollic program. caan't figure it out
ReplyDeletehow can we add stm32f407vgtx HMC5883L.C and HMC5883L.H Library
ReplyDeletehow to calculate counter period for STM32f429zi discovery board?
ReplyDeleteI am using TIMER 1.
ReplyDeletehow to calculate Count period of stm32f4zi discovery board?