文章目录
- [前言]
- [一、开发硬件与软件环境]
- [二、外部中断工作原理]
- [三、Keil工程配置]
- [四、硬件引脚与接线]
- [五、完整程序代码]
- [六、程序下载与运行现象]
- [七、调试遇到的问题]
- [八、总结]
前言
前面已经实现了GPIO驱动流水灯,流水灯会按照固定间隔循环点亮LED。在实际使用场景中,常常需要外部信号介入,改变程序运行状态。
STM32外部中断EXTI可以检测IO引脚电平跳变,不需要CPU循环不断读取引脚电平,当电平发生变化时,CPU会暂停当前主循环,跳转执行中断服务函数,适合处理这类异步外部事件。
本次在原有流水灯工程基础上,增加外部中断,实现流水灯的暂停、继续控制。
一、开发硬件与软件环境
硬件:STM32F103C8T6最小系统板,LED发光二极管3个,杜邦线若干,面包板,ST‑LINK下载器
软件:Keil MDK5,STM32F10x标准外设库
芯片:STM32F103C8T6
二、外部中断工作原理
STM32F103支持IO口外部中断,PAPG的0‑15引脚可以映射到EXTI0EXTI15中断线。
- PA3配置为上拉输入模式,引脚默认高电平;当引脚接GND时为低电平。
- 将PA3映射到EXTI3中断线,配置为上升沿触发:当PA3由低电平跳变到高电平瞬间,产生外部中断请求。
- NVIC配置中断优先级,使能EXTI3中断通道。
- 触发中断后进入中断服务函数,翻转全局标志位
run_flag。
run_flag = 1:主循环内计时,流水灯正常切换LED。
run_flag = 0:停止计时,LED保持当前状态,实现暂停。 - 中断处理完成必须清除中断挂起标志位,否则会反复进入中断。
本实验使用杜邦线模拟开关:
杜邦线插上,PA3连接GND → PA3为低电平,流水灯运行;
拔掉杜邦线,PA3变为高电平,产生上升沿,触发中断切换运行状态。
三、Keil工程配置
工程在流水灯已有工程副本基础上修改,不需要重新新建完整工程。
- 工程分组文件补充
在STD_LIB分组添加两个库文件:
stm32f10x_exti.c:外部中断底层驱动misc.c:NVIC中断优先级控制
- C/C++配置
预定义宏:STM32F10X_MD,USE_STDPERIPH_DRIVER
头文件包含路径保持标准库原有配置。 - 中断函数冲突处理
打开stm32f10x_it.c,删除内部自带的空EXTI3_IRQHandler函数,避免多重定义编译报错,中断服务函数写在main.c内部。 - 魔术棒Debug、Utilities按照ST‑LINK下载器常规配置,选择ST‑Link Debugger。
四、硬件引脚与接线
| 引脚 | 功能说明 |
|---|---|
| PA0 | LED0输出,低电平点亮 |
| PA1 | LED1输出,低电平点亮 |
| PA2 | LED2输出,低电平点亮 |
| PA3 | 外部中断输入引脚,杜邦线连接GND模拟开关 |
接线说明:
- PA0、PA1、PA2分别接LED,LED串联限流电阻后接GND。
- 一根杜邦线一端固定接PA3,另一端手动接开发板GND;拔掉导线瞬间产生上升沿触发中断。
注意:板子红色按键为RESET硬件复位按键,按下直接芯片重启,不能用作外部中断触发。
五、完整程序代码
六、程序下载与运行现象
- 编译工程,确认无Error警告,使用ST‑LINK下载程序至开发板,按下复位。
- 上电后,PA0点亮,间隔1秒依次切换PA0→PA1→PA2循环流水。
- 杜邦线保持PA3与GND接通,流水灯持续运行。
- 拔掉杜邦线断开PA3与GND,产生上升沿触发中断,流水灯立刻暂停,LED保持当前点亮状态。
- 再次插上、拔掉一次杜邦线,流水灯恢复运行,从暂停位置继续计时,不会直接回到PA0从头闪烁。
七、调试遇到的问题
- 误按开发板红色RESET按键,芯片硬件复位,所有全局变量清零,流水灯每次回到PA0。
解决:RESET属于硬件复位,不能作为外部触发信号,使用PA3引脚杜邦线模拟开关。 - 编译报
EXTI3_IRQHandler重复定义。
解决:stm32f10x_it.c文件内部自带空的中断服务函数,删除该函数,只保留main.c中的中断函数。
八、总结
外部中断可以响应引脚电平跳变事件,不需要CPU持续轮询IO口,节省CPU资源。
本实验在原有流水灯代码基础上,配置GPIO为上拉输入,配置EXTI外部中断与NVIC中断优先级,在中断服务函数修改全局状态标志位。主循环读取标志位控制计时是否继续,实现流水灯在任意时刻暂停,恢复后接续之前状态运行。
同时调试过程也体会到中断开发两个关键点:中断标志必须手动清除;外部信号存在抖动,需要做消抖处理。