《ESP8266学习笔记》之 采用定时器内的按键扫描方法,摒弃传统的延时按键消抖

  • 简介:传统的按键扫描程序,大部分都是采用 delay_ms(5); 这样的语句来进行按键消抖,但当你把它放在你高速运行的程序中时,这5ms可能会拖慢你的成语运行,导致体验感受下降,因此,我便找到了新的按键扫描思想,并将这一思想移植到ESP8266中以便后续工程使用!
  • 这种新的按键扫描思想并不复杂,你需要定义一个 1ms 的定时器,在定时器中判断按键状态,如果按键按下,则按键的检测按下次数 加一,最后将 按键的检测按下次数  乘以 1ms 则可以得到按键按下时间,如果检测到按键松开,则令按键的检测按下次数  归零,这样一来,我们便可以实现按键的 短按&&长按。
  •  接下来看下例子吧!
/*
*@作者:刘泽文
*@功能:四个按键,放在定时器里边的按键扫描程序,防止拖慢程序
*@时间:2020/3/15
 */

#include <Ticker.h>
#include <ESP8266WiFi.h>

//LED和按键引脚定义
#define LED         D4 //gpio2
#define UP_KEY      D6 //gpio12
#define M_KEY       D5 //gpio14
#define DOWN_KEY    D7 //gpio13
#define WAKE_UP     D3 //gpio0

//读按键值
#define KEYU      digitalRead(UP_KEY)
#define KEYM      digitalRead(M_KEY)
#define KEYD      digitalRead(DOWN_KEY)
#define KEYW      digitalRead(WAKE_UP)

#define LED_OFF   digitalWrite(LED, HIGH)//关灯
#define LED_ON    digitalWrite(LED, LOW)//开灯
#define LED_PWM   digitalWrite(LED, !digitalRead(LED))//灯闪烁

#define short_press_time 10     //短按时间
#define long_press_time 1000    //长按时间

#define NO_KEY_PRES     0   //无按键按下

#define UP_KEY_PRES     1
#define M_KEY_PRES      2
#define DOWN_KEY_PRES   3
#define WAKE_UP_PRES    4

#define UP_KEY_LONG_PRES     11
#define M_KEY_LONG_PRES      22
#define DOWN_KEY_LONG_PRES   33
#define WAKE_UP_LONG_PRES    44

uint16_t KEYU_PRESS_COUNT = 0;//按KEYU时间计数
uint16_t KEYM_PRESS_COUNT = 0;//按KEYM时间计数
uint16_t KEYD_PRESS_COUNT = 0;//按KEYD时间计数
uint16_t KEYW_PRESS_COUNT = 0;//按KEYW时间计数

bool KEYU_UP = 0;//按键状态,0为弹起,1为按下
bool KEYM_UP = 0;//按键状态,0为弹起,1为按下
bool KEYD_UP = 0;//按键状态,0为弹起,1为按下
bool KEYW_UP = 0;//按键状态,0为弹起,1为按下

uint8_t KEYU_KEY_READ = NO_KEY_PRES;//KEYU按键状态
uint8_t KEYM_KEY_READ = NO_KEY_PRES;//KEYM按键状态
uint8_t KEYD_KEY_READ = NO_KEY_PRES;//KEYD按键状态
uint8_t KEYW_KEY_READ = NO_KEY_PRES;//KEYW按键状态

Ticker key_tick;

/*
*@定时器里边检测按键状态并计数
*/
void flip() {
  //UP_KEY
  if(KEYU==0){
    KEYU_PRESS_COUNT++;
    KEYU_UP = 1;
    if(KEYU_PRESS_COUNT<=short_press_time)
      KEYU_KEY_READ = NO_KEY_PRES;
    if(KEYU_PRESS_COUNT>=short_press_time&&KEYU_PRESS_COUNT<=long_press_time)
      KEYU_KEY_READ = UP_KEY_PRES;
    if(KEYU_PRESS_COUNT>=long_press_time)
      KEYU_KEY_READ = UP_KEY_LONG_PRES;
  }
  if(KEYU){
    KEYU_PRESS_COUNT = 0;
    KEYU_UP = 0;//按键状态,0为弹起,1为按下
  }
  //M_KEY
  if(KEYM==0){
    KEYM_PRESS_COUNT++;
    KEYM_UP = 1;
    if(KEYM_PRESS_COUNT<=short_press_time)
      KEYM_KEY_READ = NO_KEY_PRES;
    if(KEYM_PRESS_COUNT>=short_press_time&&KEYM_PRESS_COUNT<=long_press_time)
      KEYM_KEY_READ = M_KEY_PRES;
    if(KEYM_PRESS_COUNT>=long_press_time)
      KEYM_KEY_READ = M_KEY_LONG_PRES;
  }
  if(KEYM){
    KEYM_PRESS_COUNT = 0;
    KEYM_UP = 0;//按键状态,0为弹起,1为按下
  }
  //DOWN_KEY
  if(KEYD==0){
    KEYD_PRESS_COUNT++;
    KEYD_UP = 1;
    if(KEYD_PRESS_COUNT<=short_press_time)
      KEYD_KEY_READ = NO_KEY_PRES;
    if(KEYD_PRESS_COUNT>=short_press_time&&KEYD_PRESS_COUNT<=long_press_time)
      KEYD_KEY_READ = DOWN_KEY_PRES;
    if(KEYD_PRESS_COUNT>=long_press_time)
      KEYD_KEY_READ = DOWN_KEY_LONG_PRES;
  }
  if(KEYD){
    KEYD_PRESS_COUNT = 0;
    KEYD_UP = 0;//按键状态,0为弹起,1为按下
  }
  //WAKE_UP
  if(KEYW==0){
    KEYW_PRESS_COUNT++;
    KEYW_UP = 1;
    if(KEYW_PRESS_COUNT<=short_press_time)
      KEYW_KEY_READ = NO_KEY_PRES;
    if(KEYW_PRESS_COUNT>=short_press_time&&KEYW_PRESS_COUNT<=long_press_time)
      KEYW_KEY_READ = WAKE_UP_PRES;
    if(KEYW_PRESS_COUNT>=long_press_time)
      KEYW_KEY_READ = WAKE_UP_LONG_PRES;
  }
  if(KEYW){
    KEYW_PRESS_COUNT = 0;
    KEYW_UP = 0;//按键状态,0为弹起,1为按下
  }

  if(KEYU_KEY_READ == UP_KEY_LONG_PRES && KEYU_UP == 0){
    LED_PWM;
    Serial.println("--KEYU_UP长按");
    KEYU_KEY_READ = NO_KEY_PRES;
  }

  if(KEYU_KEY_READ == UP_KEY_PRES && KEYU_UP == 0){
    LED_PWM;
    Serial.println("----KEYU_UP短按");
    KEYU_KEY_READ = NO_KEY_PRES;
  }

  if(KEYM_KEY_READ == M_KEY_LONG_PRES && KEYM_UP == 0){
    LED_PWM;
    Serial.println("------KEYM_UP长按");
    KEYM_KEY_READ = NO_KEY_PRES;
  }

  if(KEYM_KEY_READ == M_KEY_PRES && KEYM_UP == 0){
    LED_PWM;
    Serial.println("--------KEYM_UP短按");
    KEYM_KEY_READ = NO_KEY_PRES;
  }

  if(KEYD_KEY_READ == DOWN_KEY_LONG_PRES && KEYD_UP == 0){
    LED_PWM;
    Serial.println("------------KEYD_UP长按");
    KEYD_KEY_READ = NO_KEY_PRES;
  }

  if(KEYD_KEY_READ == DOWN_KEY_PRES && KEYD_UP == 0){
    LED_PWM;
    Serial.println("--------------KEYD_UP短按");
    KEYD_KEY_READ = NO_KEY_PRES;
  }

  if(KEYW_KEY_READ == WAKE_UP_LONG_PRES && KEYW_UP == 0){
    LED_PWM;
    Serial.println("----------------KEYW_UP长按");
    KEYW_KEY_READ = NO_KEY_PRES;
  }

  if(KEYW_KEY_READ == WAKE_UP_PRES && KEYW_UP == 0){
    LED_PWM;
    Serial.println("------------------KEYW_UP短按");
    KEYW_KEY_READ = NO_KEY_PRES;
  }
}

void setup()
{
  Serial.begin(9600);
  pinMode(M_KEY,INPUT_PULLUP);
  pinMode(LED,OUTPUT);
  LED_OFF;//灭灯
  key_tick.attach_ms(1, flip);//按键检测定时器(1ms)
}

void loop()
{
  delay(10*1000);
  LED_PWM; //闪灯
}
  • 打开你的串口监视器(波特率:9600),按下你的按键看看效果吧~

发布了19 篇原创文章 · 获赞 24 · 访问量 4816

猜你喜欢

转载自blog.csdn.net/qq_41868901/article/details/104871777
今日推荐