搜索
bottom↓
回复: 66

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

[复制链接]

出0入296汤圆

发表于 2008-1-29 16:46:17 | 显示全部楼层 |阅读模式
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;

BOOL  g_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;
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入296汤圆

 楼主| 发表于 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 BOOL  g_cPS2IfGetNewData;

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

#endif

出0入296汤圆

 楼主| 发表于 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   定义了一个用于特效显示用的计数器,该计数器以毫秒为单位单向增加

出0入0汤圆

发表于 2008-1-29 17:26:33 | 显示全部楼层
好贴!

出0入0汤圆

发表于 2008-1-29 21:37:48 | 显示全部楼层
非常好贴。
谢谢分享。

出0入0汤圆

发表于 2008-1-29 23:10:33 | 显示全部楼层
支持

出0入0汤圆

发表于 2008-1-29 23:13:55 | 显示全部楼层
支持,楼主写程序习惯很好啊,俺都是些好了再加注释(有时候就懒得加了)。

出0入0汤圆

发表于 2008-1-30 13:31:59 | 显示全部楼层
支持

出0入0汤圆

发表于 2008-2-5 05:14:48 | 显示全部楼层
顶!!!!!!!!!!!!!

出0入0汤圆

发表于 2008-2-5 10:17:25 | 显示全部楼层
好贴!

出0入0汤圆

发表于 2008-2-6 10:13:31 | 显示全部楼层
好贴!
编程习惯也很好啊

出0入0汤圆

发表于 2008-2-18 20:14:53 | 显示全部楼层
很好,谢谢!

出0入0汤圆

发表于 2008-2-19 09:43:32 | 显示全部楼层
长见识了,谢谢楼主!

出0入8汤圆

发表于 2008-5-27 21:29:51 | 显示全部楼层
做记号

出0入0汤圆

发表于 2008-6-12 19:14:11 | 显示全部楼层
请问硬件怎么搭,才能用上PS2键盘呢?

出0入296汤圆

 楼主| 发表于 2008-6-12 20:57:50 | 显示全部楼层
2楼有较为详细的说明。

出0入0汤圆

发表于 2008-7-19 15:13:29 | 显示全部楼层
恩,好贴呀

出0入0汤圆

发表于 2008-9-28 16:14:11 | 显示全部楼层
好東東~~

出0入0汤圆

发表于 2008-9-28 21:52:02 | 显示全部楼层
;)又出精品了

出0入0汤圆

发表于 2008-9-28 22:42:54 | 显示全部楼层
不错!

出0入0汤圆

发表于 2008-10-14 08:42:20 | 显示全部楼层
有没PS2鼠标的?

出0入46汤圆

发表于 2008-10-14 10:41:33 | 显示全部楼层
好!

出0入0汤圆

发表于 2008-10-14 12:53:14 | 显示全部楼层
好东西,顶!

出0入0汤圆

发表于 2008-11-4 21:29:10 | 显示全部楼层
mark

出0入0汤圆

发表于 2008-11-5 11:03:58 | 显示全部楼层
好东西谢谢

出0入0汤圆

发表于 2008-11-5 11:20:15 | 显示全部楼层
好东西,顶!

出0入0汤圆

发表于 2008-11-5 20:11:12 | 显示全部楼层
收藏了

出0入0汤圆

发表于 2009-2-19 12:29:41 | 显示全部楼层
收藏!

出0入0汤圆

发表于 2009-3-12 19:04:48 | 显示全部楼层
不错···

出0入0汤圆

发表于 2009-3-30 09:54:11 | 显示全部楼层
MARK

出0入0汤圆

发表于 2009-3-30 10:59:26 | 显示全部楼层
MARK

出0入0汤圆

发表于 2009-5-5 13:50:52 | 显示全部楼层
mark!

出0入0汤圆

发表于 2009-5-5 15:30:21 | 显示全部楼层
不错,支持下。

出0入0汤圆

发表于 2009-5-5 16:07:01 | 显示全部楼层
mark  支持

出0入0汤圆

发表于 2009-5-24 00:50:22 | 显示全部楼层
记号,谢谢吖~~~~

出0入0汤圆

发表于 2009-6-12 10:30:58 | 显示全部楼层
dddddddddddd

出0入0汤圆

发表于 2009-6-19 23:27:32 | 显示全部楼层
还没看,有空研究一下

出0入0汤圆

发表于 2009-8-13 18:56:27 | 显示全部楼层
顶一下

出0入0汤圆

发表于 2010-6-21 19:49:10 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-7-10 16:57:34 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-7-10 20:20:38 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-9-15 12:42:06 | 显示全部楼层
Mark

出0入0汤圆

发表于 2010-12-8 22:25:45 | 显示全部楼层
mark ,PS2,改天再看

出0入0汤圆

发表于 2010-12-9 14:38:05 | 显示全部楼层
dddddddddddddd

出0入0汤圆

发表于 2011-3-31 13:01:41 | 显示全部楼层
ps2 最近在DIY的IO口不够 矩阵键盘更改未ps2

出0入0汤圆

发表于 2011-4-11 19:03:18 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-4-22 15:13:06 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-5-2 14:08:09 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-5-2 14:57:00 | 显示全部楼层
收藏!

出0入0汤圆

发表于 2011-5-15 23:54:34 | 显示全部楼层
mark!!!!

出0入0汤圆

发表于 2011-5-23 08:09:05 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-5-24 19:39:07 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-5-24 20:11:46 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-5-30 13:22:00 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-6-10 09:27:32 | 显示全部楼层
Mark

出0入0汤圆

发表于 2011-6-10 10:48:38 | 显示全部楼层
好东西。。。

出0入0汤圆

发表于 2011-7-14 08:31:01 | 显示全部楼层
恩,好贴呀

出0入0汤圆

发表于 2011-7-26 22:13:27 | 显示全部楼层
好贴

出0入0汤圆

发表于 2012-1-13 16:17:32 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-1-13 17:24:26 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-1-13 18:06:51 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-7-3 23:19:15 | 显示全部楼层
谢谢共享

出0入0汤圆

发表于 2012-7-4 06:50:52 来自手机 | 显示全部楼层
不错的代码,没细看,但是这结构,移植性应该很好!

出0入0汤圆

发表于 2012-7-4 06:55:40 | 显示全部楼层
MARK!!!!!!!!!!!!!

出0入0汤圆

发表于 2012-10-11 20:37:34 | 显示全部楼层
我去。。。太谢谢了,
早知道我那PS2的免驱设备就好做了。。
学习。

出0入0汤圆

发表于 2012-12-8 13:58:44 | 显示全部楼层
好东西,顶一个
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-27 20:16

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表