Trong hướng dẫn này, tôi sẽ chia sẻ cách tạo ngắt mỗi khoảng thời gian nhất định bằng cách sử dụng bộ đếm thời gian trên bảng Khám phá STM32F4. Ví dụ: dự án, chúng tôi sẽ thực hiện chuyển đổi đèn LED màu cam sau mỗi khoảng thời gian 500ms bằng TIM2. Trong chương trình chính, chúng tôi sẽ chuyển đổi đèn LED màu xanh cứ sau 2500ms (chuyển đổi đèn LED màu xanh sẽ không sử dụng ngắt hẹn giờ mà chỉ sử dụng chức năng trì hoãn).
Đầu tiên, chúng tôi viết mã để khởi tạo bộ đếm thời gian. Chúng tôi sẽ sử dụng TIM2. Đây là sơ đồ khối để cấu hình đồng hồ hẹn giờ:
Hàm khởi tạo ngắt STM32F4
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); }
Chương trình ngắt tạo timer
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); } }
#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); } }