// 初始化按键
void Key_State_Init(KEY* key) {
key->state = KEY_STATE_IDLE;
key->isLongPress = false;
}
// 检测按键状态
KeyEvent Check_Key(KEY* key, bool isPressed)
{
KeyEvent event = KEY_EVENT_NONE;
static char passtimes=0;
// currentTime++;
static bool realpress=0;
if(isPressed)
{
if(++passtimes>=2)
{
realpress=1;
}
}else
{
passtimes=0;
realpress=0;
}
key->currentTime++;
switch (key->state)
{
case KEY_STATE_IDLE:
if (realpress) {
key->state = KEY_STATE_PRESSED;
key->pressTime = key->currentTime;
key->isLongPress = false;
}
break;
case KEY_STATE_PRESSED:
if (realpress) // 检测是否是长按
{
if (((key->currentTime)-(key->pressTime)) >= 400) { // 长按时间阈值设为2秒
key->isLongPress = true;
key->state = KEY_WAIT_RELEASED;//自加
event = KEY_EVENT_LONG_PRESS;
}
} else
{
key->state = KEY_WAIT_RELEASED;
//key->state = KEY_STATE_WAITING_DOUBLE_CLICK;需要双击判断再放出来
event = KEY_EVENT_CLICK;//超时触发单击
key->releaseTime = key->currentTime;
}
break;
case KEY_STATE_WAITING_DOUBLE_CLICK:
if (realpress)
{
//计算时间差是否触发双击
if (((key->currentTime)-(key->releaseTime)) <= 30)
{ // 双击时间阈值设为
key->state = KEY_WAIT_RELEASED;
event = KEY_EVENT_DOUBLE_CLICK;
}
} else if(((key->currentTime)-(key->releaseTime))>30)
{
event = KEY_EVENT_CLICK;//超时触发单击
key->state = KEY_WAIT_RELEASED;
}
break;
case KEY_WAIT_RELEASED:
if (!realpress)
{
key->state = KEY_STATE_IDLE;
}
break;
}
return event;
}
#ifndef __KEY_H
#define __KEY_H
#include <stdbool.h>
#include "stm32f10x.h"
#define KEY1 (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0))
// 返回事件
typedef enum {
KEY_EVENT_NONE, // 无事件
KEY_EVENT_CLICK, // 单击
KEY_EVENT_DOUBLE_CLICK,// 双击
KEY_EVENT_LONG_PRESS// 长按
} KeyEvent;
// 按键状态
typedef enum {
KEY_STATE_IDLE, // 空闲
KEY_STATE_PRESSED, // 按下
KEY_STATE_RELEASED,// 松开
KEY_STATE_WAITING_DOUBLE_CLICK,// 等待双击
KEY_WAIT_RELEASED //等待放开
} KeyState;
// ?????
typedef struct {
KeyState state; // ????
int pressTime; // ????
int releaseTime;// ????
int isLongPress; // ????
int currentTime;
} KEY;
void Key_Init(KEY* key);
KeyEvent Check_Key(KEY* key, bool isPressed);
#endif