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

📄 rd_usekey._c

📁 液晶模块LCD1602配合键盘显示的一个实例
💻 _C
字号:
/***********************************************************
*   函数库说明:按键处理函数库                             *
*   版本:      v2.00                                      *
*   作者:      傻孩子                                     *
*   创建日期:  2005年11月27日                             *
* -------------------------------------------------------- *
*  [支 持 库]                                              *
*   支持库名称:RD_MacroAndConst.h                         *
*   需要版本:  v0.01 &abv                                 *
*   支持库说明:系统常用宏定义库                           *
*                                                          *
*   支持库名称: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、提供了对键盘缓冲区的支持。              *
*               2、支持长按键处理。                        *
*               3、需要外部提供一个毫秒级的延时计数器。    *
*               4、需要外部提供一个有返回值得键盘扫描      *
*                  函数,该函数需要做基本的去抖。          *
*               5、可以外部定义缓冲区大小,空键值。        *
*               6、增加了一个入口键盘扫描码的噪声抑制参    *
*                 KEY_PRESS_DELAY,该值为毫秒级的单向      *
*                 递减数值,即如果值不为零,则减到0为。    *
*                 如果键盘响应过于迟钝,可以适当改小该     *
*                 参数值。                                 *
*     v1.3      修改了头文件的组织形式,对外的接口模式     *
*               对一些时间计数器进行了分类和统一宏定义     *
*               允许外部通过宏定义将这些接口连接到实际     *
*               的计数器上。同时兼容从前的版本。           *
*     v1.31     修正了按键去抖计数器会干扰外部单向计数     *
*               器的错误。                                 *
*     v1.32     允许选择自动刷新按键和手动刷新按键两种模式 *
*     v2.00     支持长按键以重复的间隔触发。               *
* -------------------------------------------------------- *
*  [说明]                                                  *
*            1、在外部合适的位置(毫秒中断程序)增加         *
*               USEKEY_INSERT_MS_TIMER_OVF_ISR_CODE来保证  *
*               头文件的正常使用。                         *
*            2、可以通过定义KEY_BUFF_SIZE来设置键盘缓冲区  *
*               的大小。                                   *
*            3、可以通过定义KEY_PRESS_DELAY来设置去抖得    *
*               时间常数。                                 *
*            4、可以通过_USE_KEY_PRESS_SCAN_FUNC_INTERFACE *
*               来连接用于键盘扫描的函数。该函数必须返回   *
*               扫描码。                                   *
*            5、通过GetKeyCode()函数来获得缓冲区状态,当   *
*               该函数返回True时,可以从ReturnKeyNum和     *
*               ReturnLongPressKeyNum中分别获取按键和长    *
*               按键的扫描码,两个值不能同时不为KeyNull    *
*            6、允许通过_USE_KEY_MANUL_REFRESH来选择自动刷 *
*               新按键缓冲区的模式。                       *
*            7、可以通过宏_USE_KEY_LONG_PRESS_DELAY_TIME来 *
*               定义长按键的最小判定时间。                 *
*            9、可以通过宏_USE_KEY_LONG_PRESS_REPEAT来打开 *
*               长按键重复触发功能。                       *
*            8、宏_USE_KEY_LONG_KEY_FASTEST_SPEED_LEVEL可  *
*               以用来设定长按键时重复触发的最小时间间隔等 *
*               级。取值范围是0至4,数值越大,时间间隔越小 *
*               默认情况下为2,即一秒钟重复4次。           *
***********************************************************/

/********************
* 头 文 件 配 置 区 *
********************/
# include "RD_MacroAndConst.h"
# include "LIB_Config.h"
# include "RD_UseKey.h"

/********************
*   系 统 宏 定 义  *
********************/


/*------------------*
*   常 数 宏 定 义  *
*------------------*/
#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

/********************
*   函 数 声 明 区  *
********************/
static void _Key_Scan(void);

/********************
*   函 数 声 明 区  *
********************/
void Add_Key_Code(void);
unsigned char Get_Key_Code(void);

/********************
*   函 数 引 用 区  *
********************/
#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

/********************
*   全局变量声明区  *
********************/
unsigned char g_cReturnKeyNum = KEY_NULL;
unsigned char g_cReturnLongPressKeyNum = KEY_NULL;
unsigned int g_wKeyPressTimeCounter = 0;
unsigned int g_wKeyPressDelayCounter = 0;

/********************
*   模块变量声明区  *
********************/
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;


/***********************************************************
*   函数说明:按键扫描码处理函数                           *
*   输入:    无                                           *
*   输出:    无                                           *
*   调用函数:_USE_KEY_PRESS_SCAN_FUNC_INTERFACE()         *
* -------------------------------------------------------- *
*   [说    明]                                             *
*            按下一个键以后,1s以内松开返回短按键键值      *
*            1s以上返回长按键键值。键值只保存一个周期      *
***********************************************************/
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
        }
    }
	 
}

/***********************************************************
*   函数说明:键盘缓冲处理函数                             *
*   输入:    无                                           *
*   输出:    无                                           *
*   调用函数:_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 ++;
}

/***********************************************************
*   函数说明:从键盘缓冲区中获得一个按键扫描码             *
*   输出:    返回操作是否成功TRUE / FALSE                 *
*   输入:    无                                           *
*   调用函数:Add_Key_Code()                               *
* -------------------------------------------------------- *
*   [说    明]                                             *
*             将按键扫描码放到专门的临时缓冲变量中         *
***********************************************************/
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;
}

⌨️ 快捷键说明

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