检测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; }