____________________________________________________________________________________________________
In last tutorial ,study how to use GPIO pins to blink led present on the Stm32f4 Discovery Board. In this tutorial ,study how to use time as a interrupt to blink led on Stm32f4 Discovery Board.
Stm32f4 controller built with several type of Timer with following features:-
- General-purpose timers are used in any application for output compare (timing and delay generation) e.g delay in led blink,sensor interfacing, encoder data reading.
- Advanced timers: In addition to general purpose functions, they include several features related to motor control and digital power conversion applications.
- Low-power timers are simpler than general purpose timers and their advantage is the ability to continue working in low-power modes and generate a wake-up event.
- High-resolution timers are specialized timer peripherals designed to drive power
conversion in lighting and power source applications. - Basic timers have no input/outputs and are used either as time base timers or for triggering the DAC peripheral.
Timer Features of Stm32f4 controller
To blink the led using timer on stm32f4 discovery board first initialize Led pins present on the discovery board.
GPIO_InitTypeDef GPIO_InitStructure; LED_NAME led_name; for(led_name=0;led_name<TOTAL_LED;led_name++) { // Clock Enable RCC_AHB1PeriphClockCmd(LED[led_name].LED_CLK, ENABLE); // Config as digital output GPIO_InitStructure.GPIO_Pin = LED[led_name].LED_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(LED[led_name].LED_PORT, &GPIO_InitStructure);
After that we initialize the timer 2:-
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; // Clock enable RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // Timer disable TIM_Cmd(TIM2, DISABLE); // Timer init TIM_TimeBaseStructure.TIM_Period = periode; TIM_TimeBaseStructure.TIM_Prescaler = prescaler; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); // Timer preload enable TIM_ARRPreloadConfig(TIM2, ENABLE);
After initializing timer 2 ,configure timer 2 as an interrupt:-
NVIC_InitTypeDef NVIC_InitStructure; // Update Interrupt enable TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE); // NVIC NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);
After that put the code which you want to do after an interval (here we put led blink function in ISR of timer 2).
void FM_TIMER2_ISR_CallBack() { FM_Led_Toggle(LED_GREEN); FM_Led_Toggle(LED_ORANGE); FM_Led_Toggle(LED_RED); FM_Led_Toggle(LED_BLUE); }
A sample example of Stm32F4 Discovery board Led blink using Timer Interrupt as follows
/*************************************************************** * File : main.c * website : www.firmcodes.com * email_id : support@firmcodes.com * IDE used : The files are Compiled in coocox ide and tested on stm32f4 discovery board. ***************************************************************/ /*************************************************************** // Header Files Includes ***************************************************************/ #include "stm32f4xx.h" #include "fm_stm32f4_led.h" #include "fm_stm32f4_tim2.h" int main(void) { SystemInit(); FM_Led_Init(); FM_TIMER2_Init(10000,540); FM_TIMER2_Start(); while(1) { } }
Dependency to compile the program as follows:-
- stm32f4xx.h
- stm32f4xx_gpio.h
- stm32f4xx_rcc.h
- fm_stm32f4_led.h
- fm_stm32f4_tim2.h
Timer 2 library
- fm_stm32f4_led.h function
/*************************************************************** * File : fm_stm32f4_led.h * website : www.firmcodes.com * email_id : support@firmcodes.com * IDE used : The files are Compiled in coocox ide and tested on stm32f4 discovery board. ***************************************************************/ #ifndef __FM_STM32F4_LED_H #define __FM_STM32F4_LED_H /*************************************************************** // Header Files Includes ***************************************************************/ #include "stm32f4xx.h" #include "stm32f4xx_gpio.h" #include "stm32f4xx_rcc.h" /*************************************************************** * List of All LED ***************************************************************/ typedef enum { LED_GREEN = 0, // Green Led on STM32F4-Discovery LED_ORANGE = 1, // Orange Led on STM32F4-Discovery LED_RED = 2, // Red Led on STM32F4-Discovery LED_BLUE = 3 // Blue Led on STM32F4-Discovery }LED_NAME; #define TOTAL_LED 4 // Anzahl von LED_NAME_t /*************************************************************** * Status einer LED ***************************************************************/ typedef enum { LED_OFF = 0, // LED AUS LED_ON // LED EIN }LED_STATUS; /*************************************************************** * Strcture of LED ***************************************************************/ typedef struct { LED_NAME LED_NAME; // Name GPIO_TypeDef* LED_PORT; // Port const uint16_t LED_PIN; // Pin const uint32_t LED_CLK; // Clock LED_STATUS LED_INIT; // status }LED_struct; /*************************************************************** * Gloable Function ***************************************************************/ void FM_Led_Init(void); void FM_Led_Off(LED_NAME led_name); void FM_Led_On(LED_NAME led_name); void FM_Led_Toggle(LED_NAME led_name); /***************************************************************/ #endif // __FM_STM32F4_LED_H
2. fm_stm32f4_led.c function
/*************************************************************** * File : fm_stm32f4_led.c * website : www.firmcodes.com * email_id : support@firmcodes.com * IDE used : The files are Compiled in coocox ide and tested on stm32f4 discovery board. ***************************************************************/ #include "fm_stm32f4_led.h" /*************************************************************** * All LED on Stm32f4 discovery board ***************************************************************/ LED_struct LED[] = { // Name ,PORT , PIN , CLOCK , Init {LED_GREEN ,GPIOD,GPIO_Pin_12,RCC_AHB1Periph_GPIOD,LED_OFF}, // PD12=Green LED on Discovery-Board {LED_ORANGE,GPIOD,GPIO_Pin_13,RCC_AHB1Periph_GPIOD,LED_OFF}, // PD13=Orange LED on Discovery-Board {LED_RED ,GPIOD,GPIO_Pin_14,RCC_AHB1Periph_GPIOD,LED_OFF}, // PD14=Red LED on Discovery-Board {LED_BLUE ,GPIOD,GPIO_Pin_15,RCC_AHB1Periph_GPIOD,LED_OFF}, // PD15=Blue LED on Discovery-Board }; /*************************************************************** * Initialize all LED ***************************************************************/ void FM_Led_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; LED_NAME led_name; for(led_name=0;led_name<TOTAL_LED;led_name++) { // Clock Enable RCC_AHB1PeriphClockCmd(LED[led_name].LED_CLK, ENABLE); // Config as digital output GPIO_InitStructure.GPIO_Pin = LED[led_name].LED_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(LED[led_name].LED_PORT, &GPIO_InitStructure); } } /*************************************************************** * LED off ***************************************************************/ void FM_Led_Off(LED_NAME led_name) { LED[led_name].LED_PORT->BSRRH = LED[led_name].LED_PIN; } /*************************************************************** * LED on ***************************************************************/ void FM_Led_On(LED_NAME led_name) { LED[led_name].LED_PORT->BSRRL = LED[led_name].LED_PIN; } /*************************************************************** * LED toggle ***************************************************************/ void FM_Led_Toggle(LED_NAME led_name) { LED[led_name].LED_PORT->ODR ^= LED[led_name].LED_PIN; }
3. fm_stm32f4_tim2.c function
/*************************************************************** * INCLUDE ***************************************************************/ #include "fm_stm32f4_tim2.h" unsigned int status=0; void FM_TIM2_TIMER_Pre(uint16_t prescaler, uint16_t periode); void FM_TIM2_NVIC_Pre(void); uint32_t tim2_enable_flag=0; static unsigned long sysTickCounter; /*************************************************************** * system Ticks initialize *SystemFrequency/1000 1ms *SystemFrequency/100000 10us *SystemFrequency/1000000 1us ***************************************************************/ void FM_SysTick_Init(void) { while (SysTick_Config(SystemCoreClock / 1000000) != 0) { } // 1 us equal to 1 system ticks } /*************************************************************** * Timer 2 initialize ***************************************************************/ void FM_TIMER2_Init(uint16_t prescaler, uint16_t periode) { // Timer flag disable tim2_enable_flag=0; // Timer initialize FM_TIM2_TIMER_Pre(prescaler, periode); FM_TIM2_NVIC_Pre(); } /*************************************************************** * Timer 2 delay count ***************************************************************/ void FM_Timer_delay(uint16_t count) { status=0; while(count--) { TIMER2_Init(9339,10); TIMER2_Start(); } } /*************************************************************** * Timer 2 initilize at given frequency ***************************************************************/ void FM_TIMER2_Init_FRQ(uint32_t frq_hz) { RCC_ClocksTypeDef RCC_Clocks; uint32_t clk_frq; uint16_t prescaler, periode; uint32_t u_temp; float teiler,f_temp; // Clock-Frequence (PCLK1) RCC_GetClocksFreq(&RCC_Clocks); clk_frq = RCC_Clocks.PCLK1_Frequency; if(frq_hz==0) frq_hz=1; if(frq_hz>clk_frq) frq_hz=clk_frq; teiler=(float)(clk_frq<<1)/(float)(frq_hz); u_temp=(uint32_t)(teiler); prescaler=(u_temp>>16); f_temp=(float)(teiler)/(float)(prescaler+1); periode=(uint16_t)(f_temp-1); FM_TIMER2_Init(prescaler, periode); } /*************************************************************** * Timer 2 start ***************************************************************/ void FM_TIMER2_Start(void) { // Timer enable TIM_Cmd(TIM2, ENABLE); // Timer flag enable tim2_enable_flag=1; } /*************************************************************** * Timer 2 stop ***************************************************************/ void FM_TIMER2_Stop(void) { // Timer flag disable tim2_enable_flag=0; // Timer 2 disable TIM_Cmd(TIM2, DISABLE); } /*************************************************************** * Timer 2 initialize ***************************************************************/ void FM_TIM2_TIMER_Pre(uint16_t prescaler, uint16_t periode) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; // Clock enable RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // Timer disable TIM_Cmd(TIM2, DISABLE); // Timer init TIM_TimeBaseStructure.TIM_Period = periode; TIM_TimeBaseStructure.TIM_Prescaler = prescaler; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); // Timer preload enable TIM_ARRPreloadConfig(TIM2, ENABLE); } /*************************************************************** * Timer 2 interrupt initialize ***************************************************************/ void FM_TIM2_NVIC_Pre(void) { NVIC_InitTypeDef NVIC_InitStructure; // Update Interrupt enable TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE); // NVIC NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } /*************************************************************** * Timer 2 interrupt function ***************************************************************/ void TIM2_IRQHandler(void) { if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) { TIM_ClearITPendingBit(TIM2, TIM_IT_Update); if(tim2_enable_flag==1) FM_TIMER2_ISR_CallBack(); } } /*************************************************************** * use as interrupt ***************************************************************/
3. fm_stm32f4_tim2.h function
/*************************************************************** * File : fm_stm32f4_tim2.h * website : www.firmcodes.com * email_id : support@firmcodes.com * IDE used : The files are Compiled in coocox ide and tested on stm32f4 discovery board. ***************************************************************/ #ifndef __FM_STM32F4_TIM2_H #define __FM_STM32F4_TIM2_H /*************************************************************** // Header Files Includes ***************************************************************/ #include "stm32f4xx.h" #include "stm32f4xx_rcc.h" #include "stm32f4xx_tim.h" #include "misc.h" #include "fm_stm32f4_led.h" /*************************************************************** * Gloable Function ***************************************************************/ void FM_TIMER2_Init(uint16_t prescaler, uint16_t periode); void FM_TIMER2_Init_FRQ(uint32_t frq_hz); void FM_TIMER2_Start(void); void FM_TIMER2_Stop(void); extern void TIMER2_ISR_CallBack(void); void FM_Timer_delay(uint16_t count); void FM_SysTick_Init(void); void FM_TIMER2_ISR_CallBack(); /***************************************************************/ #endif // __FM_STM32F4_TIM2_H
Complete project compiled in coocox is given below
- Led blinking using timer interrupt on stm32f4 Discovery Board