外部中断

罗大富 BigRich大约 4 分钟ESP32Python

之前我们学习了 ESP32 的按键控制,当时通过查询 GPIO 输入电平来判断按键状态,这种方法占用 CPU 资源,效率不高。本节课我们学习外部中断,通过外部中断实现按键控制 LED。

实验原理

在单片机中,中断是指当 CPU 在正常处理主程序时,突然发生了另一件事件 A(中断发生)需要 CPU 去处理,这时 CPU 就会暂停处理主程序(中断响应),转而去处理事件 A(中断服务)。当事件 A 处理完以后,再回到主程序原来中断的地方继续执行主程序(中断返回)。这一整个过程称为中断。

例如,当你正在洗衣时,突然手机响了(中断发生),你暂时中断洗衣的工作,转去接电话(中断响应和中断服务),待你接完后,再回来继续洗衣(中断返回),这一过程就是中断。

当中断过程 A 中,发生了另一个中断级别更高的中断事件 B,则 CPU 又会中断当前的 A 转而去处理 B,完毕后再回到 A 的断点继续处理。这称为中断的嵌套。

中断的嵌套涉及到中断的优先级问题,优先级高的中断就可以在打断优先级低的中断执行。

注意

ESP32 无法使用 MicroPython 设置中断的优先级。

中断可以根据中断源分为 硬件中断软件中断

  1. 硬件中断:也被称为外部中断,硬件中断响应外部硬件事件而发生。例如,当检测到触摸时会发生触摸中断,而当 GPIO 引脚的状态发生变化时会发生 GPIO 中断。GPIO 中断和触摸中断属于这一类;
  2. 软件中断:当触发软件事件(例如定时器溢出)时,会发生这种类型的中断。定时器中断是软件中断的一个例子。

前面我们在做按键控制实验时,虽然能实现 IO 口输入功能,但代码是一直在检测 IO 输入口的变化,因此效率不高,特别是在一些特定的场合,比如某个按键,可能 1 天才按下一次去执行相关功能,这样我们就浪费大量时间来实时检测按键的情况。

为了解决这样的问题,我们引入外部中断概念,顾名思义,就是当按键被按下(产生中断)时,才去执行相关功能。这大大节省了 CPU 的资源,因此中断在实际项目中应用非常普遍。

ESP32 的外部中断有上升沿、下降沿、低电平、高电平触发模式。上升沿和下降沿触发如下:

若将按键对应 IO 配置为下降沿触发,当按键按下后即触发中断,然后在中断回调函数内执行对应的功能。

硬件电路设计

使用按键电路实现开关灯的效果。

物料清单(BOM 表):

材料名称数量
直插式 LED1
1kΩ 电阻1
杜邦线(跳线)若干
面包板1

将材料按照下图相连:

软件程序设计

外部中断也是通过 Pin 模块来配置的,使用方法如下:

from machine import Pin

button = Pin(14, Pin.IN, Pin.PULL_DOWN)

# 配置中断模式
button.irq(handler, trigger)

其中 button.irq(handler, trigger) 是配置中断模式,参数意义:

  • handler: 中断执行的回调函数;
  • trigger: 触发中断的方式,共 4 种,分别是 Pin.IRQ_FALLING(下降沿触发)、Pin.IRQ_RISING(上升沿触发)、Pin.IRQ_LOW_LEVEL(低电平触发)、Pin.IRQ_HIGH_LEVEL(高电平触发)。

因此,我们的代码需要这么写:

import time
from machine import Pin

button = Pin(14, Pin.IN, Pin.PULL_DOWN)

led = Pin(2, Pin.OUT)

# 定义 button 的外部中断函数
def button_irq(button):
    time.sleep_ms(80)
    if button.value() == 1:
        led.value(not led.value())

button.irq(button_irq, Pin.IRQ_RISING)
上次编辑于:
贡献者: Luo