/****************************************************************************/
//文 件 名:key.c
//功 能:短擊\連擊
//調(diào)用方法:unsigned char keyValue = ReadKey();
//說 明:該程序不適用于陣列鍵盤.
// 該程序不需要使用定時器.
// 調(diào)用處要加入switch語句來判斷相應(yīng)按鍵按下并執(zhí)行相應(yīng)動作.
// 如需要在按鍵松開后執(zhí)行動作,則調(diào)用函數(shù)需要定義一個bit標志位,在default語句里判斷標志位狀態(tài).
// KEY_WOBBLE_TIME 指程序程序執(zhí)行次數(shù).實際應(yīng)用中要根據(jù)程序的長短來調(diào)整成合適的數(shù)值.
//
//備 注:程序思路是當按鍵被按下時開始計算程序的執(zhí)行次數(shù),如小于KEY_WOBBLE_TIME,則認為按鍵沒有被按下.
// 引用自http://www.rupeng.com/forum/thread-12239-1-1.html,略做更改.
// KEIL編譯時會提示W(wǎng)ARNING C291: not every exit path returns a value.不影響使用.
// 如有朋友發(fā)現(xiàn)問題所在請聯(lián)系我.
/****************************************************************************/
#include <reg52.h>
#define KEY_IO P1 //按鍵所連的IO口
#define NO_KEY_VALUE 0xf //當按鍵沒有被按下時IO口的值
#define KEY_WOBBLE_TIME 150 //去抖動時間(待定)
#define KEY_OVER_TIME 500 //等待進入連擊時間(待定),該常數(shù)要比正常
//按鍵時間要長,防止非目的性進入連擊模式
#define KEY_QUICK_TIME 200 //等待按鍵抬起的連擊時間(待定)
typedef unsigned char uchar;
typedef unsigned int uint;
uchar ReadKey(){ //判斷哪個鍵被按下
static uchar lastKey = NO_KEY_VALUE ;
static uint keyCount = 0;
static uint keyOverTime = KEY_OVER_TIME;
uchar keyTemp = NO_KEY_VALUE ;
keyTemp = KEY_IO & NO_KEY_VALUE ; //讀取鍵值
if(keyTemp == NO_KEY_VALUE ){ //無按鍵按下時
keyCount = 0;
keyOverTime = KEY_OVER_TIME;
return NO_KEY_VALUE ;
}else{ //有按鍵按下時
if(keyTemp==lastKey){
if(++keyCount == KEY_WOBBLE_TIME){ //不是第1次按下判斷抖動是否結(jié)束
return keyTemp; //去抖結(jié)束,返回鍵值
}else{
if(keyCount>keyOverTime){
keyCount = 0;
keyOverTime = KEY_QUICK_TIME;
}
return NO_KEY_VALUE ;
}
}else{ //是第1次按下則保存鍵值,下次執(zhí)行此函數(shù)時與讀到的鍵值作比較
lastKey = keyTemp ; //保存第1次讀到的鍵值
keyCount = 0; //延時計數(shù)器清零
keyOverTime = KEY_OVER_TIME ;
return NO_KEY_VALUE ;
}
}
}
///////////////////////////////////////////////////////////////////////////////////
以上程序例子我用三個按鍵連在P1^0,P1^1,P1^2,使用中根據(jù)實際需要更改
KEY_IO P1 , NO_KEY_VALUE ,KEY_WOBBLE_TIME , KEY_OVER_TIME 500,
#define KEY_QUICK_TIME 200 .
如只需要判斷單擊,把判斷連擊的代碼刪除即可.
拋磚引玉^^