1.2 EXIT 中断 - 实验篇
1.2 EXIT 中断 - 实验篇
Sarzn现在我们来看看在现实中我们如何具体的利用中断
我们的计划是这样的, 使用按钮来控制 LED 的亮还是灭 一开始默认是灯灭, 按钮被按下, 灯亮, 按钮再次被按下, 灯灭
这个与实验一相衔接, 你可以直接在实验一的工程上进行配置, 也可以再新开一个工程, 不过要注意将小灯等东西给配置好
接下来我在实验一的基础上开始继续讲解
Step 0 - 接线
- 将按钮的左右两边分别连接在 PA1 和 GND 上
Step 1 - 配置中断引脚
- 在芯片图中我们选择一个引脚, 这里以 PA1 为例, 将它配置为
GPIO_EXIT1
然后我们来到 GPIO
配置界面
- 来到 GPIO 配置界面, 选择我们的 PA1 口, 模式选择 External
Interrupt Mode with
Falling edgetrigger detection, 同时将 GPIO 配置成上拉
这里解释一下 Falling edge和 Rising edge
都是什么意思
翻译成中文就是 上升沿 - Rising edge, 下降沿 - Falling edge
上升沿就是电平从低到高, 上升了,
就是上升沿 下降沿就是电平从高到低,
下降了, 就是下降沿

选择下降沿是因为我们将它配置成了上拉模式
如图所示, 现在将 PA1 配置成上拉模式, 那么 PA1 的左边是高电平
如果按钮被按下, 连接 GND 的导线被接通, PA1 上的电平从高电平变成低电平, 这个不就是下降沿的过程吗. 这个下降沿变化被 detection, 就认为按钮被按下, 然后触发中断
解释完了之后会到正题, 我们继续配置引脚 PA1
- 设置名称
user lable为 Button - 在NVIC中将 EXIT line 1 启用
Step 2 - 生成代码并编写中断函数
生成代码之后使用 Clion 打开, 记得新增一个 OpenOCD 项目
- 打开这个项目, 我们需要更改的是
stm32f1xx_it.c这个文件, 他用来专门写有关中断的函数(再此之前, 你需要把之前在实验一中 main 函数写的 LED 闪烁的代码清除)
打开 stm32f1xx_it.c
我们可以看到:
有一段注释是:Cortex-M3 Processor Interruption and Exception Handlers 这就说明下面的所有东西都是有关中断处理函数的内容, ISR
我们看看下面的函数, 也确实都是一些 叫做 xxx_Handler,
这就是中断处理函数
而我们要用到的函数在这个文件的最下面
这里又有一段注释块写着 STM32F1xx Peripheral Interrupt Handlers - STM32F1xx 外设中断处理函数
我们要用到的函数就是叫做 EXTI1_IRQHandler() 的函数, 就是
EXTI1 线上的 IRQ(中断信号)处理函数
在这个函数的内部, 只有一句
HAL_GPIO_EXTI_IRQHandler(Button_Pin);, 这个就是 CubeMX
自动帮我们生成的 HAL 库函数, 我们按住 command(ctrl)
同时鼠标点击这个函数
于是我们跳转到 stm32f1xx_hal_gpio.c这个文件, 这是在
Driver 层的 HAL 库的驱动文件

HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin);
函数中他首先检查并清空了标志位, 这就是我在原理篇中提到的 HAL
库会自动帮你清理中断标志 flag
随后, 它调用了 HAL_GPIO_EXTI_Callback(GPIO_Pin);
这个函数, 我们继续点击它, 看看他是做什么的
他跳转到了下面这里
___weak ,
这是什么意思呢?
__weak 是弱符号(weak symbol)标记:
作用是在链接阶段告诉链接器:这是一个默认实现,如果别处有同名的强定义,就用那个、忽略我这个
为什么要这样, 不能直接重写吗? C 没有面向对象的重写机制,HAL 借助弱符号,巧妙地给你留了个覆盖默认行为的机制, 这就是C 语言里伪重写的常见手法
所以 HAL_GPIO_EXTI_Callback()
是一个用弱符号实现的回调函数,
要注意他不是虚函数
我这里说到了另外的一些个名词回调函数,弱函数, 虚函数, 他们经常被搞混, 所以你可以看[[番外篇 - 从 STM32 的 __weak说起弱符号、回调函数与虚函数|番外篇 - 从 STM32 的 __weak说起弱符号、回调函数与虚函数]]
慢慢研究吧, 总有一天你会悟的
- 于是我们在
stm32f1xx_it.c最后写上HAL_GPIO_EXTI_Callback()的强函数, 让他覆盖掉弱实现
1 | void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) |
Step 3 - 构建并烧录
其实很简单, 只要写这一段代码就行了, 但是要真正理解背后的原理并不简单
现在接好你的 daplink, 我们锤一锤代码, 然后烧录到开发板中
按下按钮, 你发现灯亮了, 再按, 灯亮
我们成功的实现了这个实验, 但是你真正理解了其中的原理, 你才算真正成功了











