基于STM32中断讲解
基于STM32中断讲解
一、NVIC讲解
简介:当一个中断请求到达时,NVIC会确定其优先级并决定是否应该中断当前执行的程序,以便及时响应和处理该中断请求。这种设计有助于提高系统的响应速度和可靠性,特别是在需要处理大量中断请求的实时应用程序中。
NVIC 支持:256个中断(16内核+240外部),支持:256个优先级,允许裁剪。
从上图中可以看出主要运用的寄存器有**中断使能寄存器(ISER)、中断失能寄存器(ICER)、应用程序中断及复位控制寄存器(AIRCR)、中断优先级寄存器(IPR)**只用对上述寄存器进行配置就行。
中断优先级几种类型:
1、抢占优先级
如果一个中断的抢占优先级高于当前正在执行的中断,那么它可以打断当前中断,优先得到执行。数值越小,优先级越高。
2、响应优先级
如果两个中断同时到达,且它们的抢占优先级相同,那么响应优先级高的中断将首先得到响应。数值越小,优先级越高。
3、自然优先级
自然优先级是由硬件固定并预先设定的,用户无法更改。当抢占优先级和响应优先级都相同时,自然优先级将决定哪个中断先得到处理。
优先级执行顺序
当多个中断同时发生时,执行顺序首先由抢占优先级决定。如果抢占优先级相同,则进一步由响应优先级决定。如果响应优先级也相同,则最终由自然优先级决定。
在中断嵌套的情况下,高抢占优先级的中断可以打断低抢占优先级的中断,但高响应优先级的中断不能打断低响应优先级的中断(当它们具有相同的抢占优先级时)。
优先级分组
优先级寄存器 IPR 有 8 位,但实际只使用到高 4 位,用于决定抢占优先级、响应优先级的等级。一般分为两组。
二、EXTI讲解
简介:EXTI 是 External Interrupt 的缩写,表示外部中断事件控制器。EXTI 可以监测指定 GPIO 口的电平信号变化,并在检测到指定条件时,向内核的中断控制器 NVIC 发出中断申请。NVIC 在裁决后,如果满足条件,会中断CPU的主程序,使 CPU 转而执行 EXTI 对应的中断服务程序。
EXTI 支持的触发方式:上升沿、下降沿、双边沿或软件触发。
EXTI 支持所有的 GPIO 口,但需要注意的是,**相同的 Pin 不能同时触发中断。**例如,PA0 和 PB0 不能同时被配置为中断源。
EXTI 提供了 16 个 GPIO_Pin 的中断线,以及额外的中断线如 PVD 输出、RTC 闹钟、USB 唤醒和以太网唤醒。
中断/事件区分
中断会打断CPU当前正在执行的程序,转而去执行中断服务程序,待中断服务程序执行完毕后,CPU会返回到原来的程序执行点继续执行。
事件只是简单地表示某个动作或状态的变化,而不会打断CPU当前正在执行的程序。当事件发生时,它会根据配置来决定是否触发相应的中断。如果开放了对应的中断屏蔽位(输入0为屏蔽中断,输入1为打开中断),事件就可以触发相应的中断,否则事件只会作为一个信号存在,不会被CPU处理。
中断屏蔽位作用图
前三行位中断触发,后三行位事件触发
EXTI结构
配置中断结构图
三、AFIO讲解
简介:AFIO 是 Alternate Function Input/Output 的缩写,表示复用功能 IO,主要用于实现 I/O 端口的复用功能以及外部中断的控制。
为了优化64脚或100脚封装的外设数量,有时需要将一些复用功能重新映射到其他引脚上。这时,就可以使用AFIO的复用重映射功能。通过设置复用重映射和调试I/O配置寄存器(AFIO_MAPR),可以实现引脚的重新映射,使得复用功能不再映射到它们的原始分配上。
此外,AFIO 还用于控制外部中断,用来配置 EXTI 中断线 0~15 对应哪个具体 IO 口。
AFIO简化图
四、配置原理
配置图:
配置代码:以按键电灯为例
void exit_init(void)
{
GPIO_InitTypeDef gpio_initstruct;//设结构体//打开GPIO的时钟__HAL_RCC_GPIOA_CLK_ENABLE();gpio_initstruct.Pin = GPIO_PIN_0;gpio_initstruct.Mode = GPIO_MODE_IT_FALLING;//中断按键为下降沿模式触发gpio_initstruct.Speed = GPIO_SPEED_FREQ_HIGH;//高速gpio_initstruct.Pull = GPIO_PULLUP; //上拉HAL_GPIO_Init(GPIOA,&gpio_initstruct);HAL_NVIC_SetPriority(EXTI0_IRQn,2,0);//GPIOA/B..00系列HAL_NVIC_EnableIRQ(EXTI0_IRQn); //NVIC中断使能函数
}
void EXTI0_IRQHandler(void) //配置中断服务函数
{
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_pin) //回调函数 回调函数_week类型返回uint16_t传参,可写相应的执行功能
{//delay_ms(20);/*if(GPIO_pin == GPIO_PIN_0)//检测按键是否是pin0脚{if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == GPIO_PIN_RESET){led_toggle();}}*/
}
其中优先级分组一般为两组,只需配置一次即可,在HAL_Init()里面进行配置。