stm32 NVIC EXTI
stm32 NVIC EXTI
- NVIC
- EXTI
- 原理圖
- main.c
- exti.h
- exti.c
- stm32f10x_it.c
NVIC
NVIC 是嵌套向量中斷控制器,控制著整個(gè)芯片中斷相關(guān)的功能,它跟內(nèi)核緊密耦合,是內(nèi)核里面的一個(gè)外設(shè)。配置中斷的時(shí)候我們一般只用 ISER、ICER 和 IP 這三個(gè)寄存器,ISER 用來使能中斷,ICER 用來失能中斷,IP用來設(shè)置中斷優(yōu)先級(jí)。NVIC 結(jié)構(gòu)體定義如下。
typedef struct {__IO uint32_t ISER[8]; /*!< Offset: 0x000 Interrupt Set Enable Register */uint32_t RESERVED0[24]; __IO uint32_t ICER[8]; /*!< Offset: 0x080 Interrupt Clear Enable Register */uint32_t RSERVED1[24]; __IO uint32_t ISPR[8]; /*!< Offset: 0x100 Interrupt Set Pending Register */uint32_t RESERVED2[24]; __IO uint32_t ICPR[8]; /*!< Offset: 0x180 Interrupt Clear Pending Register */uint32_t RESERVED3[24]; __IO uint32_t IABR[8]; /*!< Offset: 0x200 Interrupt Active bit Register */uint32_t RESERVED4[56]; __IO uint8_t IP[240]; /*!< Offset: 0x300 Interrupt Priority Register (8Bit wide) */uint32_t RESERVED5[644]; __O uint32_t STIR; /*!< Offset: 0xE00 Software Trigger Interrupt Register */ } NVIC_Type;中斷編程:
1、使能外設(shè)某個(gè)中斷,具體哪個(gè)中斷,由每個(gè)外設(shè)的相關(guān)中斷使能位控制。比如串口有發(fā)送完成中斷,接收完成中斷,這兩個(gè)中斷都由串口控制寄存器的相關(guān)中斷使能位控制。
2、初始化 NVIC_InitTypeDef 結(jié)構(gòu)體,配置中斷優(yōu)先級(jí)分組,設(shè)置搶占優(yōu)先級(jí)和子優(yōu)先級(jí),使能中斷請(qǐng)求。NVIC_InitTypeDef 結(jié)構(gòu)體在固件庫(kù)頭文件 misc.h 中定義,如下。
typedef struct {uint8_t NVIC_IRQChannel; //中斷源 uint8_t NVIC_IRQChannelPreemptionPriority; //搶占優(yōu)先級(jí)uint8_t NVIC_IRQChannelSubPriority; //子優(yōu)先級(jí)FunctionalState NVIC_IRQChannelCmd; //中斷使能或失能 } NVIC_InitTypeDef;中斷源:stm32f10x.h 頭文件里面的 IRQn_Type 結(jié)構(gòu)體包含了所有的中斷源。
搶占優(yōu)先級(jí)和子優(yōu)先級(jí):具體值要根據(jù)優(yōu)先級(jí)分組設(shè)定。
中斷使能或失能:操作的是 NVIC_ISER 和 NVIC_ICER 這兩個(gè)寄存器。
3、編寫中斷服務(wù)函數(shù)
在啟動(dòng)文件 startup_stm32f10x_hd.s 中預(yù)先為每個(gè)中斷都寫了一個(gè)中斷服務(wù)函數(shù), 只是這些中斷函數(shù)都是為空,為的只是初始化中斷向量表。
實(shí)際的中斷服務(wù)函數(shù)都需要重新編寫,這里把中斷服務(wù)函數(shù)統(tǒng)一寫在 stm32f10x_it.c 文件中。
關(guān)于中斷服務(wù)函數(shù)的函數(shù)名必須跟啟動(dòng)文件里面預(yù)先設(shè)置的一樣,如果寫錯(cuò),系統(tǒng)就在中斷向量表中找不到中斷服務(wù)函數(shù)的入口,直接跳轉(zhuǎn)到啟動(dòng)文件里面預(yù)先寫好的空函數(shù), 并且在里面無限循環(huán),實(shí)現(xiàn)不了中斷。
EXTI
EXTI:外部中斷/事件控制器
原理圖
代碼編寫流程:初始化用來產(chǎn)生中斷的 GPIO;初始化 EXTI; 配置 NVIC; 編寫中斷服務(wù)函數(shù);
main.c
效果就是按下按鍵1,燈亮,因?yàn)槭巧仙赜|發(fā)。按下按鍵2,燈不亮,按鍵松開,燈亮,因?yàn)槭窍陆笛赜|發(fā)。
#include "stm32f10x.h" #include "bsp_led.h" #include "bsp_exti.h" /*** @brief 主函數(shù)* @param 無* @retval 無*/ int main(void) {/* LED GPIO初始化 */LED_GPIO_Config();/* 初始化EXTI中斷,按下按鍵會(huì)觸發(fā)中斷,* 觸發(fā)中斷會(huì)進(jìn)入stm32f4xx_it.c文件中的函數(shù)* KEY1_IRQHandler和KEY2_IRQHandler,處理中斷,反轉(zhuǎn)LED燈。*/EXTI_Key_Config(); /*進(jìn)行成兩個(gè)按鍵的 GPIO 和 EXTI配置。/* 等待中斷,由于使用中斷方式,CPU不用輪詢按鍵 */while(1) {} }exti.h
里面是按鍵和 EXTI 的宏定義。
#ifndef __EXTI_H #define __EXTI_H#include "stm32f10x.h"//引腳定義 #define KEY1_INT_GPIO_PORT GPIOA #define KEY1_INT_GPIO_CLK (RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO) #define KEY1_INT_GPIO_PIN GPIO_Pin_0 #define KEY1_INT_EXTI_PORTSOURCE GPIO_PortSourceGPIOA #define KEY1_INT_EXTI_PINSOURCE GPIO_PinSource0 #define KEY1_INT_EXTI_LINE EXTI_Line0 #define KEY1_INT_EXTI_IRQ EXTI0_IRQn#define KEY1_IRQHandler EXTI0_IRQHandler#define KEY2_INT_GPIO_PORT GPIOC #define KEY2_INT_GPIO_CLK (RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO) #define KEY2_INT_GPIO_PIN GPIO_Pin_13 #define KEY2_INT_EXTI_PORTSOURCE GPIO_PortSourceGPIOC #define KEY2_INT_EXTI_PINSOURCE GPIO_PinSource13 #define KEY2_INT_EXTI_LINE EXTI_Line13 #define KEY2_INT_EXTI_IRQ EXTI15_10_IRQn#define KEY2_IRQHandler EXTI15_10_IRQHandlervoid EXTI_Key_Config(void);#endif /* __EXTI_H */exti.c
里面有配置嵌套向量中斷控制器NVIC的函數(shù)、配置EXTI中斷的函數(shù)。
#include "bsp_exti.h"/*** @brief 配置嵌套向量中斷控制器NVIC* @param 無* @retval 無*/ static void NVIC_Configuration(void) {NVIC_InitTypeDef NVIC_InitStructure;/* 配置NVIC為優(yōu)先級(jí)組1 */NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);/* 配置中斷源:按鍵1 */NVIC_InitStructure.NVIC_IRQChannel = KEY1_INT_EXTI_IRQ;/* 配置搶占優(yōu)先級(jí) */NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;/* 配置子優(yōu)先級(jí) */NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;/* 使能中斷通道 */NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);/* 配置中斷源:按鍵2,其他使用上面相關(guān)配置 */ NVIC_InitStructure.NVIC_IRQChannel = KEY2_INT_EXTI_IRQ;NVIC_Init(&NVIC_InitStructure); }/*** @brief 配置 IO為EXTI中斷口,并設(shè)置中斷優(yōu)先級(jí)* @param 無* @retval 無*/ void EXTI_Key_Config(void) {GPIO_InitTypeDef GPIO_InitStructure; EXTI_InitTypeDef EXTI_InitStructure;/*開啟按鍵GPIO口的時(shí)鐘*/RCC_APB2PeriphClockCmd(KEY1_INT_GPIO_CLK,ENABLE);RCC_APB2PeriphClockCmd(KEY2_INT_GPIO_CLK,ENABLE);/* 配置 NVIC 中斷*/NVIC_Configuration();/*--------------------------KEY1配置-----------------------------*//* 選擇按鍵用到的GPIO */ GPIO_InitStructure.GPIO_Pin = KEY1_INT_GPIO_PIN;/* 配置為浮空輸入 */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(KEY1_INT_GPIO_PORT, &GPIO_InitStructure);/* 選擇EXTI的信號(hào)源 */GPIO_EXTILineConfig(KEY1_INT_EXTI_PORTSOURCE, KEY1_INT_EXTI_PINSOURCE); EXTI_InitStructure.EXTI_Line = KEY1_INT_EXTI_LINE;/* EXTI為中斷模式 */EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;/* 上升沿中斷 */EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;/* 使能中斷 */ EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure);/*--------------------------KEY2配置-----------------------------*//* 選擇按鍵用到的GPIO */ GPIO_InitStructure.GPIO_Pin = KEY2_INT_GPIO_PIN;/* 配置為浮空輸入 */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(KEY2_INT_GPIO_PORT, &GPIO_InitStructure);/* 選擇EXTI的信號(hào)源 */GPIO_EXTILineConfig(KEY2_INT_EXTI_PORTSOURCE, KEY2_INT_EXTI_PINSOURCE); EXTI_InitStructure.EXTI_Line = KEY2_INT_EXTI_LINE;/* EXTI為中斷模式 */EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;/* 下降沿中斷 */EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;/* 使能中斷 */ EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure); } /*********************************************END OF FILE**********************/里面配置KEY1是根據(jù)EXTI_InitTypeDef這個(gè)結(jié)構(gòu)體來的,在stm32f10x_exti.h 文件中。
typedef struct {uint32_t EXTI_Line; EXTIMode_TypeDef EXTI_Mode; EXTITrigger_TypeDef EXTI_Trigger; FunctionalState EXTI_LineCmd; }EXTI_InitTypeDef;stm32f10x_it.c
里面是EXTI 中斷服務(wù)函數(shù),中斷發(fā)生時(shí),對(duì)應(yīng)的中斷服務(wù)函數(shù)就會(huì)被執(zhí)行。
#include "stm32f10x_it.h" #include "bsp_led.h" #include "bsp_exti.h"void KEY1_IRQHandler(void) {//確保是否產(chǎn)生了EXTI Line中斷if(EXTI_GetITStatus(KEY1_INT_EXTI_LINE) != RESET) {// LED1 取反 LED1_TOGGLE;//清除中斷標(biāo)志位EXTI_ClearITPendingBit(KEY1_INT_EXTI_LINE); } }void KEY2_IRQHandler(void) {//確保是否產(chǎn)生了EXTI Line中斷if(EXTI_GetITStatus(KEY2_INT_EXTI_LINE) != RESET) {// LED2 取反 LED2_TOGGLE;//清除中斷標(biāo)志位EXTI_ClearITPendingBit(KEY2_INT_EXTI_LINE); } }總結(jié)
以上是生活随笔為你收集整理的stm32 NVIC EXTI的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux中cooy命令_Linux:C
- 下一篇: 可以获得索引值码_SEO优化细节,怎样优