1 原理
1.1 EXTI
外部中斷用到的外設-----------EXTI(External interrupt/event controller),中斷控制器,產生中斷
EXTI的功能框圖
輸入線: 對應的是GPIO,共有20根(EXTI_Line1..EXTI_Line19)
上升沿/下降沿觸發選擇寄存器: 配置觸發條件
軟件中斷寄存器: 是否產生中斷
中斷屏蔽寄存器: 中斷請求是否相應
1.2 NVIC
NVIC----------------配置中斷優先級,將中斷信號發送到內核,內核根據中斷服務程序做出反應
2 代碼
給出一個外部中斷的樣例,實現了按鍵中斷實現燈開關
關於按鍵的一些宏定義:
#define KEY_GPIO_PIN GPIO_Pin_1
#define KEY_GPIO_PORT GPIOA
#define KEY_GPIO_CLK RCC_AHBPeriph_GPIOA
#define KEY_ON 1
#define KEY_OFF 0
步驟一:配置產生中斷的GPIO
(1)定義GPIO初始化結構體
GPIO_InitTypeDef GPIO_InitStruct;
(2)初始化GPIO
//****************1-初始化GPIO**********************
RCC_AHBPeriphClockCmd(KEY_INT_CLK, ENABLE); //開時鐘
GPIO_InitStruct.GPIO_Pin = KEY_INT_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; //浮空
GPIO_Init(KEY_INT_PORT, &GPIO_InitStruct); //初始化
步驟二:初始化EXTI
(1)定義EXTI初始化結構體
EXTI_InitTypeDef EXTI_InitStruct;
(2)初始化EXTI
//****************2-初始化EXTI**********************
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); //開時鐘
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource1); //選擇輸入線
EXTI_InitStruct.EXTI_Line = EXTI_Line0; //選擇EXTI線
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; //選擇模式
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising; //選擇上升沿觸發
EXTI_InitStruct.EXTI_LineCmd = ENABLE; //使能選擇的EXTI_Line
EXTI_Init(&EXTI_InitStruct) //初始化結構體
步驟三:配置中斷優先級
(1)定義NVIC初始化結構體
NVIC_InitTypeDef NVIC_InitStruct;
(2)配置中斷優先級
//****************3-配置中斷優先級**********************
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //配置組優先級
NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn; //選擇中斷源
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; //搶佔優先級
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1; //子優先級
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; //開總中斷
NVIC_Init(&NVIC_InitStruct); //初始化結構體
步驟四:編寫中斷服務函數
(1)在啓動文件中聲明中斷服務函數
(我用的是EXTI0這條線,啓動文件中已經默認編寫了中斷服務函數,並且爲弱定義)
(2)在stm32l1xx_it.c(根據你的型號)中實現中斷服務函數,並在頭文件中聲明
void EXTI0_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line0) != RESET)
{
LED_TOGGLE;
}
EXTI_ClearITPendingBit(EXTI_Line0);
}