Arduino-ESP8266 GPIO(中断或轮询)
检测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 HIGH Serial.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; }
qq:505645074
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律