STM32之外部中斷控制
1、STM32外部中斷結(jié)構(gòu)圖
本文引用地址:http://m.butianyuan.cn/article/201611/318683.htm如上圖所示:主要包括四個(gè)環(huán)節(jié),GPIO、AFIO、EXTI、NVIC。以STM32F103VE(100腳)為例說明硬件模塊的數(shù)量:
GPIO: 80個(gè)
AFIO選擇通道: 16個(gè)
外部中斷線EXTI: 16 + 3 = 19個(gè)
NVIC : 1個(gè)
2、EXTI控制器結(jié)構(gòu)圖
①功能
- 中斷 申請(qǐng)中斷
- 事件 當(dāng)事件發(fā)生的時(shí)候,將產(chǎn)生事件脈沖,可以用來喚醒內(nèi)核
② 功能詳細(xì)說明
如果要產(chǎn)生中斷,必須事先配置好并使能中斷線。根據(jù)需要的邊沿檢測(cè)設(shè)置2個(gè)觸發(fā)寄存器,同時(shí)在中斷屏蔽寄存器的相應(yīng)位寫’1’ 允許中斷請(qǐng)求。當(dāng)外部中斷線上發(fā)生了需要的邊沿時(shí),將產(chǎn)生一個(gè)中斷請(qǐng)求,對(duì)應(yīng)的掛起位也隨之被置’1’ 。在掛起寄存器的對(duì)應(yīng)位寫’1’,可以清除該中斷請(qǐng)求。
如果要為產(chǎn)生事件,必須事先配置好并使能事件線。根據(jù)需要的邊沿檢測(cè)通過設(shè)置2個(gè)觸發(fā)寄存器,同時(shí)在事件屏蔽寄存器的相應(yīng)位寫’1’允許事件請(qǐng)求。當(dāng)事件線上發(fā)生了需要的邊沿時(shí),將產(chǎn)生一個(gè)事件請(qǐng)求脈沖,對(duì)應(yīng)的掛起位不被置’1’。
通過在軟件中斷/事件寄存器寫’1’,也可以通過軟件產(chǎn)生中斷/事件請(qǐng)求。
3、STM32外部中斷軟件配置步驟
① 配置NVIC控制器
② 使能GPIO和AFIO時(shí)鐘
③ 配置GPIO (復(fù)用功能的輸入輸出配置)
④ 配置AFIO (選定要配置為EXTI的I/O口線)
⑤ EXTI控制器的配置
配置寄存器就好像是我們?cè)诟腟TM32的硬件電路,讓它們處于一種新的工作狀態(tài)--外部中斷模式。
二、STM32外部中斷軟件配置細(xì)節(jié)
以PA0引腳的外部中斷為例進(jìn)行介紹:
1、配置NVIC控制器
PA0引腳對(duì)應(yīng)的外部中斷線是EXTI_Line0,而EXTI_Line0對(duì)應(yīng)的中斷源是EXTI0_IRQn。
調(diào)用NVIC_Init函數(shù)設(shè)置中斷源EXTI0_IRQn的搶占優(yōu)先級(jí)和響應(yīng)優(yōu)先級(jí),并且使能中斷。
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_IRQChannel
定義配置的對(duì)象,是哪一個(gè)中斷源,它不能使用“EXTI0_IRQnEXTI0_IRQn”方式調(diào)用一次NVIC_Init函數(shù)配置多個(gè)中斷源
2、使能GPIO和AFIO時(shí)鐘
GPIO用作EXTI外部中斷或使用重映射功能的時(shí)候,不僅需要開啟外設(shè)時(shí)鐘RCC_APB2Periph_GPIOA,還需要開啟AFIO時(shí)鐘RCC_APB2Periph_AFIO。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA RCC_APB2Periph_AFIO,ENABLE);
3、配置GPIO(復(fù)用功能的輸入輸出配置)
配置PA0為上拉輸入。
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上拉輸入GPIO_Init(GPIOA, &GPIO_InitStructure);
4、配置AFIO(選定要配置為EXTI的I/O口線)
PA0引腳對(duì)應(yīng)的外部中斷線是EXTI_Line0,但是PB0~PG0對(duì)應(yīng)的也都是這個(gè)外部中斷線。所以,需要通過多路選擇器確定到底是哪一個(gè)引腳映射到EXTI_Line0。
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
5、EXTI控制器的配置
配置外部中斷線EXTI_Line0的工作模式,為中斷模式,下降沿觸發(fā)中斷,并且使能外部中斷線EXTI_Line0。
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);
三、中斷配置過程以及STM中斷結(jié)構(gòu)解惑
1、為什么NVIC有使能中斷,EXTI控制器還有一個(gè)使能控制呢?
NVIC控制器是在ARM公司設(shè)計(jì)的Cortex-M3內(nèi)核中,EXTI控制器是ST公司自己設(shè)計(jì)的外設(shè)。
在NVIC控制器中,有“Interrupt set-enable register&Interrupt clear-enable register”,它們來控制是否使能中斷源EXTI0_IRQn。
而EXTI控制器中,有“Interrupt mask register”來控制中斷線EXTI_Line0的中斷標(biāo)志位是否傳送給NVIC控制器。
2、為什么NVIC控制器使能中斷源的寄存器要兩種?
中斷的使能與除能分別使用各自的寄存器來控制——這與傳統(tǒng)的,使用單一比特的兩個(gè)狀態(tài)來表達(dá)使能與除能是不同的。CM3 中可以有 240 對(duì)使能位/除能位(SETENA 位/CLRENA 位),每個(gè)中斷擁有一對(duì)。這 240 個(gè)對(duì)子分布在 8 對(duì)32位寄存器中(最后一對(duì)沒有用完)。欲使能一個(gè)中斷,我們需要寫1 到對(duì)應(yīng)SETENA的位中;欲除能一個(gè)中斷,你需要寫 1 到對(duì)應(yīng)的CLRENA位中。如果往它們中寫0,則不會(huì)有任何效果。
寫零無效是個(gè)很關(guān)鍵的設(shè)計(jì)理念:通過這種方式,使能/除能中斷時(shí)只需把“當(dāng)事位”寫成 1,其它的位可以全部為零。再也不用像以前那樣,害怕有些位被寫入0 而破壞其對(duì)應(yīng)的中斷設(shè)置(反正現(xiàn)在寫 0 沒有效果了),從而實(shí)現(xiàn)每個(gè)中斷都可以自顧地設(shè)置,而互不侵犯——只需單一的寫指令,不再需要讀-改-寫三步曲。(摘自《CM3權(quán)威指南》)
3、在清除中斷標(biāo)志位的時(shí)候,為什么只需要清除EXTI的中斷標(biāo)志位就行,而不需要清除NVIC的懸起寄存器SETPEND?
有些程序員在中斷服務(wù)程序結(jié)束的位置清除中斷源的時(shí)候,還調(diào)用了NVIC_ClearPendingIRQ()函數(shù)清除中斷源的懸起標(biāo)志位,其實(shí)是不需要的?! ?/p>
如果中斷發(fā)生時(shí),正在處理同級(jí)或高優(yōu)先級(jí)異常,或者被掩蔽,則中斷不能立即得到響應(yīng)。此時(shí)中斷被懸起。中斷的懸起狀態(tài)可以通過“中斷設(shè)置懸起寄存器(SETPEND) ”和“中斷懸起清除寄存器(CLRPEND) ”來讀取,還可以寫它們來手工懸起中斷。(這段文字摘自《CM3權(quán)威指南》)
由此我們可以得出結(jié)論:如果中斷服務(wù)程序得到執(zhí)行(中斷得到響應(yīng)),此時(shí)中斷就不會(huì)被懸起。所以我們的中斷服務(wù)程序不需要清除“懸起標(biāo)志位”。
有人可能還會(huì)這么想:倘若一個(gè)中斷服務(wù)程序因?yàn)樘幚砥髡趫?zhí)行同級(jí)中斷服務(wù)程序而不能被執(zhí)行,中斷被懸起,那么當(dāng)輪到這個(gè)中斷得到響應(yīng)后,這個(gè)中斷服務(wù)程序需要清楚“懸起標(biāo)志位”嗎?
我認(rèn)為還是不需要,因?yàn)橹袛鄻?biāo)志位的懸起和解懸,硬件都是可以自動(dòng)控制的。也就是說,當(dāng)懸起的中斷被響應(yīng)的時(shí)候,“懸起標(biāo)志位”自動(dòng)被硬件予以清除,不必手動(dòng)清除。
參考資料:《STM32 庫開發(fā)實(shí)戰(zhàn)指南》
《CM3權(quán)威指南》
《STM32F10X芯片手冊(cè)》
《STM32F10xxx Cortex-M3 programming manual.pdf》
評(píng)論