中断点灯--外部中断代码执行流程
中断点灯
#include "exti.h"
#include "sys.h"
#include "delay.h"
#include "led.h"
void exti_init(void)
{
GPIO_InitTypeDef gpio_initstruct;
//打开时钟
__HAL_RCC_GPIOA_CLK_ENABLE(); //使能GPIO时钟
//调用GPIO初始化函数
gpio_initstruct.Pin = GPIO_PIN_0; //设置AFIO
gpio_initstruct.Mode = GPIO_MODE_IT_FALLING; //设置EXTI,下降沿触发
gpio_initstruct.Pull = GPIO_PULLUP; //设置GPIO输入模式
gpio_initstruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &gpio_initstruct);
//设置NVIC
HAL_NVIC_SetPriority(EXTI0_IRQn, 2, 0); //设置优先级,EXTI0_IRQn就是PA0的中断线
HAL_NVIC_EnableIRQ(EXTI0_IRQn); //使能中断
}
//中断服务函数,中断服务函数没有任何的返回值和传入的参数
void EXTI0_IRQHandler(void) //中断服务函数的名字是在启动文件中写好的,找到对应的中断线即可。
{
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0); //调用公共服务函数
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) //在回调函数中写代码
{
delay_ms(20);
if(GPIO_Pin == GPIO_PIN_0)
{
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == GPIO_PIN_RESET)
{
led1_toggle();
}
}
}
STM32 HAL 外部中断(EXTI)代码执行流程总结
一、整体流程概览
PA0 下降沿
↓
EXTI 硬件检测触发
↓
EXTI0 中断线置位
↓
NVIC 判断并响应中断
↓
CPU 跳转到 EXTI0_IRQHandler
↓
HAL_GPIO_EXTI_IRQHandler
↓
HAL_GPIO_EXTI_Callback
↓
执行用户代码(LED 翻转)
二、初始化阶段(exti_init)
1. 使能 GPIO 时钟
__HAL_RCC_GPIOA_CLK_ENABLE();
- GPIO 属于外设,必须先打开时钟
- 否则后续 GPIO 配置无效
2. 配置 PA0 为外部中断输入
gpio_initstruct.Pin = GPIO_PIN_0;
gpio_initstruct.Mode = GPIO_MODE_IT_FALLING;
gpio_initstruct.Pull = GPIO_PULLUP;
gpio_initstruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &gpio_initstruct);
作用说明:
GPIO_MODE_IT_FALLING- 将 PA0 连接到 EXTI0
- 配置为下降沿触发中断
GPIO_PULLUP- 默认高电平
- 按键按下拉低,形成下降沿
3. 配置 NVIC
HAL_NVIC_SetPriority(EXTI0_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(EXTI0_IRQn);
- 设置 EXTI0 中断优先级
- 允许 EXTI0 中断进入 CPU
- 若未使能 NVIC,中断不会被响应
三、中断触发阶段(硬件行为)
- 按键按下,PA0 电平由高变低
- EXTI 检测到下降沿
- EXTI0 中断标志位被置位
- 向 NVIC 发送中断请求
四、中断响应阶段(ISR)
1. NVIC 响应中断
- 判断中断是否使能
- 判断优先级
- CPU 暂停主程序,进入中断服务函数
2. 执行中断服务函数
void EXTI0_IRQHandler(void)
{
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
}
作用:
- 调用 HAL 提供的通用 EXTI 中断处理函数
3. HAL_GPIO_EXTI_IRQHandler 内部逻辑
- 判断 EXTI0 是否触发
- 清除 EXTI0 中断标志位
- 调用用户回调函数
五、回调函数阶段(用户代码)
HAL_GPIO_EXTI_Callback
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
delay_ms(20); // 按键消抖
if (GPIO_Pin == GPIO_PIN_0)
{
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET)
{
led1_toggle();
}
}
}
说明:
- 所有 EXTI 中断都会进入该回调函数
- 通过
GPIO_Pin判断具体触发源 - 延时 + 再次读取引脚电平实现按键消抖
- 执行 LED 翻转操作
六、关键点总结
- EXTI:负责检测引脚电平变化
- NVIC:决定中断是否进入 CPU
- ISR(中断服务函数):清中断标志并分发回调
- 回调函数:编写用户业务逻辑的地方
七、一句话总结
STM32 外部中断的本质是:
硬件检测 → NVIC 仲裁 → CPU 跳转 → 清标志 → 执行回调函数。

浙公网安备 33010602011771号