STM32H743-ARM例程8-EXTI外部中断
目录
- 实验平台
- 中断简介
- NVIC(嵌套向量中断控制器)
- NVIC简介
- NVIC寄存器
- 中断使能寄存器ISER
- 中断除能寄存器ICER
- 中断使能挂起控制寄存器ISPR
- 中断解挂控制寄存器ICPR
- 中断激活标志位寄存器IABR
- 中断优先级控制的寄存器IP
- NIVC中断优先级
- NVIC相关函数
- EXTI 简介
- 原理图
- STM32CubeMX生成工程
- 实验程序
- 实验现象
实验平台
硬件:银杏科技GT7000双核心开发板-ARM-STM32H743XIH6,银杏科技iToolXE仿真器
软件:最新版本STM32CubeH7固件库,STM32CubeMX v6.10.0,开发板环境MDK v5.35
中断简介
中断是指计算机运行过程中,出现某些意外情况需主机干预时,机器能自动停止正在运行的程序并转入处理新情况的程序,处理完毕后又返回原被暂停的程序继续运行。
中断优先权:
在某一时刻有几个中断源同时发出中断请求时,处理器只响应其中优先权最高的中断源。当处理机正在运行某个中断服务程序期间出现另一个中断源的请求时,如果后者的优先权低于前者,处理机不予理睬,反之,处理机立即响应后者,进入所谓的“嵌套中断”。中断优先权的排序按其性质、重要性以及处理的方便性决定,由硬件的优先权仲裁逻辑或软件的顺序询问程序来实现。
中断过程:
(1)中断源发出中断请求;
(2)判断当前处理机是否允许中断和该中断源是否被屏蔽;
(3)优先权排队;
(4)处理机执行完当前指令或当前指令无法执行完,则立即停止当前程序保护断点地址和处理机当前状态,转入相应的中断服务程序。
(5)执行中断服务程序;
(6)恢复被保护的状态,执行“中断返回”指令回到被中断的程序或转入其他程序。
NVIC(嵌套向量中断控制器)
NVIC简介
STM32H743的NVIC是ARM Cortex-M7内核的关键组件,负责管理所有中断请求的优先级分配和响应控制。其核心功能包括中断嵌套、优先级仲裁和中断向量表管理,支持256个中断源(16个系统异常+240个外部中断),并且具有256级的可编程中断设置。但STM32H743并没有使用CM7内核的全部东西,而是只用了它的一部分。其中系统异常有10个,外部中断有150个。
系统中断如下图所示:
其他150个外部中断部分可以参考《stm32h743xi参考手册》的642页,19章内容。除了个别中断的优先级被定死外,其他的优先级都是可编程修改的。有关具体的系统异常和外部中断可在标准库文件Stm32h743xx.h这个头文件查询到。
NVIC寄存器
NVIC的相关寄存器在固件库头文件:core_cm7.h就可以找到。
typedef struct {__IO uint32_t ISER[8U]; // 中断使能寄存器uint32_t RESERVED0[24U];__IO uint32_t ICER[8U]; // 中断清除寄存器uint32_t RSERVED1[24U];__IO uint32_t ISPR[8U]; // 中断使能悬起寄存器uint32_t RESERVED2[24U];__IO uint32_t ICPR[8U]; // 中断清除悬起寄存器uint32_t RESERVED3[24U];__IO uint32_t IABR[8U]; // 中断有效位寄存器uint32_t RESERVED4[56U];__IO uint8_t IP[240U]; // 中断优先级寄存器(8Bit wide)uint32_t RESERVED5[644U];__O uint32_t STIR; // 软件触发中断寄存器
} NVIC_Type;
我们在配置中断一般只用ISER、ICER和IP这三个寄存器,ISER用来使能中断,ICER用来失能中断,IP用来设置中断优先级。
中断使能寄存器ISER
要使能某个中断,必须设置相应的ISER位为1,使该中断被使能。
中断除能寄存器ICER
与ISER的作用恰好相反,是用来清除某个中断的使能的。要专门设置一个ICER来清除中断位,而不是向ISER写0来清除,是因为NVIC的这些寄存器都是写1有效的,写0是无效的。
中断使能挂起控制寄存器ISPR
通过置1,可以将正在进行的中断挂起,而执行同级或更高级别的中断。写0是无效的。
中断解挂控制寄存器ICPR
其作用与ISPR相反,对应位也和ISER是一样的。通过设置1,可以将挂起的中断解挂。写0无效。
中断激活标志位寄存器IABR
对应位所代表的中断和ISER一样,如果为1,则表示该位所对应的中断正在被执行。这是一个只读寄存器,通过它可以知道当前在执行的中断是哪一个。在中断执行完了由硬件自动清零。
中断优先级控制的寄存器IP
用来配置外部中断的优先级,IPR宽度为8bit,原则上每个外部中断可配置的优先级为0~255, 数值越小,优先级越高。
NIVC中断优先级
优先级的作用:决定多个中断同时触发时的执行顺序、允许高优先级中断抢占低优先级中断(嵌套中断)、确保关键任务(如电机控制、通信)优先响应。
中断优先级可以分为:抢占式优先级和响应优先级,响应优先级也称子优先级,每个中断源都需要被指定这两种优先级。
抢占优先级:高抢占优先级的中断可以打断正在执行的低抢占优先级中断,数值越小,优先级越高(如 0 为最高)。
响应优先级:当多个中断的抢占优先级相同时,子优先级决定执行顺序,即使子优先级更高,也不能打断同级中断。
STM32H743将中断分为5个组,组04。该分组的设置是由SCB->AIRCR寄存器的bit108来定义的。具体的分配关系如下表所示:
通过这个表,我们就可以清楚的看到组0~ 4对应的配置关系,例如组设置为3,那么此时所有的中断,每个中断的中断优先寄存器的高四位中的最高3位是抢占优先级,低1位是响应优先级。每个中断,你可以设置抢占优先级为0~7,响应优先级为1或0。抢占优先级的级别高于响应优先级。而数值越小所代表的优先级就越高。
这里需要注意两点:第一,如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行;第二,高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。而抢占优先级相同的中断,高优先级的响应优先级不可以打断低响应优先级的中断。
结合实例说明一下:假定设置中断优先级分组为2,然后设置中断3(RTC_WKUP中断)的抢占优先级为2,响应优先级为1。中断6(外部中断0)的抢占优先级为3,响应优先级为0。中断7(外部中断1)的抢占优先级为2,响应优先级为0。那么这3个中断的优先级顺序为:中断7>中断3>中断6。
上面例子中的中断3和中断7都可以打断中断6的中断。而中断7和中断3却不可以相互打断!
NVIC相关函数
我们来对常用的函数进行讲解,ST公司已经将NVIC的相关函数封装到stm32h7xx_hal_cortex.c文件中,详情可以查阅对应文件。
- 中断优先级分组函数
void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup);
参数:
PriorityGroup:优先级分组模式(NVIC_PRIORITYGROUP_0~NVIC_PRIORITYGROUP_4)。
示例:
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); // 4位抢占优先级,无子优先级
- 设置中断优先级函数
void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority);
参数:
IRQn:中断号(如 USART1_IRQn)。
PreemptPriority:抢占优先级(范围取决于分组)。
SubPriority:子优先级(若分组支持)。
示例:
HAL_NVIC_SetPriority(TIM2_IRQn, 2, 0); // 抢占优先级=2,子优先级=0
- 中断使能函数
void HAL_NVIC_EnableIRQ(IRQn_Type IRQn);
示例:
形参1是中断号,可以选择范围:IRQn_Type定义的枚举类型
HAL_NVIC_EnableIRQ(EXTI0_IRQn); // 使能 EXTI0 中断
- 中断除能函数
void HAL_NVIC_DisableIRQ(IRQn_Type IRQn);
示例:
HAL_NVIC_DisableIRQ(USART2_IRQn); // 禁用 USART2 中断
- 系统复位函数
void HAL_NVIC_SystemReset(void); // 系统复位(触发 Reset 中断)
用途:强制重启 MCU。
EXTI 简介
EXTI(External Interrupt/Event Controller) 是 STM32 中用于管理 外部中断 和 事件 的模块,能够检测 GPIO 引脚、外设触发信号(如 RTC、PVD)的电平变化,并产生中断或事件请求。它由三个部分组成:APB接口访问的寄存器模块、事件输入触发模块和屏蔽模块。其中寄存器块包含了所以得EXTI寄存器, 事件输入触发块主要提供事件输入边沿触发逻辑。事件屏蔽主要是提供不同的唤醒事件,中断/事件输出以及中断/事件屏蔽分配。
在 STM32 的 EXTI(外部中断/事件控制器)中,事件分为 可配置事件和 直接事件。这两类事件的主要区别在于 触发源的可配置性和用途。
可配置事件:
- 可通过软件配置触发条件(上升沿、下降沿或双边沿触发)。
- 通常与 GPIO 引脚关联,但也可来自部分内部外设
- 可用于唤醒 CPU 或触发其他外设(如 DMA、TIM)。
- 触发源:来自能够生成脉冲的 IO 或外设的信号.
直接事件:
- 触发条件固定,不可通过软件配置边沿检测。
- 通常由特定外设硬件自动触发,不依赖 GPIO。
- 专用于特定功能(如低功耗唤醒、外设联动)。
- 触发源:来自其它外设的中断和唤醒源,需要在外设中清除.
EXTI控制器支持88个外部中断/事件请求。每个中断设有状态位,每个中断/事件都有独立的屏蔽设置,其中26个有独立的触发设置。其中,前23个中断为:
其余的中断,请大家参考《STM32H743xi参考手册》第657页,表132.EXTI事件输入映射,从上面可以看出,中断线0-15对应外部IO口的输入中断,一共是16个外部中断线。STM32H7供IO口使用的中断线只有16个,但是STM32H7的IO口却远远不止16个,那么STM32H7是怎么把16个中断线和IO口一一对应起来的呢?于是STM32就这样设计,GPIO的引脚GPIOx.0 ~ GPIOx.15(x=A,B,C,D,E,F,G,H,I,J,K)分别对应中断线0~15。这样每个中断线对应了最多11个IO口,以线0为例:它对应了GPIOA.0、GPIOB.0、GPIOC.0、GPIOD.0、GPIOE.0、GPIOF.0、GPIOG.0,GPIOH.0,GPIOI.0,GPIOJ.0,GPIOK.0。而中断线每次只能连接到1个IO口上,这样就需要通过配置来决定对应的中断线配置到哪个GPIO上了。
GPIO和中断线映射关系是在寄存器SYSCFG_EXTICR1~SYSCFG_EXTICR4中配置的。
所以我们要配置外部中断,还需要打开SYSCFG时钟。
原理图
在本实验中,按键的一端与STM32的GPIO(PC13)相连,另外一端接地,且PC13外接一个10K的上拉电阻。初始化时把PC13设置成外部中断上升沿触发,当按键按下再弹起时,PC13由于上拉电阻的作用呈高电平。因此PC13的电平变化产生上升沿,从而进入中断函数,可得到按键状态。原理图如下:
STM32CubeMX生成工程
我们参考前面章节STM32H743-结合CubeMX新建HAL库MDK工程,打开CubeMX软件,重复步骤不再展示,我们来看配置NVIC(嵌套向量中断控制器部分如下图所示:
实验程序
1. 主函数
int main(void)
{MPU_Config();HAL_Init();SystemClock_Config();MX_GPIO_Init();while (1){}
}
2. 中断回调函数
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{if(KEY4_VALUE == 1){HAL_GPIO_TogglePin(LED_R_GPIO_Port, LED_R_Pin); // LED状态反转}
}
实验现象
GT7000底板上,K4按键每按下一次,核心板上红色LED状态改变一次。