

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

&spm=1001.2101.3001.5002&articleId=145688192&d=1&t=3&u=f6b827ae58594615aca15976ae2bd0b0)
6053

被折叠的 条评论
为什么被折叠?



