STM32學習筆記(三)——外部中斷的使用


 

開發板芯片:STM32F407ZGT6

硬件連接:PE3-KEY1

一、STM32F4的中斷介紹

STM32F4的每個IO都可以作為外部中斷輸入,很強大的功能吧!以前學習的51只有兩個外部中斷。

STM32F4的中斷控制器支持22個外部中斷/事件請求:

EXTI線0~15:對應外部IO口的輸入中斷。即GPIOx.0—EXTI0,GPIOx.a—EXTIa如下圖所示

EXTI線16:連接到PVD輸出。

EXTI線17:連接到RTC鬧鍾事件。

EXTI線18:連接到USB OTG FS喚醒事件。

EXTI線19:連接到以太網喚醒事件。

EXTI線20:連接到USB OTG HS(在FS中配置)喚醒事件。

EXTI線21:連接到RTC入侵和時間戳事件。EXTI線22:連接到RTC喚醒事件。

對於每個中斷線0我們可以設置相應的觸發方式(上升沿觸發,下降沿觸發,邊沿觸發)以及使能。

中斷服務函數又是如何分配的呢?

其中中斷線0-4有單獨的中斷向量,即單獨的中斷服務函數。

EXTI0_IRQHandler

EXTI1_IRQHandler

EXTI2_IRQHandler

EXTI3_IRQHandler

EXTI4_IRQHandler

中斷線5-9共用一個中斷服務函數

EXTI9_5_IRQHandler

中斷線10-15共同一個中斷服務函數

EXTI15_10_IRQHandler

二、中斷優先級的管理

嵌套向量中斷控制器NVIC (Nested vectored interrupt controller)

中斷優先級分組的是在SCB->AIRCR寄存器中設置的,具體設置情況如下:

選擇不同的分組可以設置不同的優先級等級,例如選擇分組2,分配結果為2位搶占,2位響應,既然是兩位,所以優先級可以設置為0-3,要注意的是,設置好分組之后不要再改變分組,隨意改變分組會導致中斷管理混亂。

 

關於搶占優先級和響應優先級的說明

    • 高優先級的搶占優先級可以打斷正在進行的低搶占優先級中斷的。
    • 搶占優先級相同的中斷,高響應優先級不可以打斷低響應優先級的中斷。
    • 搶占優先級相同的中斷,當兩個中斷同時發生的情況下,哪個響應優先級高,哪個先執行。
    • 如果兩個中斷的搶占優先級和響應優先級都是一樣的話,則看哪個中斷先發生就先執行;

例如:

這里要注意的是,搶占優先級設置的越小,則優先級越高,0最高

則這三個優先級的順序為:中斷7>中斷3>中斷6。 

三、程序設計

1.初始化PF3中斷,即EXTI3中斷的過程:

1.1.使能GPIO時鍾,注意:模式設置為輸入

    GPIO_InitTypeDef  GPIO_InitStructure;

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);   //使能GPIOA,GPIOE時鍾

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;		//普通輸入模式
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;		//上拉
    GPIO_Init(GPIOE, &GPIO_InitStructure);		
       

1.2.使能SYSCFG時鍾。

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);		//使能SYSCFG時鍾,必須的

1.3.設置GPIO和中斷線的映射關系

    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource3);	//PF3,中斷線映射,line3-Pin3

1.4.中斷初始化,包括設置觸發方式,指定中斷線,使能中斷,設置中斷模式等

    EXTI_InitTypeDef EXTI_InitStructure;		//中斷方式初始化

    EXTI_InitStructure.EXTI_Line = EXTI_Line3;				//指定中斷線3
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;					//使能中斷線
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;		//中斷模式
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;	//下降沿觸發方式,必須的,上升沿不靈敏
    EXTI_Init(&EXTI_InitStructure);

1.5.中斷分組和優先級設置

    NVIC_InitTypeDef NVIC_InitStructure;		//優先級初始化

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);		//設置中斷分組為2:2,優先級范圍0-3
    NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;				//指定中斷線3
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				//通道使能
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;		//搶占優先級0,可以設置0-3
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;			//響應優先級0,可以設置0-3
    NVIC_Init(&NVIC_InitStructure);

 2.中斷服務函數

中斷初始化完畢后,就可以編寫相應的中斷服務函數了,我們使用的是中斷線3,所以對應的中斷服務函數名稱為void EXTI3_IRQHandler(void),注意在執行完后要將標志位清零,

void EXTI3_IRQHandler(void)			//中斷線3服務函數,發生中斷時,自動執行
{
    delay_ms(10);	//消抖,很有必要,增加識別的准確度
    if(KEY1 == 0)			//用EXTI_GetITStatus(EXTI_Line3)!=RESET來判斷不是很靈敏,快速按時不准確
        LED0 = !LED0;
    EXTI_ClearITPendingBit(EXTI_Line3);  //清除LINE3上的中斷標志位,以備下一次使用
}

根據手冊可以通過EXTI_GetITStatus(EXTI_Line3)來判斷中斷標志位的狀態,實際運行時發現這種方式並不是很有效,可能是我的用法不對吧!

這個中斷服務函數還是很簡單的,就是按下按鍵時,將LED的狀態反轉

 3.主函數

主函數的執行部分可以不寫,這里寫了 LED 的閃爍用來指示程序的運行

int main(void)
{
    delay_init(168);
    LED_Init();
    IT_Init();		//中斷初始化
    LED0_OFF;
    LED1_OFF;
    while(1)
    {
        LED1_ON;
        delay_ms(500);			//LED1閃爍提醒程序運行狀態
        LED1_OFF;
        delay_ms(500);
    }
}

 

總結:

從以上過程可以看出STM32F4的外部中斷的配置和使用方法還是很簡單清晰的。雖然比51要復雜一些,但是畢竟功能那么強大,復雜一些也是可以理解的。

參考資料:

STM32F4xx中文參考手冊

STM32F4開發指南-庫函數版本_V1.1

 

以上是我學習過程的一些個人理解,有不對或不准確的地方,歡迎各位大神指正。

 

2017年4月17日22:01:43

歡迎大家關注我的個人博客

微信掃碼關注我的公眾號

不定期更新個人學習筆記和技術總結,歡迎大家互相學習交流!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM