?? keyscan.c
字號:
/***************************************************************************************************
**
** 按鍵查詢掃描軟件子程序
** 該程序采用在定時器中每間隔10ms掃描一次按鍵狀態,并且通過特定在按鍵“年份”計數器把每次的次數記錄
** 下來,然后在GetKey_Value中進行相應的處理,進而得到相應的鍵值。
** 內存占用:2個字節的按鍵狀態KeyDownF_Flag、KeyDownM_Flag
n個按鍵的字節個“年份”計數器KeyYearCnt[KeyMaxNum]
** 適用范圍:該子程序使用于按鍵接在同一個端口上,并且是連續的情況
** 返回鍵值:返回的按鍵的鍵值和按鍵連接的端口相對應
**----------------------------------------------------------------------------------------------------
** 作 者 : 嚴俊生
** 日 期 : 2007-07-06
** 版本號 :V1.0
**----------------------------------------------------------------------------------------------------
** 修改人 :
** 日 期 :
** 版本號 :
**
****************************************************************************************************/
#include "KeyScan.H"
#define Key_Scan_EN 1
#define KeyDown_Value_EN 1
static _KeyScanStatus KeyScanStatus;
/*******************************************************************************************************
** 名 稱:Key_Scan
** 功 能:本程序是采用查詢的方式來掃描按鍵的,此處是假定KEY鍵全部接在P0口上的,在使用的時候要根據
實際的情況更改。由于此程序是在定時器0#中斷中被調用,所以此處把它定義為可重入函數
** 入口參數:PinValue 按鍵實際連接的物理端口
** 出口參數:無
** 注 意:該程序執行時間的長短與所需要掃描的按鍵數目有關系;
如果在強實時系統上,可以把該定時器0#中斷設為最低優先級;需要強實時的處理在更高的優先級
中斷中進行。
**----------------------------------------------------------------------------------------------------
** 作 者 : 嚴俊生
** 日 期 : 2007-07-06
**----------------------------------------------------------------------------------------------------
** 修改人 :
** 日 期 :
*******************************************************************************************************/
#if Key_Scan_EN
void Key_Scan(unsigned char PinValue) reentrant
{ unsigned char i,keycurval;
// 暫定為P0口接按鍵
keycurval = PinValue;
/*============================= 按鍵掃描處理程序 ==============================*/
for(i=0;i<KeyMaxNum;i++)
{
if(keycurval&0x01)
{
KeyScanStatus.KeyYearCnt[i] = 0; // 按鍵“年份”計數器清0
KeyScanStatus.KeyDownF_Flag &= ( ~(1<<i) ); // 清零單次按鍵狀態
KeyScanStatus.KeyDownM_Flag &= ( ~(1<<i) ); // 清零多次按鍵狀態
}
else KeyScanStatus.KeyYearCnt[i]++; // 按鍵“年份”計數器加1
keycurval = keycurval>>1;
}
}
#endif
/*******************************************************************************************************
** 名 稱:GetKey_Value
** 功 能:本程序根據掃描的結果來判斷按鍵的狀態,是第一次按鍵,還是連擊
** 入口參數:無
** 出口參數:返回按鍵的鍵號,支持多個按鍵同時按下
**----------------------------------------------------------------------------------------------------
** 作 者 : 嚴俊生
** 日 期 : 2007-07-06
**----------------------------------------------------------------------------------------------------
** 修改人 :
** 日 期 :
*******************************************************************************************************/
#if KeyDown_Value_EN
unsigned char GetKey_Value(void)
{ unsigned char i, mm, nn=0, keydownstatus = 0;
for(i=0;i<KeyMaxNum;i++)
{
if( ( (KeyScanStatus.KeyYearCnt[i] > KeyDelayTime)&&((KeyScanStatus.KeyDownF_Flag&(1<<i))==0) ) ||
( (KeyScanStatus.KeyYearCnt[i] > KeyMaxTime) && ((KeyScanStatus.KeyDownM_Flag&(1<<i))==0) ) ||
( (KeyScanStatus.KeyYearCnt[i] > KeyMinTime) &&(KeyScanStatus.KeyDownM_Flag&(1<<i)) ) )
{
keydownstatus |= (1<<i);
// 第一次進入按鍵按下的狀態
if( (KeyScanStatus.KeyYearCnt[i]>KeyDelayTime)&&((KeyScanStatus.KeyDownF_Flag&(1<<i))==0) )
{
KeyScanStatus.KeyYearCnt[i] = 0;
KeyScanStatus.KeyDownF_Flag |= (1<<i);
continue; // 退出本次循環
}
// 多次進入按鍵按下的狀態
if( (KeyScanStatus.KeyYearCnt[i]>KeyMaxTime)&&((KeyScanStatus.KeyDownM_Flag&(1<<i))==0) )
{
KeyScanStatus.KeyYearCnt[i] = 0;
KeyScanStatus.KeyDownM_Flag |= (1<<i);
continue; // 退出本次循環
}
// 已經連擊時候的處理
KeyScanStatus.KeyYearCnt[i] = 0;
}
}
// 進行多個按鍵的判斷,如果已經有多個按鍵處于按下狀態,則返回多個按鍵的鍵號
mm = KeyScanStatus.KeyDownF_Flag;
for(i=0;i<KeyMaxNum;i++)
{
if(mm&0x01) nn++;
mm = (mm>>1);
}
if(nn>1) return KeyScanStatus.KeyDownF_Flag;
else return keydownstatus;
}
#endif
/********************************* End *************************************/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -