#include "key.h"
/**********************************************************************
*函數(shù)名:KEY_init
*功 能:按鍵初始化
*參 數(shù):無
*返 回:無
*備 注:
KEY ---- PA0
**********************************************************************/
void KEY_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能PA時鐘
GPIO_InitTypeDef GPIO_InitStructure; //定義結(jié)構(gòu)體變量
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空輸入模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
/****************************************************************
驅(qū)動層
1.完成按鍵的消抖,松手檢測
2.把過程細分為一個個狀態(tài)
3.實現(xiàn)長按與單擊功能
按鍵初始態(tài) 0
按鍵消抖與確認態(tài) 1
按鍵的單擊和長按狀態(tài) 2
等待按鍵釋放狀態(tài) 3
*****************************************************************/
u8 key_driver()
{
static unsigned char state = 0, time = 0; //靜態(tài)變量具有記憶性,不會再讀取這里的賦值
unsigned char key_return = N_key; //不用靜態(tài),避免按鍵釋放的時候回不到無鍵狀態(tài)
switch (state)
{
case 0: // 按鍵初始態(tài)
if (!KEY) state = 1; // 鍵被按下是0,非0即真,狀態(tài)轉(zhuǎn)換到按鍵消抖和確認狀態(tài) 1
break;
case 1: // 按鍵消抖與確認態(tài)
if (!KEY) // 再次確認按鍵是否按下
{
time = 0; // 按鍵按下,開始計時
state = 2; // 按鍵仍然處于按下,消抖完成,狀態(tài)轉(zhuǎn)換到按下鍵時間的計時狀態(tài),但返回的還是無鍵事件
}
else
state = 0; // 按鍵已抬起,轉(zhuǎn)換到按鍵初始態(tài)。此處完成和實現(xiàn)軟件消抖,其實按鍵的按下和釋放都在此消抖的。
break;
case 2:
if(KEY) //前面確認按鍵按下后,此時按鍵釋放為1
{
key_return = S_key; // 此時按鍵釋放,說明是產(chǎn)生一次短操作,返回S_key
state = 0; // 轉(zhuǎn)換到按鍵初始態(tài)
}
else if (++time >= 100) // 繼續(xù)按下,
{
key_return = L_key; //
state = 3; // 轉(zhuǎn)換到等待按鍵釋放狀態(tài)
}
break;
case 3: // 等待按鍵釋放狀態(tài),此狀態(tài)只返回無按鍵事件
if (KEY) state = 0; // 按鍵已釋放,轉(zhuǎn)換到按鍵初始態(tài)
break;
}
return key_return;
}
u8 key_read(void)
{
static u8 key_m=key_state_0, key_time_1=0;
u8 key_return=0,key_temp;
key_temp=key_driver();
switch(key_m)
{
case key_state_0:
if(key_temp==S_key)
{
key_time_1=0; // 第1次單擊,不返回,到下個狀態(tài)判斷后面是否出現(xiàn)雙擊
key_m=key_state_1;
}
else
key_return=key_temp; // 對于無鍵、長鍵,返回原事件
break;
case key_state_1:
if(key_temp==S_key) // 又一次單擊(間隔肯定<500ms)
{
key_return=D_key; // 返回雙擊鍵事件,回初始狀態(tài)
key_m=key_state_0;
}
else
{ // 這里500ms內(nèi)肯定讀到的都是無鍵事件,因為長鍵>1000ms,在1s前低層返回的都是無鍵
if(++key_time_1>=50)
{
key_return=S_key; // 500ms內(nèi)沒有再次出現(xiàn)單鍵事件,返回上一次的單鍵事件
key_m=key_state_0; // 返回初始狀態(tài)
}
}
break;
}
return key_return;
}
|