?? rd_usekey._c
字號(hào):
/***********************************************************
* 函數(shù)庫說明:按鍵處理函數(shù)庫 *
* 版本: v2.00 *
* 作者: 傻孩子 *
* 創(chuàng)建日期: 2005年11月27日 *
* -------------------------------------------------------- *
* [支 持 庫] *
* 支持庫名稱:RD_MacroAndConst.h *
* 需要版本: v0.01 &abv *
* 支持庫說明:系統(tǒng)常用宏定義庫 *
* *
* 支持庫名稱:RD_UseKey.h *
* 需要版本: ---- *
* 支持庫說明:按鍵處理聲明庫 *
* -------------------------------------------------------- *
* [版本更新] *
* 修改: 傻孩子 *
* 修改日期: 2006年4月15日 *
* 版本: v1.3 *
* *
* 修改: 傻孩子 *
* 修改日期: 2006年4月23日 *
* 版本: v1.31 *
* *
* 修改: 傻孩子 *
* 修改日期: 2006年5月5日 *
* 版本: v1.32 *
* *
* 修改: 王卓然 *
* 修改日期: 2007年2月25日 *
* 版本: v2.00 *
* -------------------------------------------------------- *
* [版本歷史] *
* v1.3以下 1、提供了對鍵盤緩沖區(qū)的支持。 *
* 2、支持長按鍵處理。 *
* 3、需要外部提供一個(gè)毫秒級(jí)的延時(shí)計(jì)數(shù)器。 *
* 4、需要外部提供一個(gè)有返回值得鍵盤掃描 *
* 函數(shù),該函數(shù)需要做基本的去抖。 *
* 5、可以外部定義緩沖區(qū)大小,空鍵值。 *
* 6、增加了一個(gè)入口鍵盤掃描碼的噪聲抑制參 *
* KEY_PRESS_DELAY,該值為毫秒級(jí)的單向 *
* 遞減數(shù)值,即如果值不為零,則減到0為。 *
* 如果鍵盤響應(yīng)過于遲鈍,可以適當(dāng)改小該 *
* 參數(shù)值。 *
* v1.3 修改了頭文件的組織形式,對外的接口模式 *
* 對一些時(shí)間計(jì)數(shù)器進(jìn)行了分類和統(tǒng)一宏定義 *
* 允許外部通過宏定義將這些接口連接到實(shí)際 *
* 的計(jì)數(shù)器上。同時(shí)兼容從前的版本。 *
* v1.31 修正了按鍵去抖計(jì)數(shù)器會(huì)干擾外部單向計(jì)數(shù) *
* 器的錯(cuò)誤。 *
* v1.32 允許選擇自動(dòng)刷新按鍵和手動(dòng)刷新按鍵兩種模式 *
* v2.00 支持長按鍵以重復(fù)的間隔觸發(fā)。 *
* -------------------------------------------------------- *
* [說明] *
* 1、在外部合適的位置(毫秒中斷程序)增加 *
* USEKEY_INSERT_MS_TIMER_OVF_ISR_CODE來保證 *
* 頭文件的正常使用。 *
* 2、可以通過定義KEY_BUFF_SIZE來設(shè)置鍵盤緩沖區(qū) *
* 的大小。 *
* 3、可以通過定義KEY_PRESS_DELAY來設(shè)置去抖得 *
* 時(shí)間常數(shù)。 *
* 4、可以通過_USE_KEY_PRESS_SCAN_FUNC_INTERFACE *
* 來連接用于鍵盤掃描的函數(shù)。該函數(shù)必須返回 *
* 掃描碼。 *
* 5、通過GetKeyCode()函數(shù)來獲得緩沖區(qū)狀態(tài),當(dāng) *
* 該函數(shù)返回True時(shí),可以從ReturnKeyNum和 *
* ReturnLongPressKeyNum中分別獲取按鍵和長 *
* 按鍵的掃描碼,兩個(gè)值不能同時(shí)不為KeyNull *
* 6、允許通過_USE_KEY_MANUL_REFRESH來選擇自動(dòng)刷 *
* 新按鍵緩沖區(qū)的模式。 *
* 7、可以通過宏_USE_KEY_LONG_PRESS_DELAY_TIME來 *
* 定義長按鍵的最小判定時(shí)間。 *
* 9、可以通過宏_USE_KEY_LONG_PRESS_REPEAT來打開 *
* 長按鍵重復(fù)觸發(fā)功能。 *
* 8、宏_USE_KEY_LONG_KEY_FASTEST_SPEED_LEVEL可 *
* 以用來設(shè)定長按鍵時(shí)重復(fù)觸發(fā)的最小時(shí)間間隔等 *
* 級(jí)。取值范圍是0至4,數(shù)值越大,時(shí)間間隔越小 *
* 默認(rèn)情況下為2,即一秒鐘重復(fù)4次。 *
***********************************************************/
/********************
* 頭 文 件 配 置 區(qū) *
********************/
# include "RD_MacroAndConst.h"
# include "LIB_Config.h"
# include "RD_UseKey.h"
/********************
* 系 統(tǒng) 宏 定 義 *
********************/
/*------------------*
* 常 數(shù) 宏 定 義 *
*------------------*/
#ifndef KEY_BUFF_SIZE
# define KEY_BUFF_SIZE 8
#endif
#ifndef KEY_NULL
# define KEY_NULL 0xff
#endif
#ifndef KEY_PRESS_DELAY
# define KEY_PRESS_DELAY 50
#endif
#ifndef _USE_KEY_LONG_PRESS_DELAY_TIME
# define _USE_KEY_LONG_PRESS_DELAY_TIME 1000
#endif
#ifndef _USE_KEY_LONG_KEY_FASTEST_SPEED_LEVEL
# define _USE_KEY_LONG_KEY_FASTEST_SPEED_LEVEL 2
#endif
#if _USE_KEY_LONG_KEY_FASTEST_SPEED_LEVEL == 0
# define _USE_KEY_LONG_PRESS_FASTEST_SPEED 0x03ff
#elif _USE_KEY_LONG_KEY_FASTEST_SPEED_LEVEL == 1
# define _USE_KEY_LONG_PRESS_FASTEST_SPEED 0x01ff
#elif _USE_KEY_LONG_KEY_FASTEST_SPEED_LEVEL == 2
# define _USE_KEY_LONG_PRESS_FASTEST_SPEED 0x00ff
#elif _USE_KEY_LONG_KEY_FASTEST_SPEED_LEVEL == 3
# define _USE_KEY_LONG_PRESS_FASTEST_SPEED 0x007f
#elif _USE_KEY_LONG_KEY_FASTEST_SPEED_LEVEL == 4
# define _USE_KEY_LONG_PRESS_FASTEST_SPEED 0x003f
#else
# define _USE_KEY_LONG_PRESS_FASTEST_SPEED 0x00ff
#endif
/********************
* 函 數(shù) 聲 明 區(qū) *
********************/
static void _Key_Scan(void);
/********************
* 函 數(shù) 聲 明 區(qū) *
********************/
void Add_Key_Code(void);
unsigned char Get_Key_Code(void);
/********************
* 函 數(shù) 引 用 區(qū) *
********************/
#ifndef _USE_KEY_PRESS_SCAN_FUNC_INTERFACE
# error Need for _USE_KEY_PRESS_SCAN_FUNC_INTERFACE
#else
extern unsigned char _USE_KEY_PRESS_SCAN_FUNC_INTERFACE(void);
#endif
/********************
* 全局變量聲明區(qū) *
********************/
unsigned char g_cReturnKeyNum = KEY_NULL;
unsigned char g_cReturnLongPressKeyNum = KEY_NULL;
unsigned int g_wKeyPressTimeCounter = 0;
unsigned int g_wKeyPressDelayCounter = 0;
/********************
* 模塊變量聲明區(qū) *
********************/
static unsigned char s_cKeyBUFF[KEY_BUFF_SIZE][2];
static unsigned char s_cKeyBUFFCounter = 0;
static unsigned char s_cKeyBUFFHeadPoint = 0;
static unsigned char s_cKeyBUFFTailPoint = 0;
static unsigned char s_cLongKeyPressNum = KEY_NULL;
static unsigned char s_cKeyNum = KEY_NULL;
/***********************************************************
* 函數(shù)說明:按鍵掃描碼處理函數(shù) *
* 輸入: 無 *
* 輸出: 無 *
* 調(diào)用函數(shù):_USE_KEY_PRESS_SCAN_FUNC_INTERFACE() *
* -------------------------------------------------------- *
* [說 明] *
* 按下一個(gè)鍵以后,1s以內(nèi)松開返回短按鍵鍵值 *
* 1s以上返回長按鍵鍵值。鍵值只保存一個(gè)周期 *
***********************************************************/
static void _Key_Scan(void)
{
static unsigned char OldKeyCode = KEY_NULL;
static unsigned char IfLongKeyPress = FALSE;
static unsigned int LongPressAcceleration = 0;
unsigned char NowKeyCode = _USE_KEY_PRESS_SCAN_FUNC_INTERFACE();
s_cKeyNum = KEY_NULL;
if ((OldKeyCode != NowKeyCode) && (g_wKeyPressDelayCounter == 0))
{
g_wKeyPressTimeCounter = 0;
LongPressAcceleration = 0x01ff;
if ((NowKeyCode == KEY_NULL) && (IfLongKeyPress == FALSE))
{
s_cKeyNum = OldKeyCode;
}
g_wKeyPressDelayCounter = KEY_PRESS_DELAY;
OldKeyCode = NowKeyCode;
IfLongKeyPress = FALSE;
}
else
{
s_cKeyNum = KEY_NULL;
if ((g_wKeyPressTimeCounter > _USE_KEY_LONG_PRESS_DELAY_TIME) && (IfLongKeyPress == FALSE))
{
#ifdef _USE_KEY_LONG_PRESS_REPEAT
if (LongPressAcceleration > _USE_KEY_LONG_PRESS_FASTEST_SPEED)
{
LongPressAcceleration >>= 1;
}
#endif
s_cLongKeyPressNum = NowKeyCode;
IfLongKeyPress = TRUE;
}
else
{
#ifdef _USE_KEY_LONG_PRESS_REPEAT
if (!(g_wKeyPressTimeCounter & LongPressAcceleration))
{
IfLongKeyPress = FALSE;
}
else
{
s_cLongKeyPressNum = KEY_NULL;
}
#else
s_cLongKeyPressNum = KEY_NULL;
#endif
}
}
}
/***********************************************************
* 函數(shù)說明:鍵盤緩沖處理函數(shù) *
* 輸入: 無 *
* 輸出: 無 *
* 調(diào)用函數(shù):_Key_Scan() *
***********************************************************/
void Add_Key_Code(void)
{
_Key_Scan();
if ((s_cKeyNum == KEY_NULL) && (s_cLongKeyPressNum == KEY_NULL))
{
return ;
}
if ((s_cKeyBUFFHeadPoint == s_cKeyBUFFTailPoint) && (s_cKeyBUFFCounter != NULL))
{
return ;
}
s_cKeyBUFF[s_cKeyBUFFTailPoint][0] = s_cKeyNum;
s_cKeyBUFF[s_cKeyBUFFTailPoint][1] = s_cLongKeyPressNum;
s_cKeyBUFFTailPoint ++;
if (s_cKeyBUFFTailPoint == KEY_BUFF_SIZE)
{
s_cKeyBUFFTailPoint = 0;
}
s_cKeyBUFFCounter ++;
}
/***********************************************************
* 函數(shù)說明:從鍵盤緩沖區(qū)中獲得一個(gè)按鍵掃描碼 *
* 輸出: 返回操作是否成功TRUE / FALSE *
* 輸入: 無 *
* 調(diào)用函數(shù):Add_Key_Code() *
* -------------------------------------------------------- *
* [說 明] *
* 將按鍵掃描碼放到專門的臨時(shí)緩沖變量中 *
***********************************************************/
unsigned char Get_Key_Code(void)
{
g_cReturnKeyNum = KEY_NULL;
g_cReturnLongPressKeyNum = KEY_NULL;
#ifdef _USE_KEY_MANUL_REFRESH
Add_Key_Code();
#endif
if ((s_cKeyBUFFHeadPoint == s_cKeyBUFFTailPoint) && (s_cKeyBUFFCounter == NULL))
{
return FALSE;
}
g_cReturnKeyNum = s_cKeyBUFF[s_cKeyBUFFHeadPoint][0];
g_cReturnLongPressKeyNum = s_cKeyBUFF[s_cKeyBUFFHeadPoint][1];
s_cKeyBUFFCounter--;
s_cKeyBUFFHeadPoint++;
if (s_cKeyBUFFHeadPoint == KEY_BUFF_SIZE)
{
s_cKeyBUFFHeadPoint = 0;
}
return TRUE;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -