📄 key.c
字号:
/********************************************************************************************
键盘扫描模块
说明:
本键盘扫描模块使用的是查询式键盘,MCU的一个IO引脚接一个按键(不是通常的矩阵键盘),
这种键盘适用于按键较少的嵌入式设备。
开发平台:
Winbond 77E58
Keil C 7.0
开发过程:
2005-2-17 13:27 开始编写
2005-2-22 15:48 完成,调试通过
2005-4-4 9:32 更新,增加了键盘读取端口函数,增强可移植性。调试通过
********************************************************************************************/
#include "..\..\includes.h"
#if CFG_KEY_EN > 0
// 键盘扫描状态定义
#define KEY_STATE_UP 1
#define KEY_STATE_DEBOUNCE 2
#define KEY_STATE_RPT_START_DLY 3
#define KEY_STATE_RPT_DLY 4
static INT16U KeyDlyCtr; // 键盘扫描延迟计数器
static INT8U KeyRptStartDlyCtr; // 启动按键自动重复延迟计数器
static INT8U KeyRptDlyCtr; // 按键自动重复延迟计数器
static INT8U KeyScanState; /* Current state of key scanning function */
static KEY_PORT_VALUE_TYPE key_port_value;
static INT8U KeyDecode(void); /* Get scan code from current key pressed */
static BOOLEAN KeyIsKeyDown(void); /* See if key has been pressed */
static KEY_PORT_VALUE_TYPE KeyReadKeyPort(void);
//-----------------------------------------------------------------------------
// 键盘初始化
//-----------------------------------------------------------------------------
extern void KeyInit(void)
{
KeyScanState = KEY_STATE_UP;
KeyDlyCtr = KEY_SCAN_DLY;
KeyRptStartDlyCtr = KEY_RPT_START_DLY;
KeyRptDlyCtr = KEY_RPT_DLY;
}
//-----------------------------------------------------------------------------
// 键盘扫描
//
// 出口:
// 如果有键按下,函数返回TRUE,用形参*keyScanCode返回按键编码
// 如果没有键按下,函数返回FALSE,形参*keyScanCode无定义
//-----------------------------------------------------------------------------
extern BOOLEAN KeyScan( INT8U *keyScanCode )
{
BOOLEAN isPressKey;
--KeyDlyCtr;
if( KeyDlyCtr > 0 ) // 键盘扫描的延迟时间还没有到
return FALSE;
// 键盘扫描的延迟时间到,重新置数,以便下一次的延迟计数
KeyDlyCtr = KEY_SCAN_DLY ;
isPressKey = FALSE;
switch( KeyScanState )
{
case KEY_STATE_UP:
if( KeyIsKeyDown() )
{
KeyScanState = KEY_STATE_DEBOUNCE;
}
break;
case KEY_STATE_DEBOUNCE:
if( KeyIsKeyDown() )
{
KeyRptStartDlyCtr = KEY_RPT_START_DLY;
KeyScanState = KEY_STATE_RPT_START_DLY;
*keyScanCode = KeyDecode();
isPressKey = TRUE;
}
else
{
KeyScanState = KEY_STATE_UP;
}
break;
case KEY_STATE_RPT_START_DLY:
if( KeyIsKeyDown() )
{
if( KeyRptStartDlyCtr > 0 )
{
/* See if we need to delay before auto rpt */
KeyRptStartDlyCtr--; /* Yes, decrement counter to start of rpt */
if (KeyRptStartDlyCtr == 0)
{
KeyRptDlyCtr = KEY_RPT_DLY; /* Load delay before next repeat */
KeyScanState = KEY_STATE_RPT_DLY;
*keyScanCode = KeyDecode();
isPressKey = TRUE;
}
}
}
else
{
KeyScanState = KEY_STATE_DEBOUNCE; /* Key was not pressed after all */
}
break;
case KEY_STATE_RPT_DLY:
if( KeyIsKeyDown() )
{
if( KeyRptDlyCtr > 0 )
{
KeyRptDlyCtr--;
if( KeyRptDlyCtr == 0 )
{
KeyRptDlyCtr = KEY_RPT_DLY;
*keyScanCode = KeyDecode();
isPressKey = TRUE;
}
}
}
else
{
KeyScanState = KEY_STATE_DEBOUNCE;
}
break;
}
return isPressKey;
}
//-----------------------------------------------------------------------------
// 如果有键按下,返回按键编码
//-----------------------------------------------------------------------------
static INT8U KeyDecode (void)
{
INT8U i, width;
static INT8U code KeyCodeTable[] =
{
KEY_CODE_0,
KEY_CODE_1,
KEY_CODE_2,
KEY_CODE_3,
KEY_CODE_4,
KEY_CODE_5,
KEY_CODE_6,
KEY_CODE_7,
KEY_CODE_8,
KEY_CODE_9,
KEY_CODE_10,
KEY_CODE_11,
KEY_CODE_12,
KEY_CODE_13,
KEY_CODE_14,
KEY_CODE_15,
KEY_CODE_16,
KEY_CODE_17
};
key_port_value = KeyReadKeyPort(); // 读取键盘端口
width = 8*sizeof(KEY_PORT_VALUE_TYPE);
for( i=0; i<width; i++ )
{
if( ((INT32U)(1)<<i)&KEY_PORT_MASK ) // 如果这一个引脚上接的是按键
{
if( ( ((INT32U)(1)<<i)&key_port_value ) == 0 ) // 有键按下
{
return KeyCodeTable[i];
}
}
}
return 0xff;
}
//-----------------------------------------------------------------------------
// 判断是否有键按下
//
// 如果有键按下,返回TRUE;否则,返回FALSE
//-----------------------------------------------------------------------------
static BOOLEAN KeyIsKeyDown (void)
{
key_port_value = KeyReadKeyPort(); // 读取键盘端口
if( (key_port_value&KEY_PORT_MASK) != KEY_PORT_MASK )
return TRUE;
return FALSE;
}
//-----------------------------------------------------------------------------
// 读取键盘端口
//-----------------------------------------------------------------------------
static KEY_PORT_VALUE_TYPE KeyReadKeyPort(void)
{
key_port_value = P1;
key_port_value <<= 8;
key_port_value |= P0;
if( P3_6 == 1 )
key_port_value |= (INT32U)(1)<<16;
else
key_port_value &= ~((INT32U)(1)<<16);
if( P3_7 == 1 )
key_port_value |= (INT32U)(1)<<17;
else
key_port_value &= ~((INT32U)(1)<<17);
return key_port_value;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -