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

📄 key.c

📁 用quartusII编写的
💻 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 + -