esp32中的中断

本人是初学者,非常希望与各位交流。

最近刚好在看中断,但是我比较喜欢那种比较浅显的描述语言,有兴趣的一起来看看吧。

想象一下你在专心看书(这是 ESP32 在正常执行它的主程序 loop())。

突然,有人按了门铃!叮咚!📢

这时候,你通常会怎么做?

  1. 停下看书:你会暂时把书放下(暂停正在做的事情)。

  2. 处理“中断”:你会起身,走到门口,看看是谁(执行一个特定的动作来响应这个“门铃事件”)。

  3. 回来继续:处理完门口的事情(比如签收了快递),你会回到座位,接着刚才看的地方继续看书(回到主程序 loop() 中断的地方继续执行)。

ESP32 的“中断”就是这个“门铃”机制!

  • 看书 = 主程序:ESP32 的主程序(通常是 loop() 函数)就像你在看书,它在一行一行地执行代码。

  • 门铃 = 中断源:门铃就是一个能产生“中断信号”的东西。在 ESP32 上,常见的中断源有:

    • 外部引脚电平变化:比如一个按钮被按下(引脚从高电平变成低电平)或松开(低变高)。

    • 定时器到期:就像一个闹钟响了,告诉 ESP32 “到时间了,该做某事啦!”。

    • 串口收到数据:当有新的数据通过串口传进来时。

    • 其他硬件事件:比如触摸感应、Wi-Fi事件等等。

  • 停下看书 = 中断发生:当中断源(门铃)发出信号时,ESP32 会立即暂停它当前正在执行的主程序代码。

  • 处理“中断” = 中断服务程序:ESP32 会立刻跳转去执行一个你预先写好的、专门用来处理这个特定中断的小函数,这个小函数叫 中断服务程序

  • 回来继续 = 中断返回:执行完这个小小的中断服务程序后,ESP32 会精确地回到它刚才主程序被打断的地方,像什么都没发生过一样继续运行主程序。

为什么需要中断?

  • 高效响应:想象一下,如果没有中断,ESP32 想知道按钮有没有被按下,它必须不停地、一遍又一遍地去检查那个按钮引脚的状态(这叫“轮询”)。这就像你每看一行书,就跑到门口看一眼有没有人按门铃,效率非常低!中断让 ESP32 可以专心做自己的事(比如计算、控制设备),只有当“门铃”响了(重要事件发生),它才立刻去处理。

  • 实时性:对于需要立即响应的事件(比如紧急停止按钮),中断能确保最快速度响应,比轮询快得多。

  • 省电:ESP32 可以在主循环里进入低功耗睡眠模式。当中断发生时(比如一个传感器读数准备好了),中断可以唤醒它去处理,处理完再睡回去,大大节省电量。

ESP32 中断的关键概念(简单版):

  1. 中断引脚:不是所有引脚都能产生中断。ESP32 的大部分 GPIO 引脚(0-39)都可以配置为中断源。你需要告诉 ESP32:“当这个引脚发生某种变化时,触发中断”。

  2. 触发方式:你定义什么“变化”会触发中断?

    • RISING:引脚电平从低变高(比如按钮松开)。

    • FALLING:引脚电平从高变低(比如按钮按下)。

    • CHANGE:只要引脚电平发生变化(无论高变低还是低变高)就触发。

    • LOW:只要引脚是低电平就触发(注意:这可能持续触发中断!慎用)。

  3. 中断服务程序:这是你写的一个非常简短的函数。当对应的中断发生时,这个函数就会被自动调用执行。

    • 黄金法则:这个函数必须快进快出!就像你快速处理门口的事情一样。你不能在里面做复杂耗时的操作(比如长时间延时 delay()、打印大量数据、复杂的网络请求)。如果需要做复杂的事,通常在这个函数里设置一个标志位(比如 volatile bool buttonPressed = true;),然后让主程序 loop() 去检查这个标志位并完成复杂操作。

    • 共享变量:如果中断服务程序和主程序要读写同一个变量(比如那个标志位),这个变量必须用 volatile 关键字声明(例如 volatile int counter;)。这告诉编译器:“这个变量随时可能被意外改变(被中断),别做优化,每次都要老老实实去内存里读它的最新值”。

  4. 防抖动:物理按钮在按下或松开时,金属触点会快速弹跳几次,导致引脚电平在短时间内多次快速变化(高-低-高-低),这会让 ESP32 误以为按了很多次。通常需要在硬件(加个小电容)或软件(在中断服务程序里加个小延时 delayMicroseconds(几千) 再检查状态)上做“防抖”处理。

一个超简单的例子(Arduino 框架):

const int buttonPin = 0; // 假设按钮接在 GPIO0 (注意:GPIO0 在启动时有特殊含义,实际项目慎用)
const int ledPin = 2;   // 假设板载LED接在GPIO2

volatile bool buttonPressed = false; // 关键:共享变量用 volatile

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP); // 启用内部上拉电阻,按钮按下时接地变低电平

  // 设置中断!告诉ESP32:
  // 监视 buttonPin (GPIO0)
  // 当它发生 FALLING 边沿(从高变低,即按钮按下)时,
  // 就调用 handleButtonPress 这个函数
  attachInterrupt(digitalPinToInterrupt(buttonPin), handleButtonPress, FALLING);
}

// 中断服务程序 (ISR) - 必须非常简短!
void IRAM_ATTR handleButtonPress() {
  buttonPressed = true; // 只做最简单的事:设置标志位
}

void loop() {
  // 主程序正常做事...
  digitalWrite(ledPin, HIGH); // 比如让LED亮着
  delay(1000);
  digitalWrite(ledPin, LOW);
  delay(1000);

  // 检查中断留下的“便条”(标志位)
  if (buttonPressed) {
    // 主程序来处理复杂响应(比如改变模式、发送通知等)
    Serial.println("Button was pressed!"); // 注意:在ISR里直接Serial.print不好,在主循环里做OK

    // 处理完后,记得清除标志位
    buttonPressed = false;
  }
}

总结一下 ESP32 中断:

  • 它像个“门铃”:让 ESP32 在重要事件发生时能立即暂停手头工作去处理。

  • 核心是“中断服务程序”:一个你写的、专门处理该事件的简短函数。

  • 优点:响应快、效率高、省电(尤其配合睡眠)。

  • 要点

    • 选对引脚触发方式

    • 中断服务程序代码要短

    • 和主程序共享的变量必须加 volatile

    • 注意物理按钮的抖动问题。

理解了这个“门铃”的比喻,你就掌握了 ESP32 中断最核心的思想!实际编程时,记住 attachInterrupt() 函数和保持中断服务程序简短高效的原则,你就可以开始用它来让你的项目更“聪明”地响应外部事件了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FightingFreedom

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值