立即注冊(cè) 登錄
返回首頁(yè)

uid:218435的個(gè)人空間

日志

STM32F4外部中斷入口和外部中斷線

熱度 1已有 4855 次閱讀2017-7-10 13:41 |個(gè)人分類(lèi):STM32

STM32F4的每個(gè)IO都可以作為外部中斷的中斷輸入口,這點(diǎn)也是STM32F4的強(qiáng)大之處。STM32F407的中斷控制器支持22個(gè)外部中斷/事件請(qǐng)求。每個(gè)中斷設(shè)有狀態(tài)位,每個(gè)中斷/事件都有獨(dú)立的觸發(fā)和屏蔽設(shè)置。STM32F407的22個(gè)外部中斷為:

EXTI線0~15:對(duì)應(yīng)外部IO口的輸入中斷。

EXTI線16:連接到PVD輸出。

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

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

EXTI線19:連接到以太網(wǎng)喚醒事件。

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

EXTI線21:連接到RTC入侵和時(shí)間戳事件。

EXTI線22:連接到RTC喚醒事件。

從上面可以看出,STM32F4供IO口使用的中斷線只有16個(gè),但是STM32F4的IO口卻遠(yuǎn)遠(yuǎn)不止16個(gè),那么STM32F4是怎么把16個(gè)中斷線和IO口一一對(duì)應(yīng)起來(lái)的呢?于是STM32就這樣設(shè)計(jì),GPIO的管教GPIOx.0~GPIOx.15(x=A,B,C,D,E,F(xiàn),G,H,I)分別對(duì)應(yīng)中斷線0~15。這樣每個(gè)中斷線對(duì)應(yīng)了最多9個(gè)IO口,以線0為例:它對(duì)應(yīng)了GPIOA.0、GPIOB.0、GPIOC.0、GPIOD.0、GPIOE.0、GPIOF.0、GPIOG.0,GPIOH.0,GPIOI.0。而中斷線每次只能連接到1個(gè)IO口上,這樣就需要通過(guò)配置來(lái)決定對(duì)應(yīng)的中斷線配置到哪個(gè)GPIO上了。下面我們看看GPIO跟中斷線的映射關(guān)系圖:




圖1 GPIO和中斷線的映射關(guān)系圖

接下來(lái)我們講解使用庫(kù)函數(shù)配置外部中斷的步驟。

1)      使能IO口時(shí)鐘,初始化IO口為輸入

       首先,我們要使用IO口作為中斷輸入,所以我們要使能相應(yīng)的IO口時(shí)鐘,以及初始化相應(yīng)的IO口為輸入模式。這里就不做過(guò)多講解。

2)      開(kāi)啟SYSCFG時(shí)鐘,設(shè)置IO口與中斷線的映射關(guān)系。

接下來(lái),我們要配置GPIO與中斷線的映射關(guān)系,那么我們首先需要打開(kāi)SYSCFG時(shí)鐘。

RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//使能SYSCFG時(shí)鐘

這里大家一定要注意,只要我們使用到外部中斷,就必須打開(kāi)SYSCFG時(shí)鐘。

接下來(lái),我們配置GPIO與中斷線的映射關(guān)系。在庫(kù)函數(shù)中,配置GPIO與中斷線的映射關(guān)系的函數(shù)SYSCFG_EXTILineConfig ()來(lái)實(shí)現(xiàn)的:

void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex);

該函數(shù)將GPIO端口與中斷線映射起來(lái),使用范例是:

SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);

將中斷線0與GPIOA映射起來(lái),那么很顯然是GPIOA.0與EXTI1中斷線連接了。設(shè)置好中斷線映射之后,那么到底來(lái)自這個(gè)IO口的中斷是通過(guò)什么方式觸發(fā)的呢?接下來(lái)我們就要設(shè)置該中斷線上中斷的初始化參數(shù)了。

3)      初始化線上中斷,設(shè)置觸發(fā)條件等。

中斷線上中斷的初始化是通過(guò)函數(shù)EXTI_Init()實(shí)現(xiàn)的。EXTI_Init()函數(shù)的定義是:

void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);

下面我們用一個(gè)使用范例來(lái)說(shuō)明這個(gè)函數(shù)的使用:

       EXTI_InitTypeDef  EXTI_InitStructure;

      EXTI_InitStructure.EXTI_Line=EXTI_Line4;

      EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

      EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;

      EXTI_InitStructure.EXTI_LineCmd = ENABLE;

      EXTI_Init(&EXTI_InitStructure);             //初始化外設(shè)EXTI寄存器

上面的例子設(shè)置中斷線4上的中斷為下降沿觸發(fā)。STM32的外設(shè)的初始化都是通過(guò)結(jié)構(gòu)體來(lái)設(shè)置初始值的,這里就不再講解結(jié)構(gòu)體初始化的過(guò)程了。我們來(lái)看看結(jié)構(gòu)體EXTI_InitTypeDef的成員變量:

typedef struct

{ uint32_t EXTI_Line;

  EXTIMode_TypeDef EXTI_Mode;  

  EXTITrigger_TypeDef EXTI_Trigger;

  FunctionalState EXTI_LineCmd;

}EXTI_InitTypeDef;

從定義可以看出,有4個(gè)參數(shù)需要設(shè)置。第一個(gè)參數(shù)是中斷線的標(biāo)號(hào),對(duì)于我們的外部中斷,取值范圍為EXTI_Line0~EXTI_Line15。這個(gè)在上面已經(jīng)講過(guò)中斷線的概念。也就是說(shuō),這個(gè)函數(shù)配置的是某個(gè)中斷線上的中斷參數(shù)。第二個(gè)參數(shù)是中斷模式,可選值為中斷EXTI_Mode_Interrupt和事件EXTI_Mode_Event。第三個(gè)參數(shù)是觸發(fā)方式,可以是下降沿觸發(fā)EXTI_Trigger_Falling,上升沿觸發(fā)EXTI_Trigger_Rising,或者任意電平(上升沿和下降沿)觸發(fā)EXTI_Trigger_Rising_Falling,相信學(xué)過(guò)51的對(duì)這個(gè)不難理解。最后一個(gè)參數(shù)就是使能中斷線了。

4)      配置中斷分組(NVIC),并使能中斷。

我們?cè)O(shè)置好中斷線和GPIO映射關(guān)系,然后又設(shè)置好了中斷的觸發(fā)模式等初始化參數(shù)。既然是外部中斷,涉及到中斷我們當(dāng)然還要設(shè)置NVIC中斷優(yōu)先級(jí)。這個(gè)在前面已經(jīng)講解過(guò),這里我們就接著上面的范例, 設(shè)置中斷線2的中斷優(yōu)先級(jí)。

NVIC_InitTypeDef NVIC_InitStructure;

NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;           //使能按鍵外部中斷通道

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;  //搶占優(yōu)先級(jí)2,

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;             //響應(yīng)優(yōu)先級(jí)2

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                //使能外部中斷通道

NVIC_Init(&NVIC_InitStructure);                          //中斷優(yōu)先級(jí)分組初始化


5)      編寫(xiě)中斷服務(wù)函數(shù)。

       我們配置完中斷優(yōu)先級(jí)之后,接著我們要做的就是編寫(xiě)中斷服務(wù)函數(shù)。中斷服務(wù)函數(shù)的名字是在MDK中事先有定義的。這里需要說(shuō)明一下,STM32F4的IO口外部中斷函數(shù)只有7個(gè),分別為:

EXPORT  EXTI0_IRQHandler         

EXPORT  EXTI1_IRQHandler      

EXPORT  EXTI2_IRQHandler        

EXPORT  EXTI3_IRQHandler      

EXPORT  EXTI4_IRQHandler         

EXPORT  EXTI9_5_IRQHandler      

EXPORT  EXTI15_10_IRQHandler     

中斷線0-4每個(gè)中斷線對(duì)應(yīng)一個(gè)中斷函數(shù),中斷線5-9共用中斷函數(shù)EXTI9_5_IRQHandler,中斷線10-15共用中斷函數(shù)EXTI15_10_IRQHandler。在編寫(xiě)中斷服務(wù)函數(shù)的時(shí)候會(huì)經(jīng)常使用到兩個(gè)函數(shù),第一個(gè)函數(shù)是判斷某個(gè)中斷線上的中斷是否發(fā)生(標(biāo)志位是否置位):

ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);

這個(gè)函數(shù)一般使用在中斷服務(wù)函數(shù)的開(kāi)頭判斷中斷是否發(fā)生。另一個(gè)函數(shù)是清除某個(gè)中斷線上的中斷標(biāo)志位:

void EXTI_ClearITPendingBit(uint32_t EXTI_Line);

這個(gè)函數(shù)一般應(yīng)用在中斷服務(wù)函數(shù)結(jié)束之前,清除中斷標(biāo)志位。

常用的中斷服務(wù)函數(shù)格式為:

void EXTI3_IRQHandler(void)

{

if(EXTI_GetITStatus(EXTI_Line3)!=RESET)//判斷某個(gè)線上的中斷是否發(fā)生   

       { …中斷邏輯…

        EXTI_ClearITPendingBit(EXTI_Line3);  //清除LINE上的中斷標(biāo)志位

       }           

}

在這里需要說(shuō)明一下,固件庫(kù)還提供了兩個(gè)函數(shù)用來(lái)判斷外部中斷狀態(tài)以及清除外部狀態(tài)標(biāo)志位的函數(shù)EXTI_GetFlagStatus和EXTI_ClearFlag,他們的作用和前面兩個(gè)函數(shù)的作用類(lèi)似。只是在EXTI_GetITStatus函數(shù)中會(huì)先判斷這種中斷是否使能,使能了才去判斷中斷標(biāo)志位,而EXTI_GetFlagStatus直接用來(lái)判斷狀態(tài)標(biāo)志位。

講到這里,相信大家對(duì)于STM32的IO口外部中斷已經(jīng)有了一定了了解。下面我們?cè)倏偨Y(jié)一下使用IO口外部中斷的一般步驟:

1)使能IO口時(shí)鐘,初始化IO口為輸入。

2)使能SYSCFG時(shí)鐘,設(shè)置IO口與中斷線的映射關(guān)系。

3)初始化線上中斷,設(shè)置觸發(fā)條件等。

4)配置中斷分組(NVIC),并使能中斷。

5)編寫(xiě)中斷服務(wù)函數(shù)。

通過(guò)以上幾個(gè)步驟的設(shè)置,我們就可以正常使用外部中斷了。


路過(guò)

雞蛋
1

鮮花

握手

雷人

剛表態(tài)過(guò)的朋友 (1 人)

評(píng)論 (0 個(gè)評(píng)論)

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

返回頂部