4、stm32异常与中断

1、异常和中断的概念

bash 复制代码
在 ARM Cortex-M 架构中,异常(Exception) 是指导致处理器暂停当前正常程序流、转而执行特定处理程序
(异常服务例程,Exception Handler)的事件。异常分为两类:

(1)系统异常(System Exceptions):由处理器内核产生,用于处理内部事件,如复位(Reset)、
	不可屏蔽中断(NMI)、硬故障(HardFault)、内存管理故障(MemManage)、总线故障(BusFault)、
	使用故障(UsageFault)、系统调用(SVC)、PendSV、SysTick 等。
(2)外部中断(Interrupts):由片上外设(如 EXTI、TIM、USART、ADC 等)或外部引脚触发,属于可屏蔽中断,
	通过 NVIC(Nested Vectored Interrupt Controller)进行管理。

2、中断响应与中断优先级NVIC

bash 复制代码
(1)中断响应流程
当中断条件满足且未被屏蔽时,处理器执行以下操作:
	完成当前指令(部分指令如 multi-cycle load/store 会提前终止);
	自动保存上下文:将 R0--R3、R12、LR、PC 和 xPSR 共 8 个寄存器压入当前栈(MSP 或 PSP);
	根据中断号从向量表中取出对应异常服务例程(ISR)入口地址;
跳转至 ISR 执行;
	ISR 执行完毕后,执行异常返回指令(如 BX LR),硬件自动恢复上下文并返回原程序断点继续执行。
	该过程由硬件自动完成,具有低延迟、高确定性的特点。

(2)中断优先级机制
	Cortex-M 处理器通过 NVIC(Nested Vectored Interrupt Controller) 实现可嵌套、可配置的中断优先级管理。
	每个异常/中断具有一个 8 位优先级字段,但实际可用位数由芯片实现决定(如 STM32F1 为 4 位有效)。
优先级分为两个逻辑部分:
	抢占优先级(Preemption Priority):决定是否允许高优先级中断嵌套打断正在执行的低优先级 ISR。数值越小,优先级越高。
	子优先级(Subpriority / Response Priority):当多个中断具有相同抢占优先级且同时挂起时,
	用于确定响应顺序,但不支持相互嵌套。
中断挂起概念:
	外设已经"举手申请"了中断(比如按键按下、定时器溢出);
	但因为某些原因(如当前在执行更高优先级的中断,或全局中断被关闭),CPU 还没来得及响应;
	此时,该中断就被 标记为"挂起",等待后续处理。
整体按照:抢占优先级>子优先级>IRQ编号

3、EXIT扩展中断与事件控制器

bash 复制代码
(1)事件的概念
	当检测到触发信号时,直接告知其他外设进行事件的响应而不经过中断
(2)中断
	中断则包括中断响应与事件触发,EXIT检测到触发信号,向NVIC报告中断进行裁决,之后进行事件响应

4、EXIT与NVIC搭配使用

bash 复制代码
(1)当STM32的EXTI监测到GPIO或内部外设满足配置的边沿或电平触发条件,且其中断屏蔽位已使能时
(2)EXTI硬件会自动置位挂起寄存器,并向NVIC发出中断请求。
(3)NVIC根据该中断的优先级、当前CPU执行状态及屏蔽标志进行仲裁:若优先级足够高且未被屏蔽,则在当前指令完成后触发中断响应。
(4)Cortex-M内核自动保存上下文、从向量表获取对应ISR地址,并跳转执行。
(5)用户必须在ISR中手动清除EXTI_PR挂起位(写1清零),否则将导致重复进入中断。
(6)执行完毕后,通过异常返回指令自动恢复上下文,继续主程序。
(7)若中断发生时CPU正处理更高优先级任务,该中断将保持挂起状态,待条件满足后仍会被可靠处理,确保不丢失。

5、代码使用

bash 复制代码
STM32Cube中配置:
(1)RCC使用外部晶振,CLOCK中选择PLL,频率设置72M
(2)SYS中配置程序使用Serial wire
(3)GPIO中断事件的配置(上升、下降)
(4)NVIC优先级分组,中断线使能

查看外部中断/事件控制器章节获取不同引脚对应的EXIT线,

通过PA0按键控制PB0的亮灭

bash 复制代码
GPIO配置:
void MX_GPIO_Init(void)
{

	  GPIO_InitTypeDef GPIO_InitStruct = {0};
	
	  /* GPIO Ports Clock Enable */
	  __HAL_RCC_GPIOB_CLK_ENABLE();
	  __HAL_RCC_GPIOA_CLK_ENABLE();
	
	  
	  /*配置按键PA0中断 */
	  GPIO_InitStruct.Pin = GPIO_PIN_0;
	  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
	  GPIO_InitStruct.Pull = GPIO_NOPULL;
	  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
	  HAL_NVIC_SetPriority(EXTI0_IRQn, 12, 0);
	  HAL_NVIC_EnableIRQ(EXTI0_IRQn);
	  
	  // 配置LED灯PB0
	  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	  GPIO_InitStruct.Pull = GPIO_NOPULL;
	  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
	  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
  
}

中断程序配置:

bash 复制代码
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if (GPIO_Pin == GPIO_PIN_0)  // 判断是 PA0 触发(EXTI0)
    {
        HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); // PB0 = 低电平
		HAL_Delay(500);
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET); 
    }
}
bash 复制代码
个人总结:
对于STM32有多条EXTI总线,都是调用HAL_GPIO_EXTI_Callback触发中断,在回调内部通过GPIO判断属于哪条总线。
对于同一总线则根据优先级
相关推荐
風清掦8 小时前
【江科大STM32学习笔记-05】EXTI外部中断11
笔记·stm32·学习
小龙报8 小时前
【51单片机】从 0 到 1 玩转 51 蜂鸣器:分清有源无源,轻松驱动它奏响新年旋律
c语言·数据结构·c++·stm32·单片机·嵌入式硬件·51单片机
范纹杉想快点毕业8 小时前
嵌入式与单片机开发核心学习指南——从思维转变到第一性原理的深度实践
单片机·嵌入式硬件
Industio_触觉智能8 小时前
瑞芯微RK3566开发板规格书,详细参数配置,型号EVB3566-V1,基于RK3566核心板SOM3566邮票孔封装
嵌入式硬件·开发板·rk3568·rk3566·核心板·瑞芯微
czwxkn8 小时前
4STM32(stdl)TIM定时器
stm32·单片机·嵌入式硬件
Love Song残响9 小时前
NVIDIA显卡终极优化指南
stm32·单片机·嵌入式硬件
qq_672592759 小时前
电源芯片为什么发热
单片机·嵌入式硬件
天天爱吃肉82189 小时前
【跨界封神|周杰伦×王传福(陶晶莹主持):音乐创作与新能源NVH测试,底层逻辑竟完全同源!(新人必看入行指南)】
python·嵌入式硬件·算法·汽车
国科安芯10 小时前
抗辐照MCU在精密时频系统中的单粒子效应评估与可靠性验证
单片机·嵌入式硬件·架构·制造·安全性测试
森焱森10 小时前
嵌入式硬件工程师应知 白银快速分析报告
linux·c语言·arm开发·嵌入式硬件·去中心化