Gorgon_Meducer 发表于 2006-5-12 10:29:33

[古董贴][测试]用于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





欢迎大家共同测试

Gorgon_Meducer 发表于 2006-5-12 10:32:09

比方说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]
查看完整版本: [古董贴][测试]用于OurRobotV1的通用按键缓冲处理模块