Gorgon_Meducer 发表于 2008-1-29 16:46:17

[共享]PS2键盘通用支持库(v0.9beta)

RD_KeyBoard_PS2.c
------------------------------------------------------------------

/***********************************************************
*   函数库说明:PS/2键盘底层硬件驱动函数库               *
*   版本:      v0.90beta                                  *
*   作者:      王卓然                                     *
*   创建日期:2008年1月17日                              *
* -------------------------------------------------------- *
*[支 持 库]                                              *
*   支持库名称:                                           *
*   需要版本:                                             *
*   支持库名称:                                           *
* -------------------------------------------------------- *
*[版本更新]                                              *
*   修改:                                                 *
*   修改日期:                                             *
*   版本:                                                 *
* -------------------------------------------------------- *
*[版本历史]                                              *
* -------------------------------------------------------- *
*[使用说明]                                              *
***********************************************************/

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

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

/*------------------*
*   常 数 宏 定 义*
*------------------*/

/*------------------*
*   动 作 宏 定 义*
*------------------*/

/********************
*用户变量类型定义 *
********************/

/********************
*    结构体定义区   *
********************/

/********************
*   模块函数声明区*
********************/

/********************
*   全局函数声明区*
********************/
BOOL PROC_Key_Board_PS2_Scan(void);
uint8 Scan_Key_Board_PS2(void);
UINT8 Key_Board_PS2_GetLastMakeKey(void);
UINT8 Key_Board_PS2_GetLastBreakKey(void);
/********************
*   模块变量声明区*
********************/
static uint8 s_cPS2KeyNum = KEY_NULL;
static uint8 s_cPS2LastBreakKey = KEY_NULL;
static uint8 s_cPS2LastMakeKey = KEY_NULL;

/********************
*   全局变量声明区*
********************/
uint8 g_cPS2GetData = 0;
uint8 g_cPS2ReceiveCount = 0;

BOOLg_cPS2IfGetNewData = FALSE;

/********************
*   自定义变量声明*
********************/
START_DEFINE_QUEUE(PS2KeyBuffer,8,uint8,uint8)
END_DEFINE_QUEUE

/***********************************************************
*   函数说明:按键扫描码返回函数                           *
*   输入:    无                                           *
*   输出:    无                                           *
*   调用函数:无                                           *
***********************************************************/
uint8 Scan_Key_Board_PS2(void)
{
   return s_cPS2KeyNum;
}

/***********************************************************
*   函数说明:最后一个通码函数                           *
*   输入:    无                                           *
*   输出:    最后一个通码                                 *
*   调用函数:无                                           *
* -------------------------------------------------------- *
*   [ 说 明 ] 当读取通码以后,会自动复位为KEY_NULL         *
***********************************************************/
UINT8 Key_Board_PS2_GetLastMakeKey(void)
{
   UINT8 chTempLastMakeKey = s_cPS2LastMakeKey;
   s_cPS2LastMakeKey = KEY_NULL;
   return chTempLastMakeKey;
}

/***********************************************************
*   函数说明:最后一个断码                                 *
*   输入:    无                                           *
*   输出:    最后一个断码                                 *
*   调用函数:无                                           *
* -------------------------------------------------------- *
*   [ 说 明 ] 当读取断码以后,会自动复位为KEY_NULL         *
***********************************************************/
UINT8 Key_Board_PS2_GetLastBreakKey(void)
{
    UINT8 chTempLastBreakKey = s_cPS2LastBreakKey;
    s_cPS2LastBreakKey = KEY_NULL;
    return chTempLastBreakKey;
}

/***********************************************************
*   函数说明:PS2键盘扫描处理函数                        *
*   输入:    无                                           *
*   输出:    无                                           *
*   调用函数:无                                           *
***********************************************************/
BOOL PROC_Key_Board_PS2_Scan(void)
{
    static BOOL s_bIfKeyUp = TRUE;
    uint8 cQueueCount = 0;
    uint8 cTempData = 0;
   
   
    cQueueCount = __GET_QUEUE_COUNT;
   
   
    if (__PEEK_DATA(cTempData))
    {
      
      //如果缓冲区不为空
      if (cTempData == 0xE0)
      {
            if (cQueueCount > 1)
            {
                __GET_DATA(cTempData);
                __PEEK_DATA(cTempData);
                if (cTempData == 0xF0)
                {
                  if (cQueueCount > 2)
                  {
                        //取到了断开码
                        __GET_DATA(cTempData);
                        __GET_DATA(s_cPS2LastBreakKey);
                        s_cPS2KeyNum = KEY_NULL;
                  }
                }
                else
                {
                  //取到了通码
                  __GET_DATA(s_cPS2KeyNum);
                  s_cPS2LastMakeKey = s_cPS2KeyNum;
                }
            }
      }
      else
      {
            if (cTempData == 0xF0)
            {
                if (cQueueCount > 1)
                {
                  __GET_DATA(cTempData);
                  __GET_DATA(s_cPS2LastBreakKey);
                  s_cPS2KeyNum = KEY_NULL;
                }
            }
            else
            {
                //取到了通码
                __GET_DATA(s_cPS2KeyNum);
                s_cPS2LastMakeKey = s_cPS2KeyNum;
            }
      }
    }
   
    return TRUE;
}

Gorgon_Meducer 发表于 2008-1-29 16:47:08

RD_KeyBoard_PS2.h
----------------------------------------------------------------------

#ifndef _USE_KEY_BOARD_PS2_H_
#define _USE_KEY_BOARD_PS2_H_
/***********************************************************
*   声明库说明:PS/2键盘底层硬件驱动函数声明库             *
*   版本:      v0.90beta                                  *
*   作者:      王卓然                                     *
*   创建日期:2008年1月17日                              *
* -------------------------------------------------------- *
*[支 持 库]                                              *
*   支持库名称:                                           *
*   需要版本:                                             *
*   支持库名称:                                           *
* -------------------------------------------------------- *
*[版本更新]                                              *
*   修改:                                                 *
*   修改日期:                                             *
*   版本:                                                 *
* -------------------------------------------------------- *
*[版本历史]                                              *
* -------------------------------------------------------- *
*[使用说明]                                              *
***********************************************************/

/********************
* 头 文 件 配 置 区 *
********************/

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



/*------------------*
*   常 数 宏 定 义*
*------------------*/
#ifndef KEY_NULL
   # define KEY_NULL            0xff
#endif


/*------------------*
*   动 作 宏 定 义*
*------------------*/
#ifndef KEY_BOARD_PS2_RECEIVE
   # define KEY_BOARD_PS2_RECEIVE(n)      
#endif

# define __PUT_DATA(n)          ADD_QUEUE_DATA(PS2KeyBuffer,(n))
# define __GET_DATA(n)          GET_QUEUE_DATA(PS2KeyBuffer,&(n))
# define __GET_QUEUE_COUNT      GET_QUEUE_COUNT(PS2KeyBuffer)
# define __PEEK_DATA(n)         PEEK_QUEUE_DATA(PS2KeyBuffer,&(n))

# define PS2_GET_LAST_MAKE_KEY      Key_Board_PS2_GetLastMakeKey()
# define PS2_GET_LAST_BREAK_KEY   Key_Board_PS2_GetLastBreakKey()

# define KEY_BOARD_PS2_INSERT_INT_ISR_CODE      \
                                                {\
                                                    static uint8 s_cTempData = 0;\
                                                    static uint8 s_cParity = 0;\
                                                    g_cPS2ReceiveCount++;\
                                                    if (g_cPS2ReceiveCount == 1)\
                                                    {\
                                                      if (KEY_BOARD_PS2_DATA == HIGH)\
                                                      {\
                                                            s_cTempData = 0;\
                                                            s_cParity = 0;\
                                                            g_cPS2ReceiveCount = 0;\
                                                      }\
                                                    }\
                                                    else if (g_cPS2ReceiveCount == 10)\
                                                    {\
                                                      if (KEY_BOARD_PS2_DATA ^ (s_cParity & 0x01))\
                                                      {\
                                                            g_cPS2IfGetNewData = TRUE;\
                                                            g_cPS2GetData = s_cTempData;\
                                                            __PUT_DATA(g_cPS2GetData);\
                                                            KEY_BOARD_PS2_RECEIVE(g_cPS2GetData);\
                                                      }\
                                                    }\
                                                    else if (g_cPS2ReceiveCount == 11)\
                                                    {\
                                                      g_cPS2ReceiveCount = 0;\
                                                      s_cParity = 0;\
                                                    }\
                                                    else\
                                                    {\
                                                      if (KEY_BOARD_PS2_DATA)\
                                                      {\
                                                            s_cTempData |= BIT(g_cPS2ReceiveCount-2);\
                                                            s_cParity += 1;\
                                                      }\
                                                      else\
                                                      {\
                                                            s_cTempData &= ~BIT(g_cPS2ReceiveCount-2);\
                                                      }\
                                                    }\
                                                 }
                           
/********************
*用户变量类型定义 *
********************/

/********************
*    结构体定义区   *
********************/

/********************
*   函 数 引 用 区*
********************/
extern BOOL PROC_Key_Board_PS2_Scan(void);
extern uint8 Scan_Key_Board_PS2(void);
extern UINT8 Key_Board_PS2_GetLastMakeKey(void);
extern UINT8 Key_Board_PS2_GetLastBreakKey(void);
/********************
*   全局变量引用区*
********************/
extern uint8 g_cPS2GetData;
extern uint8 g_cPS2ReceiveCount;
extern BOOLg_cPS2IfGetNewData;

/********************
*自定义变量引用区 *
********************/
EXTERN_REFERENCE_QUEUE(PS2KeyBuffer,uint8,uint8)

#endif

Gorgon_Meducer 发表于 2008-1-29 16:56:54

使用说明:
1、该头文件还处在更新中,已经可以从PS2键盘中提取所需的键盘扫描码,并能单独存储最后一次的通码和断码。
2、该头文件提供一个Scan_Key_Board_PS2()函数,该函数将PS2键盘的输出模拟成普通的 n*m 键盘扫描的输出模式,即当有键按下时,通过该函数将获得对应的键盘扫描码,当没有键按下时,将获得一个KEY_NULL的返回。
3、该头文件需要的硬件支持为:
   一个下降沿触发的外中断,并将.h中的宏KEY_BOARD_PS2_INSERT_INT_ISR_CODE粘贴到中断处理程序中。该外中断接PS2的CLK线。
   一个普通端口,接PS2的Data线。
4、将PROC_Key_Board_PS2_Scan()放到定时器的毫秒中断处理程序中,或者放到主程序的超级循环中(但必须保证该程序在超级循环中具有一定的实时性)。

所有针对该头文件的配置都必须放在一个名叫LIB_Config.h的头文件中,一个典型的配置如下:

硬件ATMega16
//PS/2键盘模块
# define KEY_BOARD_PS2_DATA             PIN_PD2

# include "RD_TPL_QUEUE.h"
# include "RD_KeyBoard_PS2.h"

大家注意到,宏KEY_BOARD_PS2_DATA实际上被绑定在了PIN_PD2上。


下面的代码你可以看作是伪代码,他实际上描述了该头文件的一个典型使用方法。

void main(void)
{
    System_INIT();                                          //代码初始化
   
    //DISP_BOARD_SET_FLASH_POS(BIT(1));
    //DISP_BOARD_SET_ICON(0x0F);
    CLS
    //Locate(1,1);
    //PrintD(123);
    //Locate(1,1);
    //PrintN(0x1234,4);
   
    while(TRUE)                                             //超级循环
    {
      UINT8 chLastBreakKey = KEY_NULL;
      UINT8 chLastMakeKey = KEY_NULL;
      
      Locate(1,1);
      PrintN(Scan_Key_Board_PS2(),2);
      
      chLastBreakKey = PS2_GET_LAST_BREAK_KEY;
      if (chLastBreakKey != KEY_NULL)
      {
            LOCATE(5,1);
            PrintN(chLastBreakKey,2);
      }
      
      chLastMakeKey = PS2_GET_LAST_MAKE_KEY;
      if (chLastMakeKey != KEY_NULL)
      {
            LOCATE(3,1);
            PrintN(chLastMakeKey,2);
      }
      
      PROC_Key_Board_PS2_Scan();
      
    }                                          
}
实例工程:点击此处下载ourdev_208916.rar(文件大小:195K)
如果你想直接使用该示例工程,需要在ICCV7的环境下进行工程编译。
硬件上,关于显示,需要两个端口来实现一个8位的排显示。相关的头文件是RD_UseDISPBoard.h。对应的配置也在LIB_Config.h中。例如:
//显示模块
# define DISP_BOARD_START_POS         2
# define _USE_DISP_BOARD_FOR_SPECIAL_POS
# define DISP_BOARD_POSITION            PORTA
# define DISP_BOARD_DATA                PORTB
# define SYS_TIMER_MS_ADD_UNTILL_OVF    g_wSystemTimer

# include "RD_UseDISPBoard.h"

因为我使用的实际上6位排显,所以调整了显示的起始位置:# define DISP_BOARD_START_POS         2
对于扫描位选,硬件决定了,给高电平,对应数码管被选中,这和头文件的默认模式是不同的,所以我要通过宏来设定:# define _USE_DISP_BOARD_FOR_SPECIAL_POS

# define DISP_BOARD_POSITION            PORTA            定义了位选端口
# define DISP_BOARD_DATA                PORTB            定义了断码端口

# define SYS_TIMER_MS_ADD_UNTILL_OVF    g_wSystemTimer   定义了一个用于特效显示用的计数器,该计数器以毫秒为单位单向增加

1181zjf 发表于 2008-1-29 17:26:33

好贴!

oilgas 发表于 2008-1-29 21:37:48

非常好贴。
谢谢分享。

liming3267 发表于 2008-1-29 23:10:33

支持

bozai 发表于 2008-1-29 23:13:55

支持,楼主写程序习惯很好啊,俺都是些好了再加注释(有时候就懒得加了)。

y2kloach 发表于 2008-1-30 13:31:59

支持

zhaod 发表于 2008-2-5 05:14:48

顶!!!!!!!!!!!!!

chenpeiguo 发表于 2008-2-5 10:17:25

好贴!

hillsea 发表于 2008-2-6 10:13:31

好贴!
编程习惯也很好啊

maoxia007 发表于 2008-2-18 20:14:53

很好,谢谢!

mshicom 发表于 2008-2-19 09:43:32

长见识了,谢谢楼主!

kebaojun305 发表于 2008-5-27 21:29:51

做记号

525133174 发表于 2008-6-12 19:14:11

请问硬件怎么搭,才能用上PS2键盘呢?

Gorgon_Meducer 发表于 2008-6-12 20:57:50

2楼有较为详细的说明。

yueyongbo 发表于 2008-7-19 15:13:29

恩,好贴呀

tomy 发表于 2008-9-28 16:14:11

好東東~~

leixianfeng 发表于 2008-9-28 21:52:02

;)又出精品了

haizaolan 发表于 2008-9-28 22:42:54

不错!

huayan 发表于 2008-10-14 08:42:20

有没PS2鼠标的?

bjj9217 发表于 2008-10-14 10:41:33

好!

spy2008 发表于 2008-10-14 12:53:14

好东西,顶!

a105 发表于 2008-11-4 21:29:10

mark

lcqqcl 发表于 2008-11-5 11:03:58

好东西谢谢

iam35200 发表于 2008-11-5 11:20:15

好东西,顶!

sonic5566 发表于 2008-11-5 20:11:12

收藏了

sunmy 发表于 2009-2-19 12:29:41

收藏!

yswanan 发表于 2009-3-12 19:04:48

不错···

deepin 发表于 2009-3-30 09:54:11

MARK

ljgvictory 发表于 2009-3-30 10:59:26

MARK

zhaolj_kstar 发表于 2009-5-5 13:50:52

mark!

flyhouse 发表于 2009-5-5 15:30:21

不错,支持下。

dsq2007001 发表于 2009-5-5 16:07:01

mark支持

naohbbq 发表于 2009-5-24 00:50:22

记号,谢谢吖~~~~

0620221 发表于 2009-6-12 10:30:58

dddddddddddd

jiangweng1234 发表于 2009-6-19 23:27:32

还没看,有空研究一下

wchqq 发表于 2009-8-13 18:56:27

顶一下

logic.pn 发表于 2010-6-21 19:49:10

mark

xuyqhd 发表于 2010-7-10 16:57:34

mark

wsm80828 发表于 2010-7-10 20:20:38

mark

QQ373466062 发表于 2010-9-15 12:42:06

Mark

xiesx1985 发表于 2010-12-8 22:25:45

mark ,PS2,改天再看

lan_boy008 发表于 2010-12-9 14:38:05

dddddddddddddd

winkle 发表于 2011-3-31 13:01:41

ps2 最近在DIY的IO口不够 矩阵键盘更改未ps2

ringan865 发表于 2011-4-11 19:03:18

mark

Bati-Gol 发表于 2011-4-22 15:13:06

mark

wpnx 发表于 2011-5-2 14:08:09

mark

geniusjia 发表于 2011-5-2 14:57:00

收藏!

lixupeng 发表于 2011-5-15 23:54:34

mark!!!!

notebook 发表于 2011-5-23 08:09:05

mark

GNMXD 发表于 2011-5-24 19:39:07

mark

wzq666 发表于 2011-5-24 20:11:46

mark

Spunky 发表于 2011-5-30 13:22:00

mark

myyule 发表于 2011-6-10 09:27:32

Mark

106415718 发表于 2011-6-10 10:48:38

好东西。。。

wenjin0386 发表于 2011-7-14 08:31:01

恩,好贴呀

ICANDO 发表于 2011-7-26 22:13:27

好贴

nicholaszao 发表于 2012-1-13 16:17:32

mark

nicksean 发表于 2012-1-13 17:24:26

mark

flyingcys 发表于 2012-1-13 18:06:51

mark

zhzj2007 发表于 2012-7-3 23:19:15

谢谢共享

jlhgold 发表于 2012-7-4 06:50:52

不错的代码,没细看,但是这结构,移植性应该很好!

pcwinner 发表于 2012-7-4 06:55:40

MARK!!!!!!!!!!!!!

perfugee 发表于 2012-10-11 20:37:34

我去。。。太谢谢了,
早知道我那PS2的免驱设备就好做了。。
学习。

xi416547162 发表于 2012-12-8 13:58:44

好东西,顶一个
页: [1]
查看完整版本: [共享]PS2键盘通用支持库(v0.9beta)