|
//頭文件(.h)
#ifndef __KEY__
#define __KEY__
#define DEBUG_KEY //key文件的調(diào)試開關(guān)
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;
//按鍵掃描狀態(tài)
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文件
/****************************************
版權(quán):微信:mcu6666
PS:承接單片機(jī)開發(fā)項(xiàng)目
*****************************************/
#include "..\Public\CH554.H"
#include "..\Public\Debug.H"
#include "key.h"
#include "UART1.H"
TASK_KEY_STATU_ST gstKey1 = {0};
/***********************************************
功能:按鍵掃描
作者:jzb2019年12月27日
備注:50ms運(yùn)行一次這個函數(shù),理論上可以擴(kuò)展到n連擊
最大響應(yīng)延時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);//如果沒有計數(shù)則證明是毛刺濾掉
}
else
{
Switch_KeyState(KEY_FIRST);//轉(zhuǎn)到第一次按下狀態(tài)
}
}
}
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)//沒有計數(shù)證明是沒有釋放按鍵的動作
{
}
else//這個分支里面已經(jīng)是第二次按下了
{
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;
}
}
/****************************************************************************
功能:執(zhí)行切換狀態(tài)的動作,同時清掉當(dāng)前狀態(tài)內(nèi)的計數(shù)
入口:要切換的狀態(tài)
作者:jzb 2019年12月27日
備注:暫時先不考慮通用的問題,直接操作全局變量如果擴(kuò)展按鍵再說
*****************************************************************************/
void Switch_KeyState(unsigned char state)
{
gstKey1.CntDly = 0;
gstKey1.Statu = state;
}
|
評分
-
查看全部評分
|