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),并调整中断服务函数名称。
- 回调函数运行在中断上下文中,应避免执行耗时操作(如延时、打印),本案例仅做引脚翻转,符合中断处理要求。