Trong hướng dẫn này, tôi sẽ chia sẻ cách sử dụng ngắt ngoài trên STM32F4 Discovery. STM32F4 có 23 ngắt ngoài. Các dòng ngắt ngoài này bao gồm 2 phần. Các phần đầu tiên (dòng0 đến dòng15) dành cho ngắt ngoài từ các chân GPIO (P0 đến P15). Phần khác dành cho các sự kiện ngoại vi (RTC, Ethernet, USB).
Chúng ta có thể sử dụng 16 dòng ngắt ngoài (line0 đến line15) để phát hiện sự kiện bên ngoài từ các chân GPIO. Mỗi chân từ tất cả các cổng GPIO được kết nối với mỗi đường ngắt ngoài có cùng số.
- PA0, PB0, PC0, v.v., được ghép thành dòng0. Vì vậy, bạn chỉ có thể cấu hình một trong các chân này để kết nối với ngắt dòng0.
- PA0 và PA8 được ghép thành dòng khác nhau. Vì vậy, bạn có thể cấu hình các chân này để sử dụng ngắt ngoài cùng một lúc. Vì PA0 được kết nối với dòng0 và PA8 được kết nối với dòng8
Đối với các trình xử lý ngắt, STM32F4 chỉ có 7 trình xử lý ngắt để xử lý ngắt ngoài từ line0 đến line15.
#include "stm32f4xx.h" #include "stm32f4xx_rcc.h" #include "stm32f4xx_gpio.h" #include "stm32f4xx_exti.h" #include "stm32f4xx_syscfg.h" #include "misc.h" #include "clock.h" #include "delay.h" void EXTI_Init(void) { // Clock for GPIOA RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); // Clock for SYSCFG RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); // GPIOA initialization as an input from user button (GPIOA0) GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOA, &GPIO_InitStruct); // Selects the GPIOA pin 0 used as external interrupt source SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0); // External interrupt settings EXTI_InitTypeDef EXTI_InitStruct; EXTI_InitStruct.EXTI_Line = EXTI_Line0; EXTI_InitStruct.EXTI_LineCmd = ENABLE; EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising; EXTI_Init(&EXTI_InitStruct); // Nested vectored interrupt settings NVIC_InitTypeDef NVIC_InitStruct; NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; // EXTI0_IRQn has Most important interrupt NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00; NVIC_Init(&NVIC_InitStruct); } void EXTI0_IRQHandler(void) { // Checks whether the interrupt from EXTI0 or not if (EXTI_GetITStatus(EXTI_Line0)) { // Toggle orange LED (GPIO13) GPIO_ToggleBits(GPIOD, GPIO_Pin_13); // Clears the EXTI line pending bit EXTI_ClearITPendingBit(EXTI_Line0); } } int main(void) { // Set clock to 168MHz CLOCK_SetClockTo168MHz(); // Delay initialization DELAY_Init(); // External interrupt initialization EXTI_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 5s DELAY_Ms(5000); } }