[古董贴][测试]用于OurRobotV1的通用按键缓冲处理模块
#ifndef _Use_KeyDriver#define _Use_KeyDriver
/***********************************************************
*函数库说明:按键处理函数库 *
*版本: v1.32 *
*作者: 傻孩子 *
*创建日期:2005年11月27日 *
* -------------------------------------------------------- *
*[支持库] *
*库名称: RD_MacroAndConst.h *
*需要版本:v0.01 &abv *
*函数库说明:系统常用宏定义库 *
* -------------------------------------------------------- *
*修改: 傻孩子 *
*修改日期:2006年4月15日 *
*版本: v1.3 *
* *
*修改: 傻孩子 *
*修改日期:2006年4月23日 *
*版本: v1.31 *
* *
*修改: 傻孩子 *
*修改日期:2006年5月5日 *
*版本: v1.32 *
* -------------------------------------------------------- *
*[版本历史] *
* v1.3以下 1、提供了对键盘缓冲区的支持。 *
* 2、支持长按键处理。 *
* 3、需要外部提供一个毫秒级的延时计数器。 *
* 4、需要外部提供一个有返回值得键盘扫描 *
* 函数,该函数需要做基本的去抖。 *
* 5、可以外部定义缓冲区大小,空键值。 *
* 6、增加了一个入口键盘扫描码的噪声抑制参 *
* KEY_PRESS_DELAY,该值为毫秒级的单向 *
* 递减数值,即如果值不为零,则减到0为。 *
* 如果键盘响应过于迟钝,可以适当改小该 *
* 参数值。 *
* v1.3 修改了头文件的组织形式,对外的接口模式 *
* 对一些时间计数器进行了分类和统一宏定义 *
* 允许外部通过宏定义将这些接口连接到实际 *
* 的计数器上。同时兼容从前的版本。 *
* v1.31 修正了按键去抖计数器会干扰外部单向计数 *
* 器的错误。 *
* v1.32 允许选择自动刷新按键和手动刷新按键两种模式。*
* -------------------------------------------------------- *
*[说明] *
* 1、在外部合适的位置(毫秒中断程序)增加 *
* USEKEY_INSERT_MS_TIMER_OVF_ISR_CODE来保证 *
* 头文件的正常使用。 *
* 2、可以通过定义KeyBuffSize来设置键盘缓冲区 *
* 的大小。 *
* 3、可以通过定义KEY_PRESS_DELAY来设置去抖得 *
* 时间常数。 *
* 4、可以通过_USE_KEY_TIMER_MS_ADD_UNTILL_OVF *
* 来连接用于键盘扫描的函数。该函数必须返回 *
* 扫描码。 *
* 5、通过GetKeyCode()函数来获得缓冲区状态,当 *
* 该函数返回True时,可以从ReturnKeyNum和 *
* ReturnLongPressKeyNum中分别获取按键和长 *
* 按键的扫描码,两个值不能同时不为KeyNull *
* 6、允许通过_USE_KEY_MANUL_REFRESH来选择自动刷新 *
* 按键缓冲区的模式。 *
***********************************************************/
# include <RD_MacroAndConst.h>
/***********************
* 系统宏定义区 *
***********************/
#ifndef KeyBuffSize
# define KeyBuffSize 8
#endif
#ifndef KeyNull
# define KeyNull 0xf0
#endif
#ifndef KEY_PRESS_DELAY
# define KEY_PRESS_DELAY50
#endif
/*---------------------*
* 动 作 宏 定 义 *
*---------------------*/
#ifndef _USE_KEY_MANUL_REFRESH
# define USEKEY_INSERT_MS_TIMER_OVF_ISR_CODE do{AddKeyCode();KeyPressTimeCounter++;if(KeyPressDelayCounter)
KeyPressDelayCounter --;}while(0);
#else
# define USEKEY_INSERT_MS_TIMER_OVF_ISR_CODE
#endif
/***********************
* 全局变量声明区 *
***********************/
char KeyBuff;
char KeyBuffCounter = 0;
char KeyBuffHeadPoint = 0;
char KeyBuffTailPoint = 0;
char ReturnKeyNum = KeyNull;
char ReturnLongPressKeyNum = KeyNull;
char LongKeyPressNum = KeyNull;
char KeyNum = KeyNull;
unsigned int KeyPressTimeCounter = 0;
unsigned int KeyPressDelayCounter = 0;
/***********************
* 函 数 声 明 区 *
***********************/
void _KeyScan(void);
void AddKeyCode(void);
char GetKeyCode(void);
#ifndef _USE_KEY_PRESS_SCAN_FUNC_INTERFACE
extern char NowKeyPressCheck(void);
# define _USE_KEY_PRESS_SCAN_FUNC_INTERFACE NowKeyPressCheck
#else
extern char _USE_KEY_PRESS_SCAN_FUNC_INTERFACE(void);
#endif
/***********************************************************
*函数说明:按键扫描码处理函数 *
*返回: 处理后的按键扫描码 *
*说明: 按下一个键以后,1s以内松开返回短按键键值 *
* 1s以上返回长按键键值。键值只保存一个周期 *
***********************************************************/
void _KeyScan(void)
{
static char OldKeyCode = KeyNull;
static char IfLongKeyPress = False;
char NowKeyCode = _USE_KEY_PRESS_SCAN_FUNC_INTERFACE();
KeyNum = KeyNull;
if ((OldKeyCode != NowKeyCode) && (KeyPressDelayCounter == 0))
{
KeyPressTimeCounter = 0;
if ((NowKeyCode == KeyNull) && (IfLongKeyPress == False))
{
KeyNum = OldKeyCode;
}
KeyPressDelayCounter = KEY_PRESS_DELAY;
OldKeyCode = NowKeyCode;
IfLongKeyPress = False;
}
else
{
KeyNum = KeyNull;
if ((KeyPressTimeCounter > 1000) && (IfLongKeyPress == False))
{
LongKeyPressNum = NowKeyCode;
IfLongKeyPress = True;
}
else
{
LongKeyPressNum = KeyNull;
}
}
}
/***********************************************************
*函数说明:键盘缓冲处理函数 *
***********************************************************/
void AddKeyCode(void)
{
_KeyScan();
if ((KeyNum == KeyNull) && (LongKeyPressNum == KeyNull))
{
return ;
}
if ((KeyBuffHeadPoint == KeyBuffTailPoint) && (KeyBuffCounter != NULL))
{
return ;
}
KeyBuff = KeyNum;
KeyBuff = LongKeyPressNum;
KeyBuffTailPoint ++;
if (KeyBuffTailPoint == KeyBuffSize)
{
KeyBuffTailPoint = 0;
}
KeyBuffCounter ++;
}
/***********************************************************
*函数说明:从键盘缓冲区中获得一个按键扫描码 *
*输出: 返回操作是否成功True / False *
*说明: 将按键扫描码放到专门的临时缓冲变量中 *
***********************************************************/
char GetKeyCode(void)
{
ReturnKeyNum = KeyNull;
ReturnLongPressKeyNum = KeyNull;
#ifdef _USE_KEY_MANUL_REFRESH
AddKeyCode();
#endif
if ((KeyBuffHeadPoint == KeyBuffTailPoint) && (KeyBuffCounter == NULL))
{
return False;
}
ReturnKeyNum = KeyBuff;
ReturnLongPressKeyNum = KeyBuff;
KeyBuffCounter --;
KeyBuffHeadPoint ++;
if (KeyBuffHeadPoint == KeyBuffSize)
{
KeyBuffHeadPoint = 0;
}
return True;
}
#endif
欢迎大家共同测试 比方说OurRobotV1中是这样使用这个模块的
/***********************************************************
*函数说明:按键扫描码返回函数 *
*输出: 当前的按键扫描码 *
***********************************************************/
char PressKeyScan(void)
{
if (DKeyNum != KeyNull) //获取595显示系统返回的按键扫描码
{
return DKeyNum;
}
if (KeyStart) //判断Start键
{
return KEY_START;
}
if (KeyModel) //判断Model键
{
return KEY_MODEL;
}
return KeyNull;
}
/*-----------按键处理模块初始化--------------*/
# define _USE_KEY_PRESS_SCAN_FUNC_INTERFACE PressKeyScan //<--指定接口函数
# include <RD_UseKey.h>
/***********************************************************
*函数说明:定时器0中断处理程序接口程序(嵌入代码) *
***********************************************************/
void InsertTimer0OvfCode(void)
{
SystemTimer ++;
DISPLAY595_INSERT_MS_TIMER_OVF_ISR_CODE
USEKEY_INSERT_MS_TIMER_OVF_ISR_CODE //<--这个就是这个头文件的插入代码
SD_INSERT_MS_TIMER_OVF_ISR_CODE
if (BeepDelay)
{
BeepDelay --;
SPEAKER_ON;
}
else
{
SPEAKER_OFF;
}
WayGuider();
}
页:
[1]