⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 key.c

📁 NT68617源程序代码集合
💻 C
字号:
/*
********************************************************************************
*
*	                                LCD控制程序
*
*	                            这是一个按键处理模块
*
*	文件名	: KEY.C
*	设计者	: Terry
********************************************************************************
*                                   功 能 描 述
*
*		该键盘模块驱动一个简单的I/O键盘,在这里是能够处理6个输入按键,按键的输入
*	数量可以被很方便的扩展。键盘的扫描由一个定时中断来驱动,在固定的间隔里对键盘
*	进行扫描,一旦有按键按下,该按键的扫描码被放入一个键盘缓冲区,应用程序从缓冲
*	区中读取扫描码并进行相应的动作。键盘缓冲区是一个良好的特性,可以防止按键动作
*	的丢失。
*       该模块带有按键锁定的功能,由标志Flg_KeyLock来控制,如果Flg_KeyLock = 1,
*   那么按键将不会被扫描,这可以使用在不需要按键输入干扰的情况下。
*       关于该按键模块的配置,公共变量,对外接口函数均放在头文件: KEY.H中,如要
*   使用按键模块就要包含该头文件
********************************************************************************
*/
#include "global.h"

/*
********************************************************************************
*		定义键盘状态机的状态
********************************************************************************
*/
#define KEY_STATE_UP				1      /* Key scanning states used in KeyScan()                   */
#define KEY_STATE_DEBOUNCE		2
#define KEY_STATE_RPT_START_DLY	3
#define KEY_STATE_RPT_DLY			4


/*
********************************************************************************
*		键盘模块所使用的静态变量
********************************************************************************
*/
static uint8 xdata KeyBuf[KEY_BUF_SIZE];
static uint16 xdata KeyDownTmr;
static uint8 xdata KeyBufInLx;
static uint8 xdata KeyBufOutLx;
static uint8 xdata KeyScanState;
static uint8 xdata KeyRptStartDlyCtr;
static uint8 xdata KeyRptDlyCtr;


/*
********************************************************************************
*		键盘模块所使用的静态功能函数定义
********************************************************************************
*/
static void KeyBufIn(uint8 key);
static uint8 KeyGetKeyCode(void);
static uint8 KeyIsDown(void);

/*
********************************************************************************
*		键盘模块的全局变量定义
********************************************************************************
*/
bit Flg_KeyOnePress = 0;

/*
********************************************************************************  
* 	函 数 名: KeyBufIn
* 	功能描述: 按键代码放入到键盘缓冲区中
* 	输    入: key	:按键的代码
* 	返    回: 无
********************************************************************************
*/
static void KeyBufIn(uint8 key)
{
	uint8 tmp;
	tmp = KeyBufInLx + 1;
	if (tmp == KEY_BUF_SIZE) tmp = 0;
	if (tmp == KeyBufOutLx)  return;		//如果尾指针加1以后等于头指针,则表示命令队列已满
	KeyBufInLx = tmp;
	KeyBuf[KeyBufInLx] = key;
}


/*
********************************************************************************  
* 	函 数 名: KeyIsDown
* 	功能描述: 判断有没有按键按下去
* 	输    入: 无
* 	返    回: 0		: 没有按键按下
*             1		: 有按键按下
********************************************************************************
*/
static uint8 KeyIsDown(void)
{
	if (KeyGetKeyCode() == KEYCODE_NOPRESS)  {
		Flg_KeyOnePress = 0;
		return 0;
		}
	
	else  {
		if (KeyDownTmr < 0xFFFF)  KeyDownTmr++;
		return 1;
		}
}


/*
********************************************************************************  
* 	函 数 名: KeyGetKey
* 	功能描述: 从键盘缓冲区中读按键代码,如果缓冲区是空则返回0xff
* 	输    入: 无
* 	返    回: 按键的代码
********************************************************************************
*/
uint8 KeyGetKey(void)
{
	if (KeyBufOutLx == KeyBufInLx )  return 0xFF;
	KeyBufOutLx++;
	if (KeyBufOutLx == KEY_BUF_SIZE)  KeyBufOutLx = 0;
	return KeyBuf[KeyBufOutLx];
}


/*
********************************************************************************  
* 	函 数 名: KeyInit
* 	功能描述: 键盘模块初始化,要正确使用键盘模块的功能,要首先调用初始化
* 	输    入: 无
* 	返    回: 0		: 键盘缓冲区中没有按键
*             1		: 键盘缓冲区中有按键
********************************************************************************
*/
void KeyInit(void)
{
	uint8 i;
	
	KeyBufInLx 		= KEY_BUF_SIZE - 1;
	KeyBufOutLx 	= KEY_BUF_SIZE - 1;
	KeyScanState 	= KEY_STATE_UP;
	KeyDownTmr 		= 0;
	for (i=0; i< KEY_BUF_SIZE; i++) KeyBuf[i] = 0xFF;
}


/*
********************************************************************************  
* 	函 数 名: KeyHit
* 	功能描述: 应用程序调用该函数判断键盘缓冲区有无按键
* 	输    入: 无
* 	返    回: 无
********************************************************************************
*/
bit KeyHit(void)
{
	if (KeyBufOutLx == KeyBufInLx )  return 0;
	else  return 1;
}


/*
********************************************************************************  
* 	函 数 名: KeyGetKeyDownTime
* 	功能描述: 返回按键按下去的时间,这个时间是扫描时间间隔的计数值
* 	输    入: 无
* 	返    回: 按键按下去的时间
********************************************************************************
*/
uint16 KeyGetKeyDownTime(void)
{
	return KeyDownTmr;
}


/*
********************************************************************************  
* 	函 数 名: KeyScan
* 	功能描述: 这是整个键盘模块的核心,完成整个键盘状态机的处理
* 	输    入: 无
* 	返    回: 按键按下去的时间
********************************************************************************
*/
void KeyScan(void)
{
	switch (KeyScanState)  {
		case  KEY_STATE_UP:							// 按键没有按下,要查看有没有按键
			if (KeyIsDown())  {					// 检查是否有按键按下
				KeyScanState 	= KEY_STATE_DEBOUNCE;	// 有按键按下,改变按键扫描的状态
				}
			KeyDownTmr 		= 0;					// 按键按下的时间清零
			break;

		case  KEY_STATE_DEBOUNCE:					// 按键已按下,获取扫描码,放入缓冲区
			if (KeyIsDown())  {					// 检查是否有按键按下
				KeyBufIn(KeyGetKeyCode());		// 获取扫描码,并放入缓冲区
				KeyRptStartDlyCtr = KEY_RPT_START_DLY;	// 启动自动重复功能
				KeyScanState = KEY_STATE_RPT_START_DLY;	// 转换按键扫描状态
				}

			else  KeyScanState = KEY_STATE_UP;		// 没有键按下,改变按键扫描状态
			break;

		case  KEY_STATE_RPT_START_DLY:				// 等待启动自动重复
			if (KeyIsDown())  {					// 检查按键是否一直按着
				if (KeyRptStartDlyCtr)  {			// 检查是否需要延时
					KeyRptStartDlyCtr--;
					if (KeyRptStartDlyCtr == 0)  {	// 检查延时时间到了没有
						KeyBufIn(KeyGetKeyCode());
						KeyRptDlyCtr = KEY_RPT_DLY;	// 设置下一次重复的延时间隔
						KeyScanState = KEY_STATE_RPT_DLY;
						}
					}
				}
			
			else  KeyScanState = KEY_STATE_DEBOUNCE;	// 键没有按下,改变扫描状态
			break;

		case  KEY_STATE_RPT_DLY:					// 等待下一次重复
			if (KeyIsDown())  {					// 检查按键是否一直按着
				if (KeyRptDlyCtr)  {				// 检查是否需要延时
					KeyRptDlyCtr--;
					if (KeyRptDlyCtr == 0)  {		// 检查延时时间到了没有
						KeyBufIn(KeyGetKeyCode());
						KeyRptDlyCtr = KEY_RPT_DLY;	// 设置下一次重复的延时间隔
						}
					}
				}

			else  KeyScanState = KEY_STATE_DEBOUNCE;	// 键没有按下,改变扫描状态
			break;
		}
}
/*
********************************************************************************
*                                文 件 结 束                                   *
********************************************************************************
*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -