久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

第16章 STM32中斷應用概覽

 waston 2018-05-02

第16章     STM32中斷應用概覽

本章參考資料《STM32F4xx 中文參考手冊》第十章-中斷和事件,、《 ARM Cortex?-M4F 技術參考手冊》-4.3 章節(jié):NVIC4.4章節(jié):SCB4.4.5AIRCR

STM32中斷非常強大,,每個外設都可以產生中斷,,所以中斷的講解放在哪一個外設里面去講都不合適,,這里單獨抽出一章來做一個總結性的介紹,這樣在其他章節(jié)涉及到中斷部分的知識我們就不用費很大的篇幅去講解,,只要示意性帶過即可,。

本章如無特別說明,異常就是中斷,,中斷就是異常,,請不要刻意鉆牛角尖較勁。

16.1 異常類型

F429在內核水平上搭載了一個異常響應系統(tǒng),,支持為數眾多的系統(tǒng)異常和外部中斷,。其中系統(tǒng)異常有10個,外部中斷有91個,。除了個別異常的優(yōu)先級被定死外,,其它異常的優(yōu)先級都是可編程的。有關具體的系統(tǒng)異常和外部中斷可在標準庫文件stm32f4xx.h這個頭文件查詢到,,在IRQn_Type這個結構體里面包含了F4系列全部的異常聲明,。

表格 12 F429系統(tǒng)異常清單

編號

優(yōu)先級

優(yōu)先級類型

名稱

說明

地址

 

-

-

-

保留(實際存的是MSP地址)

0X0000 0000

 

-3

固定

Reset

復位

0X0000 0004

 

-2

固定

NMI

不可屏蔽中斷。 RCC 時鐘安全系統(tǒng)(CSS) 連接到 NMI 向量

0X0000 0008

 

-1

固定

HardFault

所有類型的錯誤

0X0000 000C

 

0

可編程

MemManage

存儲器管理

0X0000 0010

 

1

可編程

BusFault

預取指失敗,,存儲器訪問失敗

0X0000 0014

 

2

可編程

UsageFault

未定義的指令或非法狀態(tài)

0X0000 0018

 

-

-

-

保留

0X0000 001C-

0X0000 002B

 

3

可編程

SVCall

通過 SWI 指令調用的系統(tǒng)服務

0X0000 002C

 

4

可編程

Debug Monitor

調試監(jiān)控器

0X0000 0030

 

-

-

-

保留

0X0000 0034

 

5

可編程

PendSV

可掛起的系統(tǒng)服務

0X0000 0038

 

6

可編程

SysTick

系統(tǒng)嘀嗒定時器

0X0000 003C

表格 13 F429外部中斷清單

編號

優(yōu)先級

優(yōu)先級類型

名稱

說明

地址

0

7

可編程

-

窗口看門狗中斷

0X0000 0040

1

8

可編程

PVD

連接EXTI 線的可編程電壓檢測中斷

0X0000 0044

2

9

可編程

TAMP_STAMP

連接EXTI 線的入侵和時間戳中斷

0X0000 0048

中間部分省略,,詳情請參考STM32F4xx 中文參考手冊》第十章-中斷和事件-向量表部分

84

91

可編程

SPI4

SPI4全局中斷

0X0000 0190

85

92

可編程

SPI5

SPI5全局中斷

0X0000 0194

86

93

可編程

SPI6

SPI6全局中斷

0X0000 0198

87

94

可編程

SAI1

SAI1全局中斷

0X0000 019C

88

95

可編程

LTDC

LTDC全局中斷

0X0000 01A0

89

96

可編程

LTDC_ER

LTDC_ER全局中斷

0X0000 01A4

90

97

可編程

DMA2D

DMA2D全局中斷

0X0000 01A8

16.2 NVIC簡介

在講如何配置中斷優(yōu)先級之前,我們需要先了解下NVIC,。NVIC是嵌套向量中斷控制器,,控制著整個芯片中斷相關的功能,,它跟內核緊密耦合,,是內核里面的一個外設。但是各個芯片廠商在設計芯片的時候會對Cortex-M4內核里面的NVIC進行裁剪,,把不需要的部分去掉,,所以說STM32NVICCortex-M4NVIC的一個子集。

16.2.1 NVIC寄存器簡介

在固件庫中,,NVIC的結構體定義可謂是頗有遠慮,,給每個寄存器都預覽了很多位,恐怕為的是日后擴展功能,。不過STM32F429可用不了這么多,,只是用了部分而已,具體使用了多少可參考《 ARM Cortex?-M4F 技術參考手冊》-4.3.11:NVIC寄存器映射,。

代碼 17 NVIC結構體定義,,來自固件庫頭文件:core_cm4.h

 1 typedef
							struct {
				
 2     __IO uint32_t ISER[8];       // 中斷使能寄存器
			
 3 
							uint32_t RESERVED0[24];
				
 4     __IO uint32_t ICER[8];       // 中斷清除寄存器
			
 5 
							uint32_t RSERVED1[24];
				
 6     __IO uint32_t ISPR[8];       // 中斷使能懸起寄存器
			
 7 
							uint32_t RESERVED2[24];
				
 8     __IO uint32_t ICPR[8];       // 中斷清除懸起寄存器
			
 9 
							uint32_t RESERVED3[24];
				
10     __IO uint32_t IABR[8];       // 中斷有效位寄存器
			
11 
							uint32_t RESERVED4[56];
				
12     __IO uint8_t  IP[240];       // 中斷優(yōu)先級寄存器(8Bit wide)
				
13 
							uint32_t RESERVED5[644];
				
14     __O  uint32_t STIR;          // 軟件觸發(fā)中斷寄存器
			
15 }  NVIC_Type;
				
			

在配置中斷的時候我們一般只用ISERICERIP這三個寄存器,,ISER用來使能中斷,,ICER用來失能中斷,,IP用來設置中斷優(yōu)先級。

16.2.2 NVIC 中斷配置固件庫

固件庫文件core_cm4.h的最后,,還提供了NVIC的一些函數,,這些函數遵循CMSI規(guī)則,只要是Cortex-M4 的處理器都可以使用,,具體如下:

表格 14 符合CMSIS標準的NVIC庫函數

NVIC庫函數

描述

void NVIC_EnableIRQ(IRQn_Type IRQn)

使能中斷

void NVIC_DisableIRQ(IRQn_Type IRQn)

失能中斷

void NVIC_SetPendingIRQ(IRQn_Type IRQn)

設置中斷懸起位

void NVIC_ClearPendingIRQ(IRQn_Type IRQn)

清除中斷懸起位

uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)

獲取懸起中斷編號

void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)

設置中斷優(yōu)先級

uint32_t NVIC_GetPriority(IRQn_Type IRQn)

獲取中斷優(yōu)先級

void NVIC_SystemReset(void)

系統(tǒng)復位

這些庫函數我們在編程的時候用的都比較少,,甚至基本都不用。在配置中斷的時候我們還有更簡潔的方法,,請看中斷編程小節(jié),。

16.3 優(yōu)先級的定義

16.3.1 優(yōu)先級定義

NVIC 有一個專門的寄存器:中斷優(yōu)先級寄存器NVIC_IPRx(在F429中,x=0...90)用來配置外部中斷的優(yōu)先級,,IPR寬度為8bit,,原則上每個外部中斷可配置的優(yōu)先級為0~255,數值越小,,優(yōu)先級越高,。但是絕大多數CM4芯片都會精簡設計,以致實際上支持的優(yōu)先級數減少,,在F429中,,只使用了高4bit,如下所示:

表格 15 F429 使用4bit表達優(yōu)先級

bit7

bit6

bit5

bit4

bit3

bit2

bit1

bit0

用于表達優(yōu)先級

未使用,,讀回為0

用于表達優(yōu)先級的這4bit,,又被分組成搶占優(yōu)先級和子優(yōu)先級。如果有多個中斷同時響應,,搶占優(yōu)先級高的就會搶占搶占優(yōu)先級低的優(yōu)先得到執(zhí)行,,如果搶占優(yōu)先級相同,就比較子優(yōu)先級,。如果搶占優(yōu)先級和子優(yōu)先級都相同的話,,就比較他們的硬件中斷編號,編號越小,,優(yōu)先級越高,。

16.3.2 優(yōu)先級分組

優(yōu)先級的分組由內核外設SCB的應用程序中斷及復位控制寄存器AIRCRPRIGROUP[10:8]位決定,F429分為了5組,,具體如下:主優(yōu)先級=搶占優(yōu)先級

PRIGROUP[2:0]

中斷優(yōu)先級值PRI_N[7:4]

級數

二進制點

主優(yōu)先級位

子優(yōu)先級位

主優(yōu)先級

子優(yōu)先級

0b 011

0b xxxx

[7:4]

None

16

None

0b 100

0b xxx.y

[7:5]

[4]

8

2

0b 101

0b xx.yy

[7:6]

[5:4]

4

4

0b 110

0b x.yyy

[7]

[6:4]

2

9

0b 111

0b .yyyy

None

[7:4]

None

16

設置優(yōu)先級分組可調用庫函數NVIC_PriorityGroupConfig()實現,,有關NVIC中斷相關的庫函數都在庫文件misc.cmisc.h中。

代碼 18 中斷優(yōu)先級分組庫函數

 1 /**
				
 2   * 配置中斷優(yōu)先級分組:搶占優(yōu)先級和子優(yōu)先級
			
 3   * 形參如下:
			
 4   * @arg NVIC_PriorityGroup_0: 0bit for搶占優(yōu)先級
			
 5   *                            4 bits for 子優(yōu)先級
			
 6   * @arg NVIC_PriorityGroup_1: 1 bit for搶占優(yōu)先級
			
 7   *                            3 bits for 子優(yōu)先級
			
 8   * @arg NVIC_PriorityGroup_2: 2 bit for搶占優(yōu)先級
			
 9   *                            2 bits for 子優(yōu)先級
			
10   * @arg NVIC_PriorityGroup_3: 3 bit for搶占優(yōu)先級
			
11   *                            1 bits for 子優(yōu)先級
			
12   * @arg NVIC_PriorityGroup_4: 4 bit for搶占優(yōu)先級
			
13   *                            0 bits for 子優(yōu)先級
			
14   * @注意如果優(yōu)先級分組為0,,則搶占優(yōu)先級就不存在,,優(yōu)先級就全部由子優(yōu)先級控制
				
15   */
				
16 void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
				
17 {
				
18 
							// 設置優(yōu)先級分組
			
19     SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
				
20 }

表格 16 優(yōu)先級分組真值表

優(yōu)先級分組

主優(yōu)先級

子優(yōu)先級

描述

NVIC_PriorityGroup_0

0

0-15

-0bit,子-4bit

NVIC_PriorityGroup_1

0-1

0-7

-1bit,,子-3bit

NVIC_PriorityGroup_2

0-3

0-3

-2bit,,子-2bit

NVIC_PriorityGroup_3

0-7

0-1

-3bit,,子-1bit

NVIC_PriorityGroup_4

0-15

0

-4bit,子-0bit

16.4 中斷編程

在配置每個中斷的時候一般有3個編程要點:

1,、使能外設某個中斷,,這個具體由每個外設的相關中斷使能位控制。比如串口有發(fā)送完成中斷,,接收完成中斷,,這兩個中斷都由串口控制寄存器的相關中斷使能位控制。

2,、初始化NVIC_InitTypeDef結構體,,配置中斷優(yōu)先級分組,設置搶占優(yōu)先級和子優(yōu)先級,,使能中斷請求,。

代碼 19 NVIC初始化結構體

 1 typedef
							struct {
				
 2 
							uint8_t NVIC_IRQChannel;                    // 中斷源
			
 3 
							uint8_t NVIC_IRQChannelPreemptionPriority;  // 搶占優(yōu)先級
			
 4 
							uint8_t NVIC_IRQChannelSubPriority;         // 子優(yōu)先級
			
 5     FunctionalState NVIC_IRQChannelCmd;         // 中斷使能或者失能
			
 6 } NVIC_InitTypeDef;

有關NVIC初始化結構體的成員我們一一解釋下:

1)NVIC_IROChannel:用來設置中斷源,不同的中斷中斷源不一樣,,且不可寫錯,,即使寫錯了程序不會報錯,只會導致不想要中斷,。具體的成員配置可參考stm32f4xx.h頭文件里面的IRQn_Type結構體定義,,這個結構體包含了所有的中斷源。

代碼 20 IRQn_Type中斷源結構體

 1 typedef
							enum IRQn {
				
 2 
							//Cortex-M4 處理器異常編號
			
 3     NonMaskableInt_IRQn      = -14,
				
 4     MemoryManagement_IRQn    = -12,
				
 5     BusFault_IRQn            = -11,
				
 6     UsageFault_IRQn          = -10,
				
 7     SVCall_IRQn              = -5,
				
 8     DebugMonitor_IRQn        = -4,
				
 9     PendSV_IRQn              = -2,
				
10     SysTick_IRQn             = -1,
				
11 
							//STM32 外部中斷編號
			
12     WWDG_IRQn                = 0,
				
13     PVD_IRQn                 = 1,
				
14     TAMP_STAMP_IRQn          = 2,
				
15 
			
16 
								// 限于篇幅,,中間部分代碼省略,,具體的可查看庫文件stm32f4xx.h
				
17 
			
18     SPI4_IRQn                = 84,
				
19     SPI5_IRQn                = 85,
				
20     SPI6_IRQn                = 86,
				
21     SAI1_IRQn                = 87,
				
22     LTDC_IRQn                = 88,
				
23     LTDC_ER_IRQn             = 89,
				
24     DMA2D_IRQn               = 90
				
25 } IRQn_Type;
				
			

2)NVIC_IRQChannelPreemptionPriority:搶占優(yōu)先級,具體的值要根據優(yōu)先級分組來確定,,具體參考表格 16 優(yōu)先級分組真值表 ,。

3)NVIC_IRQChannelSubPriority:子優(yōu)先級,具體的值要根據優(yōu)先級分組來確定,,具體參考表格 16 優(yōu)先級分組真值表 ,。

4)NVIC_IRQChannelCmd:中斷使能(ENABLE)或者失能(DISABLE),。操作的是NVIC_ISER和NVIC_ICER這兩個寄存器,。

3、編寫中斷服務函數

在啟動文件startup_stm32f429_439xx.s中我們預先為每個中斷都寫了一個中斷服務函數,,只是這些中斷函數都是為空,,為的只是初始化中斷向量表。實際的中斷服務函數都需要我們重新編寫,,中斷服務函數我們統(tǒng)一寫在stm32f4xx_it.c這個庫文件中,。

關于中斷服務函數的函數名必須跟啟動文件里面預先設置的一樣,如果寫錯,,系統(tǒng)就在中斷向量表中找不到中斷服務函數的入口,,直接跳轉到啟動文件里面預先寫好的空函數,,并且在里面無限循環(huán),實現不了中斷,。

16.5 每課一問

1,、庫文件core_cm4.h主要實現了什么?回去認真看庫的源碼

2,、庫文件mics.c和mics.h主要實現了什么,?回去認真看庫的源碼

3、如果實現一次軟件系統(tǒng)復位,,具體是操作哪個寄存器的哪個位實現,?答案:給內核外設SCB的AIRCR寄存器的位2:SYSRESETREQ 寫1即可實現一次系統(tǒng)復位。


第17章     EXTI—外部中斷/事件控制器

本章參考資料:《STM32F4xx中文參考手冊》系統(tǒng)配置控制器以及中斷和事件章節(jié),。

上一章節(jié)我們已經詳細介紹了NVIC,,對STM32F4xx中斷管理系統(tǒng)有個全局的了解,我們這章的內容是NVIC的實例應用,,也是STM32F4xx控制器非常重要的一個資源,。學習本章時,配合《STM32F4xx中文參考手冊》系統(tǒng)配置控制器以及中斷和事件章節(jié)一起閱讀,,效果會更佳,,特別是涉及到寄存器說明的部分。

特別說明,,本書內容是以STM32F42xxx系列控制器資源講解,。

17.1 EXTI簡介

外部中斷/事件控制器(EXTI)管理了控制器的23個中斷/事件線。每個中斷/事件線都對應有一個邊沿檢測器,,可以實現輸入信號的上升沿檢測和下降沿的檢測,。EXTI可以實現對每個中斷/事件線進行單獨配置,可以單獨配置為中斷或者事件,,以及觸發(fā)事件的屬性,。

17.2 EXTI功能框圖

EXTI的功能框圖包含了EXTI最核心內容,掌握了功能框圖,,對EXTI就有一個整體的把握,,在編程時就思路就非常清晰。EXTI功能框圖見圖 171,。

在圖 171可以看到很多在信號線上打一個斜杠并標注"23"字樣,,這個表示在控制器內部類似的信號線路有23個,這與EXTI總共有23個中斷/事件線是吻合的,。所以我們只要明白其中一個的原理,,那其他22個線路原理也就知道了。

171 EXTI功能框圖

EXTI可分為兩大部分功能,一個是產生中斷,,另一個是產生事件,,這兩個功能從硬件上就有所不同。

首先我們來看圖 171中紅色虛線指示的電路流程,。它是一個產生中斷的線路,,最終信號流入到NVIC控制器內。

編號1是輸入線,,EXTI控制器有23個中斷/事件輸入線,,這些輸入線可以通過寄存器設置為任意一個GPIO,也可以是一些外設的事件,,這部分內容我們將在后面專門講解,。輸入線一般是存在電平變化的信號。

編號2是一個邊沿檢測電路,,它會根據上升沿觸發(fā)選擇寄存器(EXTI_RTSR)和下降沿觸發(fā)選擇寄存器(EXTI_FTSR)對應位的設置來控制信號觸發(fā),。邊沿檢測電路以輸入線作為信號輸入端,如果檢測到有邊沿跳變就輸出有效信號1給編號3電路,,否則輸出無效信號0,。而EXTI_RTSREXTI_FTSR兩個寄存器可以控制器需要檢測哪些類型的電平跳變過程,可以是只有上升沿觸發(fā),、只有下降沿觸發(fā)或者上升沿和下降沿都觸發(fā),。

編號3電路實際就是一個或門電路,它一個輸入來自編號2電路,,另外一輸入來自軟件中斷事件寄存器(EXTI_SWIER),。EXTI_SWIER允許我們通過程序控制就可以啟動中斷/事件線,這在某些地方非常有用,。我們知道或門的作用就是有"就為1,,所以這兩個輸入隨便一個有有效信號1就可以輸出1給編號4和編號6電路。

編號4電路是一個與門電路,,它一個輸入編號3電路,,另外一個輸入來自中斷屏蔽寄存器(EXTI_IMR)。與門電路要求輸入都為1才輸出1,,導致的結果如果EXTI_IMR設置為0時,,那不管編號3電路的輸出信號是1還是0,最終編號4電路輸出的信號都為0,;如果EXTI_IMR設置為1時,,最終編號4電路輸出的信號才由編號3電路的輸出信號決定,,這樣我們可以簡單的控制EXTI_IMR來實現是否產生中斷的目的,。編號4電路輸出的信號會被保存到掛起寄存器(EXTI_PR)內,如果確定編號4電路輸出為1就會把EXTI_PR對應位置1,。

編號5是將EXTI_PR寄存器內容輸出到NVIC內,,從而實現系統(tǒng)中斷事件控制,。

接下來我們來看看綠色虛線指示的電路流程。它是一個產生事件的線路,,最終輸出一個脈沖信號,。

產生事件線路是在編號3電路之后與中斷線路有所不同,之前電路都是共用的,。編號6電路是一個與門,,它一個輸入編號3電路,另外一個輸入來自事件屏蔽寄存器(EXTI_EMR),。如果EXTI_EMR設置為0時,,那不管編號3電路的輸出信號是1還是0,最終編號6電路輸出的信號都為0,;如果EXTI_EMR設置為1時,,最終編號6電路輸出的信號才由編號3電路的輸出信號決定,這樣我們可以簡單的控制EXTI_EMR來實現是否產生事件的目的,。

編號7是一個脈沖發(fā)生器電路,,當它的輸入端,即編號6電路的輸出端,,是一個有效信號1時就會產生一個脈沖,;如果輸入端是無效信號就不會輸出脈沖。

編號8是一個脈沖信號,,就是產生事件的線路最終的產物,,這個脈沖信號可以給其他外設電路使用,比如定時器TIM,、模擬數字轉換器ADC等等,。

產生中斷線路目的是把輸入信號輸入到NVIC,進一步會運行中斷服務函數,,實現功能,,這樣是軟件級的。而產生事件線路目的就是傳輸一個脈沖信號給其他外設使用,,并且是電路級別的信號傳輸,,屬于硬件級的。

另外,,EXTI是在APB2總線上的,,在編程時候需要注意到這點。

17.3 中斷/事件線

EXTI23個中斷/事件線,,每個GPIO都可以被設置為輸入線,,占用EXTI0EXTI15,還有另外七根用于特定的外設事件,見表 171,。

七根特定外設中斷/事件線由外設觸發(fā),,具體用法參考《STM32F4xx中文參考手冊》中對外設的具體說明。

171 EXTI中斷/事件線

中斷/事件線

輸入源

EXTI0

PX0(X可為A,B,C,D,E,F,G,H,I)

EXTI1

PX1(X可為A,B,C,D,E,F,G,H,I)

EXTI2

PX2(X可為A,B,C,D,E,F,G,H,I)

EXTI3

PX3(X可為A,B,C,D,E,F,G,H,I)

EXTI4

PX4(X可為A,B,C,D,E,F,G,H,I)

EXTI5

PX5(X可為A,B,C,D,E,F,G,H,I)

EXTI6

PX6(X可為A,B,C,D,E,F,G,H,I)

EXTI7

PX7(X可為A,B,C,D,E,F,G,H,I)

EXTI8

PX8(X可為A,B,C,D,E,F,G,H,I)

EXTI9

PX9(X可為A,B,C,D,E,F,G,H,I)

EXTI10

PX10(X可為A,B,C,D,E,F,G,H,I)

EXTI11

PX11(X可為A,B,C,D,E,F,G,H,I)

EXTI12

PX12(X可為A,B,C,D,E,F,G,H,I)

EXTI13

PX13(X可為A,B,C,D,E,F,G,H,I)

EXTI14

PX14(X可為A,B,C,D,E,F,G,H,I)

EXTI15

PX15(X可為A,B,C,D,E,F,G,H)

EXTI16

可編程電壓檢測器(PVD)輸出

EXTI17

RTC鬧鐘事件

EXTI18

USB OTG FS喚醒事件

EXTI19

以太網喚醒事件

EXTI20

USB OTG HS(FS中配置)喚醒事件

EXTI21

RTC入侵和時間戳事件

EXTI22

RTC喚醒事件

EXTI0EXTI15用于GPIO,,通過編程控制可以實現任意一個GPIO作為EXTI的輸入源,。由表 171可知,EXTI0可以通過SYSCFG外部中斷配置寄存器1(SYSCFG_EXTICR1)EXTI0[3:0]位選擇配置為PA0,、PB0,、PC0PD0,、PE0,、PF0PG0,、PH0或者PI0,,見圖 172。其他EXTI(EXTI中斷/事件線)使用配置都是類似的,。

172 EXTI0輸入源選擇

17.4 EXTI初始化結構體詳解

標準庫函數對每個外設都建立了一個初始化結構體,,比如EXTI_InitTypeDef,結構體成員用于設置外設工作參數,,并由外設初始化配置函數,,比如EXTI_Init()調用,這些設定參數將會設置外設相應的寄存器,,達到配置外設工作環(huán)境的目的,。

初始化結構體和初始化庫函數配合使用是標準庫精髓所在,理解了初始化結構體每個成員意義基本上就可以對該外設運用自如了,。初始化結構體定義在stm32f4xx_exti.h文件中,,初始化庫函數定義在stm32f4xx_exti.c文件中,編程時我們可以結合這兩個文件內注釋使用,。

代碼清單 171 EXTI初始化結構體

1 typedef struct {

2 uint32_t EXTI_Line; // 中斷/事件線

3 EXTIMode_TypeDef EXTI_Mode; // EXTI模式

4 EXTITrigger_TypeDef EXTI_Trigger; // 觸發(fā)事件

5 FunctionalState EXTI_LineCmd; // EXTI控制

6 } EXTI_InitTypeDef;

1)    EXTI_Line:EXTI中斷/事件線選擇,,可選EXTI0至EXTI22,可參考表 171選擇,。

2)    EXTI_Mode:EXTI模式選擇,,可選為產生中斷(EXTI_Mode_Interrupt)或者產生事件(EXTI_Mode_Event)。

3)    EXTI_Trigger:EXTI邊沿觸發(fā)事件,,可選上升沿觸發(fā)(EXTI_Trigger_Rising),、下降沿觸發(fā)( EXTI_Trigger_Falling)或者上升沿和下降沿都觸發(fā)( EXTI_Trigger_Rising_Falling)。

4)    EXTI_LineCmd:控制是否使能EXTI線,,可選使能EXTI線(ENABLE)或禁用(DISABLE),。

17.5 外部中斷控制實驗

中斷在嵌入式應用中占有非常重要的地位,,幾乎每個控制器都有中斷功能。中斷對保證緊急事件得到第一時間處理是非常重要的

我們設計使用外接的按鍵來作為觸發(fā)源,,使得控制器產生中斷,,并在中斷服務函數中實現控制RGB彩燈的任務,。

17.5.1 硬件設計

輕觸按鍵在按下時會使得引腳接通,,通過電路設計可以使得按下時產生電平變化,見圖 171,。

173 按鍵電路設計

17.5.2 軟件設計

這里只講解核心的部分代碼,,有些變量的設置,頭文件的包含等并沒有涉及到,,完整的代碼請參考本章配套的工程,。我們創(chuàng)建了兩個文件:bsp_exti.cbsp_exti.h文件用來存放EXTI驅動程序及相關宏定義,中斷服務函數放在stm32f4xx_it.h文件中,。

1.    編程要點

1)    初始化RGB彩燈的GPIO,;

2)    開啟按鍵GPIO時鐘和SYSCFG時鐘;

3)    配置NVIC,;

4)    配置按鍵GPIO為輸入模式,;

5)    將按鍵GPIO連接到EXTI源輸入;

6)    配置按鍵EXTI中斷/事件線,;

7)    編寫EXTI中斷服務函數,。

2.    軟件分析
按鍵和EXTI宏定義

代碼清單 172 按鍵和EXTI 宏定義

1 //引腳定義

2 /*******************************************************/

3 #define KEY1_INT_GPIO_PORT GPIOA

4 #define KEY1_INT_GPIO_CLK RCC_AHB1Periph_GPIOA

5 #define KEY1_INT_GPIO_PIN GPIO_Pin_0

6 #define KEY1_INT_EXTI_PORTSOURCE EXTI_PortSourceGPIOA

7 #define KEY1_INT_EXTI_PINSOURCE EXTI_PinSource0

8 #define KEY1_INT_EXTI_LINE EXTI_Line0

9 #define KEY1_INT_EXTI_IRQ EXTI0_IRQn

10

11 #define KEY1_IRQHandler EXTI0_IRQHandler

12

13 #define KEY2_INT_GPIO_PORT GPIOC

14 #define KEY2_INT_GPIO_CLK RCC_AHB1Periph_GPIOC

15 #define KEY2_INT_GPIO_PIN GPIO_Pin_13

16 #define KEY2_INT_EXTI_PORTSOURCE EXTI_PortSourceGPIOC

17 #define KEY2_INT_EXTI_PINSOURCE EXTI_PinSource13

18 #define KEY2_INT_EXTI_LINE EXTI_Line13

19 #define KEY2_INT_EXTI_IRQ EXTI15_10_IRQn

20

21 #define KEY2_IRQHandler EXTI15_10_IRQHandler

使用宏定義方法指定與電路設計相關配置,這對于程序移植或升級非常有用的,。

嵌套向量中斷控制器NVIC配置

代碼清單 173 NVIC配置

1 static void NVIC_Configuration(void)

2 {

3 NVIC_InitTypeDef NVIC_InitStructure;

4

5 /* 配置NVIC為優(yōu)先級組1 */

6 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

7

8 /* 配置中斷源:按鍵1 */

9 NVIC_InitStructure.NVIC_IRQChannel = KEY1_INT_EXTI_IRQ;

10 /* 配置搶占優(yōu)先級:1 */

11 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

12 /* 配置子優(yōu)先級:1 */

13 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

14 /* 使能中斷通道 */

15 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

16 NVIC_Init(&NVIC_InitStructure);

17

18 /* 配置中斷源:按鍵2,,其他使用上面相關配置 */

19 NVIC_InitStructure.NVIC_IRQChannel = KEY2_INT_EXTI_IRQ;

20 NVIC_Init(&NVIC_InitStructure);

21 }

有關NVIC配置問題可參考上一章節(jié)內容,這里不做過多解釋,。

EXTI中斷配置

代碼清單 174 EXTI中斷配置

1 void EXTI_Key_Config(void)

2 {

3 GPIO_InitTypeDef GPIO_InitStructure;

4 EXTI_InitTypeDef EXTI_InitStructure;

5

6 /*開啟按鍵GPIO口的時鐘*/

7 RCC_AHB1PeriphClockCmd(KEY1_INT_GPIO_CLK|KEY2_INT_GPIO_CLK ,ENABLE);

8

9 /* 使能 SYSCFG 時鐘,,使用GPIO外部中斷時必須使能SYSCFG時鐘*/

10 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

11

12 /* 配置 NVIC */

13 NVIC_Configuration();

14

15 /* 選擇按鍵1的引腳 */

16 GPIO_InitStructure.GPIO_Pin = KEY1_INT_GPIO_PIN;

17 /* 設置引腳為輸入模式 */

18 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;

19 /* 設置引腳不上拉也不下拉 */

20 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

21 /* 使用上面的結構體初始化按鍵 */

22 GPIO_Init(KEY1_INT_GPIO_PORT, &GPIO_InitStructure);

23

24 /* 連接 EXTI 中斷源key1引腳 */

25 SYSCFG_EXTILineConfig(KEY1_INT_EXTI_PORTSOURCE,

26 KEY1_INT_EXTI_PINSOURCE);

27

28 /* 選擇 EXTI 中斷源 */

29 EXTI_InitStructure.EXTI_Line = KEY1_INT_EXTI_LINE;

30 /* 中斷模式 */

31 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

32 /* 下降沿觸發(fā) */

33 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;

34 /* 使能中斷/事件線 */

35 EXTI_InitStructure.EXTI_LineCmd = ENABLE;

36 EXTI_Init(&EXTI_InitStructure);

37

38 /* 選擇按鍵2的引腳 */

39 GPIO_InitStructure.GPIO_Pin = KEY2_INT_GPIO_PIN;

40 /* 其他配置與上面相同 */

41 GPIO_Init(KEY2_INT_GPIO_PORT, &GPIO_InitStructure);

42

43 /* 連接 EXTI 中斷源key2 引腳 */

44 SYSCFG_EXTILineConfig(KEY2_INT_EXTI_PORTSOURCE,

45 KEY2_INT_EXTI_PINSOURCE);

46

47 /* 選擇 EXTI 中斷源 */

48 EXTI_InitStructure.EXTI_Line = KEY2_INT_EXTI_LINE;

49 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

50 /* 上升沿觸發(fā) */

51 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;

52 EXTI_InitStructure.EXTI_LineCmd = ENABLE;

53 EXTI_Init(&EXTI_InitStructure);

54 }

首先,使用GPIO_InitTypeDefEXTI_InitTypeDef結構體定義兩個用于GPIOEXTI初始化配置的變量,,關于這兩個結構體前面都已經做了詳細的講解,。

使用GPIO之前必須開啟GPIO端口的時鐘;用到EXTI必須開啟SYSCFG時鐘,。

調用NVIC_Configuration函數完成對按鍵1,、按鍵2優(yōu)先級配置并使能中斷通道,。

作為中斷/時間輸入線把GPIO配置為輸入模式,這里不使用上拉或下拉,有外部電路完全決定引腳的狀態(tài),。

SYSCFG_EXTILineConfig函數用來指定中斷/事件線的輸入源,它實際是設定SYSCFG外部中斷配置寄存器的值,,該函數接收兩個參數,,第一個參數指定GPIO端口源,,第二個參數為選擇對應GPIO引腳源編號。

我們的目的是產生中斷,,執(zhí)行中斷服務函數,,EXTI選擇中斷模式,按鍵1使用下降沿觸發(fā)方式,,并使能EXTI線,。

按鍵2基本上采用與按鍵1相關參數配置,只是改為上升沿觸發(fā)方式,。

EXTI中斷服務函數

代碼清單 175 EXTI中斷服務函數

1 void KEY1_IRQHandler(void)

2 {

3 //確保是否產生了EXTI Line中斷

4 if (EXTI_GetITStatus(KEY1_INT_EXTI_LINE) != RESET) {

5 // LED1 取反

6 LED1_TOGGLE;

7 //清除中斷標志位

8 EXTI_ClearITPendingBit(KEY1_INT_EXTI_LINE);

9 }

10 }

11

12 void KEY2_IRQHandler(void)

13 {

14 //確保是否產生了EXTI Line中斷

15 if (EXTI_GetITStatus(KEY2_INT_EXTI_LINE) != RESET) {

16 // LED2 取反

17 LED2_TOGGLE;

18 //清除中斷標志位

19 EXTI_ClearITPendingBit(KEY2_INT_EXTI_LINE);

20 }

21 }

當中斷發(fā)生時,,對應的中斷服務函數就會被執(zhí)行,我們可以在中斷服務函數實現一些控制,。

一般為確保中斷確實發(fā)生,,我們會在中斷服務函數調用中斷標志位狀態(tài)讀取函數讀取外設中斷標志位并判斷標志位狀態(tài)。

EXTI_GetITStatus函數用來獲取EXTI的中斷標志位狀態(tài),,如果EXTI線有中斷發(fā)生函數返回"SET"否則返回"RESET",。實際上,EXTI_GetITStatus函數是通過讀取EXTI_PR寄存器值來判斷EXTI線狀態(tài)的,。

按鍵1的中斷服務函數我們讓LED1翻轉其狀態(tài),,按鍵2的中斷服務函數我們讓LED2翻轉其狀態(tài)。執(zhí)行任務后需要調用EXTI_ClearITPendingBit函數清除EXTI線的中斷標志位,。

主函數

代碼清單 176 主函數

1 int main(void)

2 {

3 /* LED 端口初始化 */

4 LED_GPIO_Config();

5

6 /* 初始化EXTI中斷,,按下按鍵會觸發(fā)中斷,

7 * 觸發(fā)中斷會進入stm32f4xx_it.c文件中的函數

8 * KEY1_IRQHandlerKEY2_IRQHandler,,處理中斷,,反轉LED燈。

9 */

10 EXTI_Key_Config();

11

12 /* 等待中斷,,由于使用中斷方式,,CPU不用輪詢按鍵 */

13 while (1) {

14 }

15 }

主函數非常簡單,只有兩個任務函數,。LED_GPIO_Config函數定義在bsp_led.c文件內,,完成RGB彩燈的GPIO初始化配置。EXTI_Key_Config函數完成兩個按鍵的GPIOEXTI配置,。

17.5.3 下載驗證

保證開發(fā)板相關硬件連接正確,,把編譯好的程序下載到開發(fā)板。此時RGB彩色燈是暗的,,如果我們按下開發(fā)板上的按鍵1,,RGB彩燈變亮,再按下按鍵1,,RGB彩燈又變暗,;如果我們按下開發(fā)板上的按鍵2并彈開,,RGB彩燈變亮,再按下開發(fā)板上的KEY2并彈開,,RGB彩燈又變暗,。

每課一問

1、    是否可以同時使用PA0和PB0中斷,?如果不可以,,有什么解決方法。

2,、    從硬件角度結合程序分析,,為什么按下按鍵1RGB彩燈就馬上變化,,而按鍵2卻需要按下按鍵再彈開之后RGB彩燈才變化,?

    本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,,不代表本站觀點,。請注意甄別內容中的聯系方式、誘導購買等信息,,謹防詐騙,。如發(fā)現有害或侵權內容,請點擊一鍵舉報,。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多