使用S? 32設置GPIO中斷
- 中斷示例
- 按鍵中斷實例設計:EXTI0和EXTI9
- 硬件連接分析
- STM32代碼實現
- 代碼說明
中斷示例
設計一個按鍵中斷的實例。設置兩個中斷:EXTI0、EXTI9,
在EXTI9的中斷服務之程序中實現LED燈的控制
按鍵中斷實例設計:EXTI0和EXTI9
根據提供的電路圖,我將設計一個基于STM32的按鍵中斷系統,其中兩個按鍵分別連接到EXTI0和EXTI9引腳,并通過EXTI9的中斷服務程序控制LED燈組。
硬件連接分析
從電路圖可以看出:
- 兩個按鍵
Key Button
和Wakeup Button
通過上拉/下拉電阻連接到微控制器 - EXTI0連接到第一個按鍵輸入
- EXTI9連接到第二個按鍵輸入
- 四個LED燈(帶限流電阻)連接到微控制器的GPIO引腳
STM32代碼實現
#include "stm32f10x.h" // 假設使用STM32F10x系列,可根據實際芯片修改// LED相關定義
#define LED_PORT GPIOB
#define LED_PIN_ALL (GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11)
#define LED_ALL_ON() GPIO_SetBits(LED_PORT, LED_PIN_ALL)
#define LED_ALL_OFF() GPIO_ResetBits(LED_PORT, LED_PIN_ALL)// 按鍵相關定義
#define KEY0_PORT GPIOA
#define KEY0_PIN GPIO_Pin_0 // EXTI0對應PA0
#define KEY1_PORT GPIOA
#define KEY1_PIN GPIO_Pin_9 // EXTI9對應PA9// 中斷標志位
volatile uint8_t Key0Pressed = 0;
volatile uint8_t Key1Pressed = 0;// LED狀態變量
volatile uint8_t ledState = 0; // 0:全滅, 1:交替閃爍, 2:全部點亮/** 函數名:EXTI0_IRQHandler* 描述:EXTI0中斷服務程序* 輸入:無* 輸出:無*/外部中斷函數EXTI0_IRQHandler
void EXTI0_IRQHandler(void)
{// 檢查是否是KEY0觸發的中斷if(EXTI_GetITStatus(EXTI_Line0) != RESET){// 清除中斷標志位EXTI_ClearITPendingBit(EXTI_Line0);// 設置按鍵0被按下的標志Key0Pressed = 1;}
}/** 函數名:EXTI9_5_IRQHandler* 描述:EXTI9-5中斷服務程序* 輸入:無* 輸出:無*/EXTI9-5中斷服務程序EXTI9中斷服務程序中實現了三種LED控制模式
void EXTI9_5_IRQHandler(void)
{// 檢查是否是KEY1觸發的中斷if(EXTI_GetITStatus(EXTI_Line9) != RESET){// 清除中斷標志位EXTI_ClearITPendingBit(EXTI_Line9);// 設置按鍵1被按下的標志Key1Pressed = 1;// 控制LED燈switch(ledState){case 0: // 全滅LED_ALL_ON();ledState = 1;break;case 1: // 全部點亮LED_ALL_OFF();ledState = 2;break;case 2: // 交替閃爍模式GPIO_Write(LED_PORT, (GPIO_ReadOutputData(LED_PORT) ^ LED_PIN_ALL));break;}}
}/** 函數名:KEY_Init* 描述:初始化按鍵GPIO和中斷* 輸入:無* 輸出:無*/
void KEY_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;EXTI_InitTypeDef EXTI_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;// 使能GPIOA時鐘RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);// 配置KEY0和KEY1為浮空輸入GPIO_InitStructure.GPIO_Pin = KEY0_PIN | KEY1_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(KEY0_PORT, &GPIO_InitStructure);// 使能AFIO時鐘RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);// 配置KEY0為EXTI0中斷線GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);配置EXIT線EXTI_InitStructure.EXTI_Line = EXTI_Line0;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿觸發EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure);// 配置KEY1為EXTI9中斷線GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource9);EXTI_InitStructure.EXTI_Line = EXTI_Line9;EXTI_Init(&EXTI_InitStructure);// 配置NVIC中斷優先級NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;NVIC_Init(&NVIC_InitStructure);
}/** 函數名:LED_Init* 描述:初始化LED GPIO* 輸入:無* 輸出:無*/
void LED_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;// 使能GPIOB時鐘RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);// 配置LED端口為推挽輸出GPIO_InitStructure.GPIO_Pin = LED_PIN_ALL;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(LED_PORT, &GPIO_InitStructure);// 初始狀態:全滅LED_ALL_OFF();
}int main(void)
{// 初始化按鍵和LEDKEY_Init();LED_Init();while(1){// 檢查KEY0是否被按下if(Key0Pressed){// 短暫延時,消除抖動for(volatile uint32_t i = 0; i < 10000; i++);// 處理按鍵事件// 這里可以添加其他功能// 清除標志位Key0Pressed = 0;}// 檢查KEY1是否被按下if(Key1Pressed){// 短暫延時,消除抖動for(volatile uint32_t i = 0; i < 10000; i++);// 清除標志位Key1Pressed = 0;}// 可以在這里添加其他主循環邏輯}
}
代碼說明
-
硬件配置:
- EXTI0連接到PA0引腳
- EXTI9連接到PA9引腳
- 四個LED燈連接到PB8-PB11引腳
-
中斷配置:
- EXTI0和EXTI9均配置為下降沿觸發
- 為兩個中斷分配了相同的優先級
-
LED控制:
- EXTI9中斷服務程序中實現了三種LED控制模式:
- 全滅 → 全部點亮 → 交替閃爍
- 使用ledState變量跟蹤當前LED狀態
- EXTI9中斷服務程序中實現了三種LED控制模式:
-
按鍵消抖:
- 在主循環中通過延時實現簡單的按鍵消抖
-
中斷標志位:
- 使用Key0Pressed和Key1Pressed變量作為中斷標志位
這個設計實現了按鍵檢測和LED控制的基本功能,可以根據實際需求進一步擴展和優化。