一、STM32中斷的含義
中斷的含義在這裡用一個打比方來解釋。STM32好比是一個人。這個人,他現在正在幹某一項活動(比如寫作業,作業還挺多,他估計得寫很久),現在他的班主任要找他去幹一個某一個活(比如去取個快遞,時間比較短的一個活動)。這個時候這個人 ,他放下作業去取快遞就是中斷。那麼如果班主任和校長同時叫他去取快遞呢?這個時候,就要涉及到優先級的問題。
二、中斷優先級
在初始化一個EXTI的時候,我們需要先指定各個中斷的優先級(誰叫來指使這個“他”來幹活)。在STM32中, 設定有搶占優先級 和 響應優先級
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIwczX0xiRGZkRGZ0Xy9GbvNGL2EzXlpXazxSdW12YuVzVaRnVHFmesdkYxY0MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnLyYzNyIDMxYTMzEzNwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
搶占優先級 響應優先級兩級比較規則為 : 先比較搶占優先級,如果搶占優先級一樣,再比較響應優先級。
每一級比較規則為:“The lower the value, the greater the priority of the corresponding interrupt.”
三、在stm32 keil中的程式設計
(1)打開時鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
//待商榷記得打開複用時鐘。
(2)配置GPIO口
GPIO_InitStructre.GPIO_Pin=GPIO_Pin_x; // x口作為GPIO,也是EXTI口。
GPIO_InitStructre.GPIO_Mode=GPIO_Mode_IPU/GPIO_Mode_IPU; //下降沿觸發 ,是以給上拉的。
GPIO_InitStructre.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIO_InitStructre);
(3)定義兩個配置中斷的結構體
NVIC_InitTypeDef NVIC_InitStru;
EXTI_InitTypeDef EXTI_InitStru;
NVIC的意思是Nested vectoredinterrupt controller,即嵌套向量中斷控制器。
如果需要定義優先級分組的話,采用NVIC_PriorityGroupConfig指令,其中變量填:NVIC_PriorityGroup_1/2/3/4。NVIC_PriorityGroupConfig(NVIC_PriorityGroup_x)
NVIC結構體定義:
NVIC_InitStru.NVIC_IRQChannel:選擇哪個中斷,中斷類型可在STM32中文參考手冊_V10.pdf,131頁。可以看到EXTI0-4是單獨的channel,5-9,10-15是共的一個channel。完整的為EXTI9_5(channel)_IRQn。其中IRQ:Interrupt Request。
NVIC_InitStru.NVIC_IRQChannelCmd:給ENABLE。
NVIC_InitStru.NVIC_IRQChannelPreemptionPriority,NVIC_IRQChannelSubPriority是 搶占優先級 與 響應優先級。
EXTI結構體初始化:
EXTI_InitStru.EXTI_Line:外部的中斷通用I/O映像,從此處可以選擇line。
EXTI_InitStru.EXTI_Mode:中斷模式選擇,可選 中斷(EXTI_Mode_Interrupt) 或者 事件(EXTI_Mode_Event)。
EXTI_InitStru.EXTI_Trigger:觸發信号,可選 上升沿(EXTI_Trigger_Rising) 或者下降沿 (EXTI_Trigger_Falling) 或者 上升沿/下降沿(EXTI_Trigger_Rising_Falling)。
EXTI_InitStru.EXTI_LineCmd:給ENABLE。
再加上 EXTI_Init(&EXTI_InitStru); 就完成EXTI初始化。
(4)總體代碼
int main(void){
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //需要使能複用時鐘
GPIO_InitTypeDef GPIO_InitStructre;
NVIC_InitTypeDef NVIC_InitStru;
EXTI_InitTypeDef EXTI_InitStru;
GPIO_InitStructre.GPIO_Pin=GPIO_Pin_8; //在這兒要修改,修改為需要的口。
GPIO_InitStructre.GPIO_Mode=GPIO_Mode_IPU; //需要修改,修改為上拉或者下降。
GPIO_InitStructre.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIO_InitStructre);
NVIC_InitStru.NVIC_IRQChannel = EXTI9_5_IRQn; //這兒需要修改, 修改為對應的channel
NVIC_InitStru.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStru.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStru.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStru);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource8);
EXTI_InitStru.EXTI_Line = EXTI_Line8; //這兒需要修改, 修改為對應的channel
EXTI_InitStru.EXTI_Mode= EXTI_Mode_Interrupt;
EXTI_InitStru.EXTI_Trigger=EXTI_Trigger_Falling;
EXTI_InitStru.EXTI_LineCmd=ENABLE;
EXTI_Init(&EXTI_InitStru);
while(1){
}
}
void EXTI9_5_IRQHandler(){ //一定要注意是EXTI9_5_IRQHandler,中間有個IRQ 不要落了。
EXTI_ClearITPendingBit(EXTI_Line8);//保證能正确退出
}