.中断优先级:固定的和可编辑的,异常也可理解为中断,小值优先原则,中断值越小,优先级越高,会被优先响应。中断优先级按照优先级分组配置。
.STM32使用的M3内核支持8bit的优先级中的高4位bit,也就是支持2^4共16个优先级,且被分成五组。组织形式如下:
IRQ小的先行: 所以:抢占优先级>子优先级>IRQ编号
如果外设要发起中断请求则要把 设置中断悬起位 置1,一般由硬件进行操作。清除中断悬起位 置1则内核不会相应中断。新来的中断等待就是悬起。
EXTI扩展中断和事件控制器
EXTI的主要功能是捕获外部输入事件
上升沿触发寄存器和下降沿触发寄存器的配置用来决定输入线的电平变化能否传输到下一级的寄存器。
软件中断事件寄存器:用软件的方式来触发中断。
请求挂存寄存器:用来控制中断请求的生成,然后与中断屏蔽寄存器相与,若没有被屏蔽则到NVIC中断控制器中
中断触发->中断向量表找偏移->找到需要执行的中断函数(此函数存放中断函数的地址)->跳转到中断服务函数
配置中断一般过程:配置时钟 – 配置GPIO端口 – 配置EXTI – 配置NVIC:
1.配置时钟:需要配置GPIO端口和EXTI的时钟,但NVNVIC属于片内外设,不需要在此配置时钟。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能GPIOA的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); // 初始化EXTI外设,EXTI要使能AFIO寄存器时钟
//配置GPIO的初始化函数:
GPIO_InitTypeDef GPIO_InitStructure;//定义一个GPIO_InitStructure为GPIO_InitTypeDef类型的结构体
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //设定要操作的管脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //设置为浮空输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // IO口速度为50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOA
typedef struct
{
uint16_t GPIO_Pin; //指定要初始化的IO口
GPIOSpeed_TypeDef GPIO_Speed; //设置IO口输出速度
GPIOMode_TypeDef GPIO_Mode; //设置工作模式:8种中的一个
}GPIO_InitTypeDef; //GPIO_InitTypeDef结构体的定义
//配置EXTI函数:
EXTI_InitTypeDef EXTI_InitStruct; //定义EXTI_InitStruct为EXTI_InitTypeDef类型的结构体
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource8); //配置EXTI的输入引脚为GPIOA的Pin8脚
EXTI_InitStruct.EXTI_Line=EXTI_Line9——5; //配置EXTI的通道
EXTI_InitStruct.EXTI_LineCmd=ENABLE; //配置EXTI为ENABLE
EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt; //配置EXTI为中断模式或事件模式
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling; //配置中断为上升沿模式触发
EXTI_Init(&EXTI_InitStruct); //根据设置的参数初始化EXTI
typedef struct
{
uint32_t EXTI_Line; // 中断/事件线
EXTIMode_TypeDef EXTI_Mode; // EXTI 模式
EXTITrigger_TypeDef EXTI_Trigger; // 触发类型
FunctionalState EXTI_LineCmd; // EXTI 使能
} EXTI_InitTypeDef; //EXTI_InitTypeDef结构体的定义
//配置NVIC函数:
NVIC_InitTypeDef NVIC_InitStruct ; //定义NVIC_InitStruct为NVIC_InitTypeDef类型的结构体
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1) ; // 配置中断优先级分组为1(设置抢占优先级和子优先级的分配),在函数在misc.c可查看
NVIC_InitStruct.NVIC_IRQChannel = EXTI5-9IRQn; //设置外部中断为0
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1 ; //配置抢占优先级为1
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1 ; //配置响应(子)优先级为1
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE ; //使能外部中断通道
NVIC_Init(&NVIC_InitStruct) ; //根据设置的参数初始化NVIC
typedef struct {
uint8_t NVIC_IRQChannel; // 中断源
uint8_t NVIC_IRQChannelPreemptionPriority; // 抢占优先级
uint8_t NVIC_IRQChannelSubPriority; // 子优先级
FunctionalState NVIC_IRQChannelCmd; // 中断使能或者失能
} NVIC_InitTypeDef; //NVIC_InitTypeDef的结构体定义
void EXTI0_IRQHandler(void)
{
if( EXTI_GetITStatus(KEY1_EXTI_LINE)!=RESET) //使用ITStatus EXTI_GetITStatus(uint32_t EXTI_Line)函数读取中断是否执行
{
......
}
EXTI_ClearITPendingBit(KEY1_EXTI_LINE); //执行完之后要利用EXTI_ClearITPendingBit(uint32_t EXTI_Line)清除清除中断标志位,以 免不断进入中断
}