赞
踩
目录
NVIC被称为做嵌套中断向量控制器,其作用是统一分配中断优先级和管理中断的。
NVIC的中断优先级由优先级寄存器的4位(0~15)决定,这4位可以进行切分,分为高n位的抢占优先级和低4-n位的响应优先级 。抢占优先级高的可以中断嵌套,响应优先级高的可以优先排队,抢占优先级和响应优先级均相同的按中断号排队 。
抢占优先级:抢占优先级高的中断,可以在CPU暂停处理当前中断,转而处理抢占优先级较高的中断事件,处理完抢占优先级较高的中断事件后,继续处理之前暂停的中断。
优先级和响应优先级均相同:按以下表格中的中断顺序排队。
第四点中, 但相同的Pin不能同时触发中断,即PA0 与PB0等不可同时使用。
AFIO是选择开启需要GPIOx引脚。对应1.2、中的第四点,相同的Pin不能同时触发中断,即PA0 与PB0等不可同时使用。因为选择GPIOA后无法再使其他GPIOx口的引脚信号输入。
引脚5-9、引脚10-15共用一个中断函数。
在STM32中,AFIO主要完成两个任务:复用功能引脚重映射、中断引脚选择。
上图为硬件线路接线。
我们要配置中断函数就需要知道我们需要配置那些外设。下图可以清晰的了解我们需要配置的外设
此时,我选择的红外连接在GPIOB--14引脚,所以我需要配置外设GPIOB的时钟信号,而AFIO在图一中也是必不可少的,所以我们还需要配置AFIO外设。由于EXTI由MVIC模块直接控制,是默认开启时钟的,所以并不需要单独设置。以下就是我们的配置代码
- uint8_t CountSensor_Init()
- {
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
-
- //开启外设AFIO时钟 EXTI由MVIC模块直接控制,并不需要单独外设
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
-
- GPIO_InitTypeDef GPIO_InitStruct;
- //上拉输入,高电平输入;不知道配置什么模式,可以查看芯片手册
- GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
-
- GPIO_InitStruct.GPIO_Pin=GPIO_Pin_14;
- GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
- }
2.1.2、选择用作EXTI线的GPIO引脚
即选择哪个GPIO口作为EXTI输入
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14);
- EXTI_InitTypeDef EXTI_InitStructure;
- EXTI_InitStructure.EXTI_Line=EXTI_Line14;
- EXTI_InitStructure.EXTI_LineCmd=ENABLE;
- EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
- EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising;
- EXTI_Init(&EXTI_InitStructure);
【1】EXTI_Line: 指定要启用或禁用的EXTI行。
【2】EXTI_LineCmd:指定选定EXTI线的新状态。
【3】EXTI_Mode:指定EXTI线的模式。即选择事件模式还是中断模式。事件模式一般是外设与外设的联系。
【4】EXTI_Trigger:指定EXTI线的触发信号激活边缘模式。即是继续上升沿、下降沿还是其他边沿触发。
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
-
- NVIC_InitTypeDef NVIC_InitStructure;
- NVIC_InitStructure.NVIC_IRQChannel=EXTI15_10_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
- NVIC_Init(&NVIC_InitStructure);
【1】 NVIC_PriorityGroupConfig()://配置优先级分组:抢占优先级和次优先级。
【2】NVIC_IRQChannel:指定要启用或禁用的IRQ通道。即选择图中黄色框选进入NVIC的通道。为节省资源在该系列中引脚10-15、引脚5-9共用一个通道。本例中使用的是14引脚,因此使用EXTI15_10_IRQn。
【3】NVIC_IRQChannelCmd:指定在NVIC_IRQChannel中定义的IRQ通道将被启用或禁用。即选择禁用或启用【2】中选中的通道。本例中是启用 。
【4】NVIC_IRQChannelPreemptionPriority:指定NVIC_IRQChannel中指定的IRQ信道的抢占优先级。
【5】NVIC_IRQChannelSubPriority:指定NVIC_IRQChannel中指定的IRQ通道的响应优先级级别。由于本例子中并无太多中断,因此可以【4】【5】自行选择。
在STM32里,中断函数的名字都是固定的,需要在启动文件 startup_stm32f10x_md.s 中找到对应的函数名字,由于本例程中使用的NVIC_IRQChannel 通道为 EXTI15_10_IRQn,因此使用的中断函数名称应为 EXTI15_10_IRQHandler。
- uint16_t CountSensor_Get(void) //返回计次值
- {
- return CountSensor_Count;
- }
-
- void EXTI15_10_IRQHandler()
- {
- if(EXTI_GetITStatus(EXTI_Line14)==SET)
- {
- CountSensor_Count++; //计次
- Delay_ms(200); //消除抖动
- EXTI_ClearITPendingBit(EXTI_Line14);
- }
- }
- #include "stm32f10x.h" // Device header
- #include "Delay.h"
-
- uint16_t CountSensor_Count;
-
- void CountSensor_Init(void)
- {
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //开启外设AFIO时钟 EXTI由MVIC模块直接控制,并不需要单独外设
-
- GPIO_InitTypeDef GPIO_InitStructure;
- GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU; //上拉输入,高电平输入
- GPIO_InitStructure.GPIO_Pin=GPIO_Pin_14;
- GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
- GPIO_Init(GPIOB,&GPIO_InitStructure);
-
- GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14);
-
- EXTI_InitTypeDef EXTI_InitStructure;
- EXTI_InitStructure.EXTI_Line=EXTI_Line14;
- EXTI_InitStructure.EXTI_LineCmd=ENABLE;
- EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
- EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising; // EXTI_Trigger_Falling 下降沿触发 /EXTI_Trigger_Rising 上升沿触发
- EXTI_Init(&EXTI_InitStructure);
-
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
-
- NVIC_InitTypeDef NVIC_InitStructure;
- NVIC_InitStructure.NVIC_IRQChannel=EXTI15_10_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
- NVIC_Init(&NVIC_InitStructure);
- }
-
- uint16_t CountSensor_Get(void) //返回计次值
- {
- return CountSensor_Count;
- }
-
- void EXTI15_10_IRQHandler()
- {
- if(EXTI_GetITStatus(EXTI_Line14)==SET)
- {
- CountSensor_Count++; //计次
- Delay_ms(200); //消除抖动
- EXTI_ClearITPendingBit(EXTI_Line14);
- }
- }
- #include "stm32f10x.h" // Device header
- #include "Delay.h" // Device header
- #include "OLED.h"
- #include "CountSensor.h"
-
- int main(void)
- {
- CountSensor_Init();
- OLED_Init(); //OLED初始化
- CountSensor_Get();
- OLED_ShowString(1,1,"Count:");
-
- while(1)
- {
-
- }
- }
//清除 AFIO 外设配置
GPIO_AFIODeInit(void)
//锁定GPIO配置,参数指定某个引脚,该引脚配置被锁定,无法更改
GPIO_PinLockConfig((GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin))
//配置 AFIO的数据选择器,选择想要的中断引脚;参数1、选择某个GPIO外设作为外部中断源
参数2、指定要配置的外部中断线
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
//引脚重映射 参数1、选择重映射的方式; 参数2、新的状态
GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState);
//这两个函数用来配置AFIO的时间输出功能(使用频率不多)
- GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
-
- GPIO_EventOutputCmd(FunctionalState NewState);
//与以太网有关
GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface);
//参数1、选择某个GPIO外设作为外部中断源 参数2、指定要配置的外部中断线
本实验中我选择的红外连接在GPIOB--14引脚,所以参数配置如下
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14);
//清除EXTI的配置 并回复成上电默认的转态.
GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource)
//清除EXTI配置
EXTI_DeInit(void)
//根据结构体参数配置EXTI外设,与GPIO_Init 用法类似
EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct)
//把参数传递的结构体变量赋一个默认值
EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct)
//软件触发外部中断
EXTI_GenerateSWInterrupt(uint32_t EXTI_Line)
//获取指定的标志位是否被置1
EXTI_GetFlagStatus(uint32_t EXTI_Line);
//对被置1的标志位进行清除
EXTI_ClearFlag(uint32_t EXTI_Line);
//获取中断位是否被置1
EXTI_GetITStatus(uint32_t EXTI_Line);
//清除中断挂起的标志位
EXTI_ClearITPendingBit(uint32_t EXTI_Line);
若想在主程序中查看和清除标志位,使用5/6这两个函数,
若想在中断函数中查看和清除标志位,使用7/8这两个函数
//中断分组,参数为中断分组的方式
NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
//初始化NVIC
NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)
//设置中断向量表(本实验中暂未用到)
NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset);
//系统低功耗配置(本实验中暂未用到)
NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState)
以上为更新后的EXTI以及中断函数使用,主要优化了文章代码思路以及简介。本文将不定期优化更新。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。