左左右学堂 · 课程目录

第43期 EXTI外部中断实例解析

观看B站原视频 · 文稿与高清画面

Hello,小伙伴们,大家好,这里是左左右。这期视频我们会通过一个非常经典的按键控制LED小灯的例子。彻底搞懂中断的工作流程以及在实际开发中的正确姿势。在之前的视频中,我们写过一个按键控制LED亮灭的代码。当时,我们把按键检测的逻辑直接放在了main函数的。while循环里面。

大概是这样的,循环里不断读取按键IO口的电平。如果判断按键被按下,就翻转LED的状态。这种方式虽然能工作。但存在一个很明显的缺陷。主程序被阻塞了。大家可以想一下。按下按键这个动作是随机的,而且不是持续发生的,但是,我们的程序却要在while循环里一刻不停地去读按键。那他还怎么去干别的活呢?

这就是所谓的“轮询”方式。它会占用CPU的全部时间。导致其他任务无法及时执行。说通俗点。主程序什么都干不了了。只能守在那里等待按键。那有没有更好的办法呢?当然,有!既然按键动作是随机发生的,我们就应该让它“主动通知”CPU,而不是让CPU去“主动问”。这就是中断的典型应用场景,把按键检测放到中断里面。

CPU平时可以安心处理其他事情。一旦按键被按下。硬件就会自动触发中断。暂时打断当前任务。去执行我们预先写好的中断处理程序。执行完再回来继续原来的工作。这样一来,主程序就不会被阻塞了。好,理论说完了。我们打开STM32CubeIDE。

首先,将引脚设置为外部中断触发。由于我们的按钮是与地相连的,所以,我们将P C 13引脚设置为下降沿触发。输入模式为上拉输入。同时,在 N V I C中将中断使能。点击保存代码就自动生成了。实际看一下中断在底层到底是怎么被调用的?我们都知道。中断是由硬件自动调用的,那它到底调用了哪个函数呢?

视频画面 02:42.3
视频画面 02:42.3 · 1080P 原图 · 查看对应视频

我们可以打开启动文件startup_stm32f103c8tx.s。这个文件是用汇编写的,里面定义了各种中断向量。仔细看,你会看到一大堆以IRQHandler结尾的函数名。这些就是硬件发生中断时自动调用的入口函数。比如,我们这次要用到的按键。它接在哪个IO口呢?我们这里用的是PC13。

视频画面 04:51.2
视频画面 04:51.2 · 1080P 原图 · 查看对应视频

那对应的外部中断通道就是EXTI13。它属于EXTI15_10这一组。所以,我们就能看到EXTI15_10_IRQHandler这个函数。当按键按下触发中断后,硬件就会自动跳转到这个函数。我们点进去看它的实现过程。发现这个函数里调用了HAL_GPIO_EXTI_IRQHandler。

视频画面 03:25.3
视频画面 03:25.3 · 1080P 原图 · 查看对应视频

并且传入了对应的GPIO引脚。再继续往下追。在HAL_GPIO_EXTI_IRQHandler这个函数内部,它又会调用一个叫做HAL_GPIO_EXTI_Callback的函数。注意看,这个回调函数前面有一个__weak关键字。在C语言中表示“弱定义”,什么意思呢?就是说?

如果你自己没有写这个函数,编译器就会用这个默认的,什么都没做的弱函数。如果你自己写了一个同名的函数,那编译器就会用你的版本。覆盖掉弱定义。HAL库把中断的处理流程固定好了。但真正要做的事情。留给我们去实现。所以,结论很简单。我们想要在中断发生时执行的自定义代码都应该写在HAL_GPIO_EXTI_Callback这个函数里面。

我们将之前写好的代码复制到这里就可以了。点击运行这时我们发现按下按钮并不能实现小灯的亮灭功能。这是为什么呢?这时我们将HAL_Delay这个延时函数更换为我们之前自己写的my_delay延时函数。点击运行,程序正常执行了。我想此时大家心中应该已经有答案了。HAL_Delay和my_delay这两个函数的区别就是HAL_Delay使用了滴答定时器这个中断。

视频画面 05:34.1
视频画面 05:34.1 · 1080P 原图 · 查看对应视频

EXTI本身就是中断。它打断了主程序,而HAL_Delay中也包含中断,也就是要实现中断的嵌套。这就要求滴答定时器的抢占优先级要高于EXTI。打开NVIC来看一下。这里的滴答定时器抢占优先级确实低于EXTI。这里我们只要保证滴答定时器抢占优先级确实高于EXTI就可以了。

点击运行,程序是不是也能正常执行了?由于这里是EXTI15-10的中断,这里也可能是除PC13外的其他引脚触发的中断。谨慎起见我们在这里加个if判断。确保是PC13触发的中断才去执行我们这段代码。其实,这段代码还是存在一定问题的,这里加入HAL_Delay的延时其实并不合适。

虽然10毫秒对于我们来说是一瞬间的事,但是,对于单片机来说是很漫长的,中断讲究“短且快”。所以,在中断里使用延时是并不合适的,但是,在这个案例中使用是没有问题的,随着视频内容的推进,我们会讲更合适的方法来处理这个问题的。我只是想通过这个案例让大家熟悉中断和中断嵌套的相关知识点。

好的,今天的视频就到这里。下期视频我们将使用CLion使用寄存器的方式完成相同的案例。一定要关注、点赞、收藏,评论。您的支持是我这样的小博主持续更新下去的最大动力。期待下期视频再见!

找出这篇stm32f103c8t6单片机口播文案存在的错误,,形成一篇2500字左右的完整口播文案。

首先,将引脚设置为外部中断触发,由于我们的按钮是与地相连的,所以我们将P C 13引脚设置为下降沿触发,输入模式为上拉输入,同时在 N V I C中将中断使能,点击保存代码就自动生成了,