//头文件(.h)
#ifndef __KEY__
#define __KEY__
#define DEBUG_KEY //key文件的调试开关
sbit KEY1 = P1^0;
#define KEY_DOWN 0
#define KEY_UP 1
//按键值
typedef enum
{
NONE_CLICK = 0,
SINGLE_CLICK ,
DOUBLE_CLICK,
LONG_PRESS,
NUM_KEY,
}KEY_VALUE_EN;
typedef enum
{
KEY_IDLE = 0,
KEY_FILTER,
KEY_FIRST, //第一次按下
KEY_CHECK_FREE,//抬起检测(长按)
NUM_KEY_STAUS,
}KEY_STATUS_EN;
//按键扫描状态
typedef struct
{
unsigned char Statu;
unsigned char CntDly;
unsigned char KeyValue;
}TASK_KEY_STATU_ST;
void Task_Keyscan(void);
void Switch_KeyState(unsigned char state);
#endif
//.C文件
/****************************************
版权:微信:mcu6666
PS:承接单片机开发项目
*****************************************/
#include "..\Public\CH554.H"
#include "..\Public\Debug.H"
#include "key.h"
#include "UART1.H"
TASK_KEY_STATU_ST gstKey1 = {0};
/***********************************************
功能:按键扫描
作者:jzb2019年12月27日
备注:50ms运行一次这个函数,理论上可以扩展到n连击
最大响应延时500ms(单击时)
***********************************************/
void Task_Keyscan(void)
{
switch (gstKey1.Statu)
{
case KEY_IDLE:
{
if(KEY1 == KEY_DOWN)
{
Switch_KeyState(KEY_FILTER);//按键按下了去抖
}
}
break;
case KEY_FILTER:
{
if(KEY1 == KEY_DOWN)
{
gstKey1.CntDly++;
if(gstKey1.CntDly >= 60)
{
gstKey1.KeyValue = LONG_PRESS;//长按
#ifdef DEBUG_KEY
UART1_SendString("LONG_PRESS\n");
#endif
Switch_KeyState(KEY_CHECK_FREE);//抬起检测
}
}
else
{
if(gstKey1.CntDly == 0)
{
Switch_KeyState(KEY_IDLE);//如果没有计数则证明是毛刺滤掉
}
else
{
Switch_KeyState(KEY_FIRST);//转到第一次按下状态
}
}
}
break;
case KEY_FIRST:
{
if(KEY1 == KEY_UP)//释放了
{
gstKey1.CntDly++;
if(gstKey1.CntDly > 10)//500ms
{
gstKey1.KeyValue = SINGLE_CLICK;
#ifdef DEBUG_KEY
UART1_SendString("SINGLE\n");
#endif
Switch_KeyState(KEY_IDLE);//回到空闲
}
}
else//按下了
{
if(gstKey1.CntDly == 0)//没有计数证明是没有释放按键的动作
{
}
else//这个分支里面已经是第二次按下了
{
gstKey1.KeyValue = DOUBLE_CLICK;
#ifdef DEBUG_KEY
UART1_SendString("DOUBLE\n");
#endif
Switch_KeyState(KEY_CHECK_FREE);//抬起检测
}
}
}
break;
case KEY_CHECK_FREE:
{
if(KEY1 == KEY_UP)
{
Switch_KeyState(KEY_IDLE);
}
}
break;
default :
{
Switch_KeyState(KEY_IDLE);
}
break;
}
}
/****************************************************************************
功能:执行切换状态的动作,同时清掉当前状态内的计数
入口:要切换的状态
作者:jzb 2019年12月27日
备注:暂时先不考虑通用的问题,直接操作全局变量如果扩展按键再说
*****************************************************************************/
void Switch_KeyState(unsigned char state)
{
gstKey1.CntDly = 0;
gstKey1.Statu = state;
}
|