3. 外部中断触发事件

外部中断触发事件 学习卡片

任务说明

本案例基于MCU HAL库实现外部中断触发事件:配置一个外部中断输入引脚(连接按键),当按键按下产生下降沿中断时,HAL库回调函数被触发,在回调中翻转LED引脚状态,实现按键中断控制LED亮灭切换。案例以STM32F4系列HAL库为标准实现,核心代码可直接移植到其他支持HAL库的MCU平台。

硬件连接

  • 按键:PA0(外部中断线0,下降沿触发),按键另一端接GND
  • LED:PC13(推挽输出,低电平点亮),串联限流电阻后接VCC

HAL库外部中断配置

外部中断配置分为两部分:引脚基础配置(GPIO工作模式、上下拉、触发边沿)和中断通道配置(NVIC使能)。HAL库将两者封装在HAL_GPIO_Init()和HAL_NVIC_SetPriority()/HAL_NVIC_EnableIRQ()中。中断触发后,硬件跳转到EXTI0_IRQHandler(),该函数调用HAL库公共处理函数HAL_GPIO_EXTI_IRQHandler(),最终回调用户编写的HAL_GPIO_EXTI_Callback()。

代码实现


/* main.c 中用户代码区域 */

/* 引脚与中断配置 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if (GPIO_Pin == GPIO_PIN_0)
    {
        /* 按键按下,翻转LED状态 */
        HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
    }
}

/* GPIO初始化(在main函数中调用) */
static void MX_GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    /* 使能GPIOA和GPIOC时钟 */
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();

    /* 配置PC13为推挽输出 */
    GPIO_InitStruct.Pin   = GPIO_PIN_13;
    GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull  = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

    /* 配置PA0为外部中断输入,下降沿触发 */
    GPIO_InitStruct.Pin   = GPIO_PIN_0;
    GPIO_InitStruct.Mode  = GPIO_MODE_IT_FALLING;
    GPIO_InitStruct.Pull  = GPIO_PULLUP;   /* 按键接GND,默认上拉 */
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* 使能EXTI0中断通道 */
    HAL_NVIC_SetPriority(EXTI0_IRQn, 2, 0);
    HAL_NVIC_EnableIRQ(EXTI0_IRQn);
}

/* 中断服务函数(放在stm32f4xx_it.c中) */
void EXTI0_IRQHandler(void)
{
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
}

/* main函数主循环 */
int main(void)
{
    HAL_Init();
    MX_GPIO_Init();

    while (1)
    {
        /* 主循环无需轮询按键,中断自动处理 */
    }
}

代码说明

上述代码中,MX_GPIO_Init()完成所有引脚初始化:PC13配置为普通推挽输出用于驱动LED;PA0配置为GPIO_MODE_IT_FALLING模式,即外部中断下降沿触发,同时使能内部上拉电阻,保证按键未按下时引脚为高电平。中断服务函数EXTI0_IRQHandler()直接调用HAL库公共处理函数,该函数会检查中断标志并调用用户回调。在回调HAL_GPIO_EXTI_Callback()中判断中断引脚号,执行LED翻转操作。主循环为空,系统完全由中断驱动。

验证方法

将代码编译后下载至开发板,观察以下现象:

  • 初始状态:LED处于熄灭状态(PC13输出高电平)
  • 每次按下按键并释放(产生一次下降沿),LED状态翻转一次(亮→灭或灭→亮)
  • 连续快速按键,LED状态跟随每次按键动作切换,无遗漏

判定标准:按键每按下一次,LED亮灭状态切换一次,且状态保持稳定,说明外部中断触发与回调执行正确。

关键注意事项

  • 按键按下时若存在机械抖动,可能产生多次沿跳变。实际应用中可在回调中增加软件消抖(如延时10ms后再次读取引脚电平确认),本案例为演示中断机制,未包含消抖逻辑。
  • 若使用其他MCU型号,需确认外部中断线编号与引脚对应关系(如PA0对应EXTI0),并调整中断服务函数名称。
  • 回调函数运行在中断上下文中,应避免执行耗时操作(如延时、打印),本案例仅做引脚翻转,符合中断处理要求。
外部中断触发事件——中断链路与信号流向 按键输入 PA0 上拉输入 按下→低电平 下降沿 EXTI0 中断线 边沿检测 触发中断请求 硬件跳转 NVIC 中断控制器 优先级判定 响应中断 调用 EXTI0_IRQHandler HAL_GPIO_EXTI_ IRQHandler() 用户回调函数(中断上下文) HAL_GPIO_EXTI_Callback() 判断 GPIO_PIN_0 回调 HAL_GPIO_TogglePin() 翻转 PC13 LED 中断触发路径:按键按下 → PA0下降沿 → EXTI0请求 → NVIC响应 → ISR → HAL公共处理 → 用户回调 → LED翻转 主循环无需轮询,系统完全由外部中断事件驱动