STM32F1迷你板外部中断
開始學習外部中斷的基本知識
中斷優(yōu)先級分組管理
CortexM3內(nèi)部支持256個中斷,其中包含了 16 個內(nèi)核中斷和 240 個外部中斷,并且具有 256
級的可編程中斷設(shè)置。STM32F1系列有 84 個中斷,包括 16 個內(nèi)核中斷和 68 個可屏蔽中斷,具有 16 級可編程的中斷優(yōu)先級。而我們常用的就是這 68 個可屏蔽中斷, 但是 STM32 的 68 個可屏蔽中斷,在 STM32F103 系列
上面,可屏蔽中斷又只有 60 個(在 107 系列才有 68 個)。
中斷管理辦法:
首先,對STM32中斷進行分組,分成5個組:組0~4,該分組的設(shè)置是由 SCB->AIRCR 寄存器的 bit10~8 來定義的。 同時,對每個中斷設(shè)置一個搶占優(yōu)先級和一個響應(yīng)優(yōu)先級。
有4個位來分配搶占優(yōu)先級和響應(yīng)優(yōu)先級。
下面是AIRCR 中斷分組設(shè)置表
| 0 | 111 | 0: 4 | 0 位搶占優(yōu)先級, 4 位響應(yīng)優(yōu)先級 |
| 1 | 110 | 1: 3 | 1 位搶占優(yōu)先級, 3 位響應(yīng)優(yōu)先級 |
| 2 | 101 | 2: 2 | 2 位搶占優(yōu)先級, 2 位響應(yīng)優(yōu)先級 |
| 3 | 100 | 3: 1 | 3 位搶占優(yōu)先級, 1 位響應(yīng)優(yōu)先級 |
| 4 | 011 | 4: 0 | 4 位搶占優(yōu)先級, 0 位響應(yīng)優(yōu)先級 |
每個中斷,可以設(shè)置搶占優(yōu)先級為 0~7,響應(yīng)優(yōu)先級為 1 或 0。搶占優(yōu)先級的級別高于響應(yīng)優(yōu)先級。而數(shù)值越小所代表的優(yōu)先級就越高。搶占優(yōu)先級相同的中斷,當兩個中斷同時發(fā)生,哪個響應(yīng)優(yōu)先級高,哪個先執(zhí)行。
這里需要注意兩點:第一,如果兩個中斷的搶占優(yōu)先級和響應(yīng)優(yōu)先級都是一樣的話,則看哪個中斷先發(fā)生就先執(zhí)行;第二,高優(yōu)先級的搶占優(yōu)先級是可以打斷正在進行的低搶占優(yōu)先級中斷的。而搶占優(yōu)先級相同的中斷,高優(yōu)先級的響應(yīng)優(yōu)先級不可以打斷低響應(yīng)優(yōu)先級的中斷。
中斷優(yōu)先級分組設(shè)置函數(shù)NVIC_PriorityGroupConfig
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup) {assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup; }分組可以在下面選
(((GROUP) == NVIC_PriorityGroup_0) || ((GROUP) == NVIC_PriorityGroup_1) || \ ((GROUP) == NVIC_PriorityGroup_2) || \ ((GROUP) == NVIC_PriorityGroup_3) || \ ((GROUP) == NVIC_PriorityGroup_4))設(shè)置好了系統(tǒng)中斷分組,那么對于每個中斷我們又怎么確定他的搶占優(yōu)先級和響應(yīng)優(yōu)先級呢?通過中斷初始化函數(shù)void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)
解析一下上式用到的結(jié)構(gòu)體NVIC_InitTypeDef
typedef struct { uint8_t NVIC_IRQChannel; uint8_t NVIC_IRQChannelPreemptionPriority; uint8_t NVIC_IRQChannelSubPriority; FunctionalState NVIC_IRQChannelCmd; } NVIC_InitTypeDef;成員變量的含義
NVIC_InitTypeDef 結(jié)構(gòu)體中間有三個成員變量,這三個成員變量的作用是:
NVIC_IRQChannel:定義初始化的是哪個中斷,這個我們可以在 stm32f10x.h 中找到每個中斷對應(yīng)的名字。例如 USART1_IRQn。
NVIC_IRQChannelPreemptionPriority:定義這個中斷的搶占優(yōu)先級別。
NVIC_IRQChannelSubPriority:定義這個中斷的子優(yōu)先級別。
NVIC_IRQChannelCmd:該中斷是否使能。
比如我們要使能串口 1 的中斷,同時設(shè)置搶占優(yōu)先級為 1,子優(yōu)先級位 2,初始化的方法是
NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口 1 中斷 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;// 搶占優(yōu)先級為 1 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;// 子優(yōu)先級位 2 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ 通道使能 NVIC_Init(&NVIC_InitStructure); //根據(jù)上面指定的參數(shù)初始化 NVIC 寄存器NVIC 寄存器結(jié)構(gòu)體NVIC_Type
typedef struct {__IO uint32_t ISER[8]; /*!< Interrupt Set Enable Register */uint32_t RESERVED0[24];__IO uint32_t ICER[8]; /*!< Interrupt Clear Enable Register */uint32_t RSERVED1[24];__IO uint32_t ISPR[8]; /*!< Interrupt Set Pending Register */uint32_t RESERVED2[24];__IO uint32_t ICPR[8]; /*!< Interrupt Clear Pending Register */uint32_t RESERVED3[24];__IO uint32_t IABR[8]; /*!< Interrupt Active bit Register */uint32_t RESERVED4[56];__IO uint8_t IP[240]; /*!< Interrupt Priority Register, 8Bit wide */uint32_t RESERVED5[644];__O uint32_t STIR; /*!< Software Trigger Interrupt Register */ } NVIC_Type;外部中斷
STM32每一個IO口都可以作為外部中斷輸入。
STM32的中斷控制器支持19個外部中斷/事件請求。
線0~15:對應(yīng)外部IO口的輸入中斷
每個外部中斷線可以獨立配置觸發(fā)方式(上升沿,下降沿或者雙邊沿觸發(fā)),觸發(fā)/屏蔽,專用的狀態(tài)位。
GPIO的管腳和中斷線有一個對應(yīng)關(guān)系,每個中斷線最多對應(yīng)7個IO口。以線0為例,它對應(yīng)了GPIOA.0,GPIOB.0,GPIOC.0,GPIOD.0,GPIOE.0,GPIOF.0,GPIOG.0。中斷線每次只能連接到一個IO口,所以需要在7個IO口中進行選擇。
映射關(guān)系
圖片來源:正點原子
外部中斷的一般配置步驟
初始化IO口為輸入GPIO_Init()
開啟IO口復用時鐘RCC_APB2PeriphClockCmd(RCC_APB2Perith_AFIO,ENABLE);
設(shè)置IO口與中斷線的映射關(guān)系void GPIO_EXTILineConfig()
初始化線上中斷,設(shè)置觸發(fā)條件等EXTI_Init()
配置中斷分組(NVIC),并使能中斷NVIC_Init()
編寫中斷服務(wù)程序EXTIx_IRQHandler()
清除中斷標志位EXTI_ClearTPendingBit()
IO口和中斷線的映射
在庫函數(shù)中,配置 GPIO 與中斷線的映射關(guān)系的函數(shù) GPIO_EXTILineConfig()來實現(xiàn)的:
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource)
該函數(shù)將 GPIO 端口與中斷線映射起來,使用范例是:
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);
將中斷線 2 與 GPIOE 映射起來,即GPIOE.2 與 EXTI2 中斷線連接了。我們要是用的是PE4(對應(yīng)的是KEY0),所以這里是
然后我們對中斷進行初始化
//初始化中斷EXTI_InitStructure.EXTI_Line=EXTI_Line4;//線號EXTI_InitStructure.EXTI_LineCmd=ENABLE;//使能EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;//中斷還是事件EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;//下降沿觸發(fā)EXTI_Init(&EXTI_InitStructure);這里筆者有個問題?這里為什么選擇下降沿觸發(fā)呢?原來是因為KEY0接的是低電平,所以讓它有效的話,必須是到低電平。
配置中斷分組NVIC
//NVIC中斷分組的設(shè)置NVIC_InitStructure.NVIC_IRQChannel=EXTI4_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE:NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;NVIC_Init(&NVIC_InitStructure);前五步的初始化函數(shù)如下
void EXITX_Init(){EXTI_InitTypeDef EXTI_InitStructure;//結(jié)構(gòu)體變量NVIC_InitTypeDef NVIC_InitStructure;KEY_Init();//初始化GPIORCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//key0對應(yīng)PE4//PE4映射到中斷線4GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource4 );//初始化中斷EXTI_InitStructure.EXTI_Line=EXTI_Line4;//線號EXTI_InitStructure.EXTI_LineCmd=ENABLE;EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;//中斷EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;//下降沿觸發(fā)EXTI_Init(&EXTI_InitStructure);//NVIC中斷分組的設(shè)置NVIC_InitStructure.NVIC_IRQChannel=EXTI4_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE:NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;NVIC_Init(&NVIC_InitStructure);}總結(jié)
以上是生活随笔為你收集整理的STM32F1迷你板外部中断的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: VS2019中配置opencv4.3.0
- 下一篇: 奶茶涨价了 利润那么却还要涨价的原因