

检测GPIO高低电平
1. 中断
2. 轮询
gpio.ino

// ============ GPIO按键输入 ============// 监听高电平接线图
// ESP8266 NodeMCU
// ┌───────────┐
// │ D1(GPIO5) │──────┤按键一端
// │ │ │
// │ 3V3 │──────┤按键另一端
// └───────────┘// 监听低电平接线图
// ESP8266 NodeMCU
// ┌───────────┐
// │ D1(GPIO5) │──────┤按键一端
// │ │ │
// │ GND │──────┤按键另一端
// └───────────┘#include "button.h" // 添加按钮头文件
#include "gpioinput.h" #define ISR_PREFIX ICACHE_RAM_ATTR
Button button1(D1); // 中断模式,监听高电平信号
GPIOInput button2(D2, 20, 5);// 轮询模式void setup() {Serial.begin(9600); // 先初始化串口Serial.println("MCU RUN"); // 再输出信息button1.setCallback([](){ if (HIGH == digitalRead(D1)) {Serial.printf("Button1 Pressed,%d\n", digitalRead(D1));} });button1.begin();
}void loop() { int val = button2.read();if (val == LOW) { // LOW HIGHSerial.println("按钮按下!"); } delay(100);
}

button.h

#ifndef Button_H
#define Button_H#include <Arduino.h>
#include <functional>class Button {
public:typedef std::function<void()> Callback;Button(uint8_t pin);void begin();void setCallback(Callback cb);private:uint8_t pin;Callback pressedCallback;static Button* instance;static void IRAM_ATTR isrHandler();
};#endif

button.cpp

#include "Button.h"Button* Button::instance = nullptr;Button::Button(uint8_t pin) : pin(pin) {instance = this;
}void Button::setCallback(Callback cb) {pressedCallback = cb;
}void Button::begin() {pinMode(pin, INPUT_PULLUP);// INPUT(输入) OUTPUT(输出) INPUT_PULLUP(上拉输入) INPUT_PULLDOWN(下拉输入)attachInterrupt(digitalPinToInterrupt(pin), isrHandler, CHANGE);// RISING(上升沿L->H) FALLING(下降沿H->L) CHANGE(改变时)
}void IRAM_ATTR Button::isrHandler() { Serial.printf("Current Value,%d\n", digitalRead(D1));// 硬件去抖处理(通过使用电容器和电阻器电路来进行去抖动) if (instance->pressedCallback) {instance->pressedCallback();}
}

gpioinput.h

#ifndef GPIOINPUT_H
#define GPIOINPUT_H #include <Arduino.h> class GPIOInput {
public: // 构造函数 GPIOInput(int pin, int checkInterval, int checkCount);// 轮询方法, 返回当前状态 int read(); private:int pin = 0;int checkInterval = 0;int checkIndex = -1;int checkCount = 0;long checkTime = 0; int stateOld = 0;int stateTemp = 0;
}; #endif // GPIOINPUT_H

gpioinput.cpp

#include "gpioinput.h" // 构造函数
GPIOInput::GPIOInput(int pin, int checkInterval, int checkCount) : pin(pin), checkInterval(checkInterval), checkCount(checkCount) {pinMode(pin, INPUT); stateOld = stateTemp = digitalRead(pin);Serial.println("pin input:" + String(pin));
} // 轮询读取引脚状态
int GPIOInput::read() { if ((0 != checkIndex) && (millis() - checkTime) <= checkInterval) return -1;// 过滤中间时段的数据int state = digitalRead(pin); if (state != stateTemp){checkIndex = 0;stateOld = stateTemp;}else{if (state != stateOld){checkIndex++;checkTime = millis();}}stateTemp = state;int ret = -1; if (checkIndex == checkCount) {checkIndex = 0;if (stateOld != state) {stateOld = state;ret = state;}}return ret;
}
