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;  
}
复制代码

 

posted @   CHHC  阅读(18)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示