50元从零到成品:一套AI辅助的嵌入式实战入门教程——中断篇

前面几章,我们搭建好了开发环境,配置好了基础工程,也学会了用GPIO点灯和读取传感器信号。但不知道大家有没有想过一个问题:

如果CPU一直在main函数里不停地循环读取某个引脚的状态,那它还有时间干别的吗?

GPIO输入那篇里,我们读取声音传感器的信号用的是轮询方式------CPU在循环里一遍又一遍地问"引脚变高了没?变低了没?"这种方式在只检测一个信号的时候还能应付,但如果系统里有多个信号需要同时检测、多个任务需要同时处理,轮询就力不从心了。

这时候就需要中断 登场了。这篇咱们就来聊聊:中断是什么、它怎么工作、以及我们怎么用按键中断来替代轮询检测。中断也是我们接触到的第一个比较重要而且有点难理解的功能,这里尽量讲得详细一点。

一、什么是中断?一个生活化的比喻

先别急着看寄存器,咱们用一个生活中最常见的场景来理解中断。

假设你正在书房里专心写代码(这是你当前执行的主程序 )。这时候------叮咚 ------门铃响了(这是一个中断事件 )。你停下手中的工作(打断当前任务 ),起身去开门(执行中断服务程序 )。发现是快递员,签收完包裹之后,你回到书房,继续接着刚才的代码往下写(恢复主程序执行)。

整个过程有几个关键点:

  • 中断源

    :门铃(触发中断的外部事件)

  • 中断响应

    :你停下当前工作去开门(CPU暂停主程序,跳转执行中断服务函数)

  • 中断服务函数

    :开门、签收这个具体动作(处理中断事件的代码)

  • 恢复执行

    :处理完后回到书房继续写代码(CPU回到被打断的位置继续执行)

中断的本质就是这样------让CPU能够在处理主要任务的同时,及时响应突发的、更紧急的事件

如果用GPIO轮询的方式来处理门铃,那就相当于:你写代码的时候每隔一秒钟就抬头看一眼门口有没有人------效率极其低下,而且如果正好在两次抬头的间隙有人敲门,你就错过了。

二、STM32的中断系统长什么样?

STM32F103内部有一套完整的中断管理系统,主要由两个核心部件组成:

2.1 NVIC------中断的"调度中心"

NVIC(Nested Vectored Interrupt Controller,嵌套向量中断控制器)是Cortex-M3内核内置的中断管理单元。它的职责是:

  • 管理所有中断

    :STM32F103一共有60个可屏蔽中断,加上16个内核中断(异常),总共76个中断源

  • 决定中断优先级

    :当多个中断同时发生时,谁先处理、谁能打断谁

  • 嵌套处理

    :高优先级的中断可以打断正在执行的低优先级中断

简单理解:NVIC就是CPU门口的保安------所有中断请求都要经过它,它根据优先级决定让谁先进去。

2.2 中断向量表------中断的"通讯录"

中断向量表是一个存放在Flash起始地址的表,里面按顺序记录了每个中断对应的服务函数的入口地址

当某个中断发生时,CPU会去这个表里查找:这个中断对应的函数在哪个地址?然后跳转过去执行。

这个表在STM32的启动文件 (如startup_stm32f103xb.s)里已经预先定义好了,比如外部中断0对应的服务函数叫EXTI0_IRQHandler,外部中断5~9共用EXTI9_5_IRQHandler,外部中断10~15共用EXTI15_10_IRQHandler。我们只需要在代码里实现这些函数就可以了,不需要在main函数里调用它们------中断发生后CPU会自动跳转过去。

三、外部中断(EXTI)------GPIO引脚的中断能力

如果上面这些简单的介绍还是不能完全理解,没关系,可以先跟着做,动手操作之后再思考,有时候更容易理解。这里我们用最常用的一种中断类型来介绍如何使用中断------通过GPIO的外部中断来控制LED

STM32F103的每一个GPIO引脚都可以配置为外部中断输入 ,EXTI(External Interrupt/Event Controller)支持19个外部中断/事件线。这19条线分别是:

  • 线0~15

    :对应外部IO口的输入中断

  • 线16

    :连接到PVD(可编程电压监测器)输出

  • 线17

    :连接到RTC闹钟事件

  • 线18

    :连接到USB唤醒事件

EXTI的核心功能是:

  • 边沿检测

    :可以检测输入信号的上升沿下降沿 或者双边沿触发

  • 独立配置

    :每个中断线可以单独配置触发方式和使能/屏蔽

这意味着:当按键被按下(电平从低变高,产生上升沿)时,EXTI会检测到这个变化,向NVIC发出中断请求,CPU就会暂停当前任务去执行对应的中断服务函数。

四、按键中断------我们这篇要做的实验

回到我们室内环境检测系统的项目进度。前一篇GPIO篇里,我们实现了两个功能:

  • PC13输出

    :控制LED以1秒间隔闪烁,表示系统正常运行

  • PB12输入

    :读取声音传感器的数字输出

这一篇我们要增加第三个功能------按键中断

  • 硬件连接

    :将一个按键模块连接到单片机的PB3引脚,然后就是经典组合------仿真器和单片机

  • 功能需求

    :按下按键时,触发中断,在中断服务函数中翻转LED的状态(亮→灭,或灭→亮)

为什么用中断而不用轮询?

如果用轮询方式检测按键,CPU需要在主循环里不断地读取引脚电平------这有两个问题:

  1. CPU被占用

    :一直在做"读引脚"这件事,没法专心干别的

  2. 可能漏检

    :如果按键按下刚好发生在两次读取之间,程序就"看不见"这次按键

而中断方式则是事件驱动 的------按键按下才触发处理,平时CPU可以安心执行主程序,真正做到了有事件才响应,没事件不打扰

消抖问题------中断的"坑"

不过中断方式也有一个需要注意的地方:按键的机械抖动

机械按键在按下和释放的瞬间,触点会快速弹跳几次,产生一连串的电平变化。如果用中断直接检测边沿,按一次键可能会触发多次中断------明明只想翻转一次LED,结果可能翻转了好几次。

解决方式通常有:

  • 软件延时消抖

    :在中断服务函数中延时10~20ms再读取电平确认

  • 定时器消抖

    :用定时器中断来做延时检测(更精确,不阻塞)

  • 状态机消抖

    :用状态机管理按键状态,滤除抖动

本篇我们利用AI,直接使用HAL_GetTick()配合时间戳来实现100ms软件消抖。

五、配置步骤一览

结合我们之前几篇的配置流程,按键中断的配置大致需要这几步:

  1. CubeMX引脚配置

    :找到按键对应的引脚(PB3),在Pinout视图中选择GPIO_EXTI3模式

  2. 触发方式配置

    :在GPIO配置中,选择中断触发方式------上升沿触发(按键按下时电平从低变高)

  3. NVIC中断使能

    :在NVIC选项卡中,勾选对应的EXTI中断线,使能中断

  4. 生成代码

    :点击GENERATE CODE,CubeMX会自动生成中断初始化代码

  5. 编写按键功能

    :让AI编写按键功能并生成按键功能文件,实现按键反转IO的功能

六、小结

这一篇我们从"为什么需要中断"出发,梳理了中断的基本概念、STM32的中断体系架构(NVIC和中断向量表),以及外部中断EXTI的工作原理。

核心要记住的是:

  • 中断 = 让CPU从"主动轮询"变成"被动响应"

    ,效率更高、响应更及时

  • NVIC是中断的调度中心

    ,负责管理优先级和嵌套

  • EXTI让每个GPIO引脚都能产生中断

    ,是GPIO输入的高级形态

  • 按键中断要注意消抖

    ,否则一次按下可能触发多次

刚开始接触中断,基本都是从外部中断开始的,这导致很长一段时间里我都混淆了"外部中断"和"中断"的关系。实际上,外部中断只是中断功能中的一种类型,还有很多其他中断类型,比如串口接收中断、DMA发送完成中断、定时器溢出中断等等。感兴趣的朋友可以利用AI去深入了解一下。

相关推荐
影寂ldy1 小时前
C# UDP+串口Modbus转发网关
单片机·网络协议·udp
HUI-4742 小时前
EG1188|SOP‑8 高压非隔离降压 PWM 控制器,小功率辅助电源高性价比方案
嵌入式硬件·硬件工程
fox081512 小时前
栈空间带来的大问题
单片机·嵌入式硬件
wuyk55513 小时前
从零吃透Modbus通信|第3章:STM32 Modbus RTU主机
服务器·开发语言·网络·数据结构·stm32·单片机·嵌入式硬件
恒锐丰小瑞14 小时前
率能SS6285L 18V/5A/单通道直流电机驱动IC,超低导通电阻(58mΩ)与多重保护,用于电子锁/玩具/机器人
单片机·嵌入式硬件·机器人
天空'之城15 小时前
单片机基础核心知识点汇总(二十)
单片机·嵌入式硬件
笨笨饿15 小时前
#121_图传中的H.364编码与MP4的联系
linux·运维·前端·单片机·嵌入式硬件·面试·职场和发展
送外卖的工程师16 小时前
STM32智能鞋柜(机智云)
stm32·单片机·嵌入式硬件
Romantic_love_17 小时前
USART串口初始化源码解析
stm32·单片机·嵌入式硬件·学习