ESP8266Arduino编程实例中断
ESP8266-Arduino编程实例-中断
中断
本文将演示如何使用 ESP8266 NodeMCU 的中断和定时器。 中断检测 GPIO 状态的变化且无需不断检查其当前值。通过使用中断,当检测到更改时,会触发事件(调用函数)。
在实例中,使用 PIR 运动传感器检测运动:当检测到运动时,ESP8266 会启动一个定时器并打开 LED 预定义的秒数。 当计时器完成倒计时,LED 会自动关闭。
1、ESP8266中断介绍
中断对于在微控制器程序中使事情自动发生很有用,并且可以帮助解决时序问题。
使用中断,您无需不断检查当前引脚值。 当检测到变化时,会触发一个事件——调用一个函数。 该函数称为中断服务程序(ISR)。
当中断发生时,处理器停止执行主程序执行任务,进入中断服务程序,中断服务程序执行完成后再返回到主程序,如下图所示。

ESP8266 支持任何 GPIO 中的中断,但 GPIO16 除外。
要创建中断,需要调用 attachInterrupt() 并将 GPIO 中断引脚、ISR(要调用的函数)和模式作为参数传递。 ISR 函数必须声明 ICACHE_RAM_ATTR 属性。 模式可以是 CHANGE、RISING 或 FALLING。
1 | attachInterrupt(digitalPinToInterrupt(GPIO), ISR, mode); |
函数的第一个参数是 GPIO 中断。需要应该使用 digitalPinToInterrupt(GPIO)函数 将实际的 GPIO 设置为中断引脚。 例如,将 GPIO 14 作为中断:
1 | digitalPinToInterrupt(14) |
函数的第二个参数是中断服务程序ISR(Interrupt Service Routine)。ISR 功能应该尽可能简单,以便处理器快速返回主程序的执行。
最好的方法是使用全局变量向主代码发出中断已经发生的信号,并在 loop() 中检查并清除该标志,然后执行代码。
ISR 需要在函数定义之前有 IRAM_ATTR 才能在 RAM 中运行中断代码。
函数的第三个参数是中断触发模式。ESP8266支持以下三种中断触发模式:
- CHANGE:每当引脚改变值时触发中断——例如从高到低或从低到高;
- FALLING:当引脚从 HIGH 变为 LOW 时;
- RISING:当引脚从 LOW 变为 HIGH 时触发。
在本次演示实例中,将使用 RISING 模式,因为当 PIR 运动传感器检测到运动时,它所连接的 GPIO 会从 LOW 变为 HIGH。
2、硬件准备
- ESP8266 NodeMCU开发板一块
- PIR运动传感器一个
- LED一个
- 220欧姆电阻一个
- 杜邦线若干
- 数据线一条
3、软件准备
- Arduino IDE或VSCode + PlatformIO
在前面的文章中,对如何搭建ESP8266开发环境做了详细的介绍,请参考:
ESP8266 NodeMCU的引脚介绍在前面的文章中做了详细的介绍,请参考:
4、硬件电路接线图

引脚D5(GPIO14)与PIR的信号引脚连接;引脚D6(GPIO12)与LED引脚连接。
5、代码实现
1 | #include <Arduino.h> |
6、代码解析
首先,定义引脚
1 | const int led = 12; |
接下来,创建计数辅助变量
1 | unsigned long now = millis(); |
变量now储存当前时间;变量lastTrigger保存PIR传感器最后触发时间;变量startTimer标志当前计时器时运是否开始,当PIR触发时,设置true,计时完成后设置为false。
接下来,定义中断服务函数
1 | ICACHE_RAM_ATTR void detectsMovement() { |
接下来,在setup函数中设置串口
1 | Serial.begin(115200); |
设置PIR引脚和LED引脚
1 | pinMode(motionSensor, INPUT_PULLUP); |
设置GPIO中断服务
1 | attachInterrupt(digitalPinToInterrupt(motionSensor), detectsMovement, RISING); |
设置LED
1 | // 设置LED引脚为输出 |
最后,在loop函数中,进行计数
1 | if(startTimer && (now - lastTrigger > (timeSeconds\*1000))) { |
文章来源: https://iotsmart.blog.csdn.net/article/details/126006866