- 简介:传统的按键扫描程序,大部分都是采用 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(UP_KEY,INPUT_PULLUP);
pinMode(M_KEY,INPUT_PULLUP);
pinMode(DOWN_KEY,INPUT_PULLUP);
pinMode(WAKE_UP,INPUT_PULLUP);
pinMode(LED,OUTPUT);
LED_OFF;//灭灯
key_tick.attach_ms(1, flip);//按键检测定时器(1ms)
}
void loop()
{
delay(10*1000);
LED_PWM; //闪灯
}
- 打开你的串口监视器(波特率:9600),按下你的按键看看效果吧~