搜索
bottom↓
回复: 6

给关注PIC论坛的朋友们拜年啦(礼包:PS2键盘代码)

[复制链接]

出0入42汤圆

发表于 2011-2-3 11:45:09 | 显示全部楼层 |阅读模式
<font size=12>祝大家 新春快乐 技术有成 梦想成真</font>  



转载一篇关于PS2键盘的代码和文章:点击此处下载 ourdev_614524JIK2YF.rar(文件大小:505K) (原文件名:PS2_driver.rar)

/*论坛上相关的文章:
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=3232940&bbs_page_no=1&search_mode=1&search_text=键盘&bbs_id=1028
/*

ps2key.c:
**************************************************************************************************
*                                                                Embedded Systems Building Blocks
*                                                     PS/2 Keyboard 104 keys, NumPad driver
*
*                                        Original obtained from www.picant.com, C2C complier web site
*                                                by Julio Cesar Silva Briano, modified by John Leung
*
* Filenmae                 : ps2key.c
* Programmer         : John Leung, www.TechToys.com.hk under Downloads Section.
* Version                : Version 1.1 - 17th June 2004
* Remarks                : Consult www.beyong.org for PS/2 keyboard protocol
**************************************************************************************************
*                                                                                        DESCRIPTION
*                This is a PS/2 keyboard driver for standard 101/104 keyboard or Numerical Keypad
*                                 Application software must include PS2Key.h and PS2ScanCode.h
*                                                        PS2Key.h contains hardware port configuration
*                        PS2ScanCode.h configures if it is a complete 101 keyboard, or just the Numpad
*        Two lookup tables PS2KeyUnshifted[] and PS2KeyShifted[] map the PS2Key_Code to ASCII characters
* If it is going to be the Numpad ONLY, PS2KeyUnshifted[] and PS2KeyShifted[] can be undefined to save ROM
*                                        Application must declare the followings (see ps2key.h)
*        PS2key.c is PS/2 keyboard driver to handle ordinary PS/2 or AT-style keyboard with mcu
*        Global variable PS2Key_Code returns the raw key code of a key
*        Key Buffer is defined by constant PS2KEY_BUF_SIZE (in PS2Key.h)
*
*        PS2Key_Clk                        The port address of the PS/2 CLK signal
*        PS2Key_Data                        The port address of the PS/2 Data signal
*        PS2Key_BUF_SIZE         Size of the PS/2 keyboard buffer
**************************************************************************************************
*/

/*
**************************************************************************************************
*        Date: 2 Feb 2006
*        Revised for void PS2KeyIntHandler(void), bug reported by CSS forum that, this piece of code
*        didn't work for Xtal frequency 4Mhz. This is because the following switch case spent too much
*        time
*        void PSKeyIntHandler(void){
*        ....
        case PS2Key_STOP:                                                                                // Stop bit (PS2Key_STOP = 11)
                                if (PS2Key_Code==0x12||PS2Key_Code==0x59)        // Key=Left shift or right shift
                                {        if (PS2_BREAKCODE==TRUE)                               
                                                PS2_SHIFT=FALSE;
                                        else
                                                PS2_SHIFT=TRUE;
                                }

                                if (PS2Key_Code==0xF0)                                                // Is a break code!
                                        PS2_BREAKCODE=TRUE;                                                // ignore break code
                                else if (PS2_BREAKCODE==TRUE)
                                        PS2_BREAKCODE=FALSE;
                                else
                                         PS2KeyBufIn (PS2Key_Code);                                // put valid key in buffer

                         PS2Key_bit_Ix=0;
*        ....}
*        CHECKING FOR SHIFT KEY OR BREAK KEY SHOULDN'T BE HANDLED UNDER RB0 INTERRUPT ROUTINE!
**************************************************************************************************
*/

/*
**************************************************************************************
*        Date 3 Feb 2005
*        Bug reported when Xtal = 4MHz. When Xtal = 20MHz, the original code ran OK
*        Revision :  1. Change to 4MHz crystal
*                                2. Add #use fast_io(b) in main()
*                                3. Change A4 -> B1 for PS2Key_Data (for hardware simplicity only)
*                                4. The key modification in void PS2KeyIntHandler(void). Previously
*                                   switch (PS2Key_bit_Ix) case... applied but the assembly code
*                                   generated took too long for clock signal detection of keyboard
*                                   Instead of switch, a simple if() else if ... selection employed
*                                5. Detection of PS2_BREAKCODE and PS2_SHIFT deleted from
*                                   PS2KeyIntHandler(void) to save interrupt time.
**************************************************************************************
*/

/*
**************************************************************************************************
                                                                                        GLOBAL VARIABLES
**************************************************************************************************
*/

INT8U        PS2KeyBuf[PS2KEY_BUF_SIZE];        //PS2 Keyboard buffer, the register to store characters key in
INT8U        PS2KeyBufInIx;                                //Index into PS/2 key buf where next scan code will be inserted
INT8U        PS2KeyBufOutIx;                                //Index into PS/2 key buf where next scan code will be removed
INT8U        PS2KeyNRead;                                //Number of keys read from the PS/2 keyboard
INT8U        PS2Key_Code;                                //Key code from PS/2 keyboard
INT8U        PS2Key_bit_Ix;                                //bit index of the byte stream, Start_bit(1), Parity(10), Stop_bit(11)
BOOLEAN PS2_SHIFT;                                        //TRUE if left or right shift pressed
BOOLEAN        PS2_BREAKCODE;                                //TRUE if a BREAKCODE received

/*
**************************************************************************************************
                                                                        LOCAL FUNCTION PROTOTYPES
**************************************************************************************************
*/
void         PS2KeyBufIn(INT8U code);                                /* Insert scan code into keyboard buffer */
INT8U         PS2KeyDecode(void);                                        /* Function to decode a key stroke */


/*
**************************************************************************************************
*                                                                INSERT KEY CHARACTER INTO KEYBOARD BUFFER
* Description: This function inserts a key character into the keyboard buffer from a PS/2 keyboard
**************************************************************************************************
*/

void PS2KeyBufIn (INT8U code)
{
        if (PS2KeyNRead < PS2Key_BUF_SIZE) {                //make sure that we don't overflow the buffer
                PS2KeyNRead++;                                                        //Increment the number of keys read
                PS2KeyBuf[PS2KeyBufInIx++] = code;                //Store the scan code into the buffer
                if (PS2KeyBufInIx >= PS2Key_BUF_SIZE) {        //Adjust index to the next scan code to put in buffer
                        PS2KeyBufInIx = 0;
                }
        }
}

/*
**************************************************************************************************
*                                                                        DECODE PS/2 KEYBOARD SCAN CODE
* Description: This function is called to determine the key scane code of the PS/2 keyboard
* Arguments:   none
* Returns:           the key scan code
**************************************************************************************************
*/
INT8U PS2KeyDecode(void)
{
        ;
}

/*
**************************************************************************************************
*                                                                                GET KEY       
* Description:         Get a PS/2 keyboard scan code from the keyboard driver
* Arguments:           none
* Returns:                   !=0xFF is the key scan code of the PS/2 keyboard key pressed
*                                ==0xFF indicates that there is on key in the PS2KeyBuf[PS2KEY_BUF_SIZE] buffer
**************************************************************************************************
*/

INT8U PS2KeyGetKey (void)
{
        INT8U code;

                        //OS_ENTER_CRITICAL();
        if (PS2KeyNRead > 0) {                                        /* See if we have keys in PS2KeyBuf[] */
                PS2KeyNRead--;                                                /* Decrement the number of keys in the buffer */
                code = PS2KeyBuf[PS2KeyBufOutIx];        /* Get scan code from the buffer */
                PS2KeyBufOutIx++;
                if (PS2KeyBufOutIx >= PS2Key_BUF_SIZE) {
                        PS2KeyBufOutIx = 0;
                        }
                        //OS_EXIT_CRITICAL();
                return (code);                                                /* return the scan code of the key pressed */
                } else {
                        //OS_EXIT_CRITICAL();
                return (0xFF);                                                /* No scan codes in buffer, return -1 */
        }
}

/*
**************************************************************************************************
*                                                                                SEND COMMAND
* Description:         Send command to the PS/2 keyboard
* Arguments:           cmd is the command to send
*                                $ED Set Status LED's - This command can be used to turn on and off the Num Lock, Caps Lock & Scroll Lock LED's.
*                                        After Sending ED, keyboard will reply with ACK (FA) and wait for another byte which determines their Status.
*                                        Bit 0 controls the Scroll Lock, Bit 1 the Num Lock and Bit 2 the Caps lock. Bits 3 to 7 are ignored.  
*                                 $EE Echo - Upon sending a Echo command to the Keyboard, the keyboard should reply with a Echo (EE)
*                                $F0 Set Scan Code Set. Upon Sending F0, keyboard will reply with ACK (FA) and wait for another byte,
                                        01-03 which determines the Scan Code Used.
                                        Sending 00 as the second byte will return the Scan Code Set currently in Use
*                                $F3 Set Typematic Repeat Rate. Keyboard will Acknowledge command with FA and wait for second byte,
                                        which determines the Typematic Repeat Rate.
*                                $F4 Keyboard Enable - Clears the keyboards output buffer, enables Keyboard Scanning and returns an Acknowledgment.
*                                $F5 Keyboard Disable - Resets the keyboard, disables Keyboard Scanning and returns an Acknowledgment.
*                                $FE Resend - Upon receipt of the resend command the keyboard will re- transmit the last byte sent.
*                                $FF Reset - Resets the Keyboard.

* Returns:                   none
* Remarks:                Refer to AN1723 of Motorola for detailed description of Host-to-KBD protocol
*                                Is NOT working as per 17th June 2004. Should work more on this function.
**************************************************************************************************
*/

void PS2SendComm(INT8U cmd)
{
        PS2Key_bit_Ix = 0;                                //bit index of the byte stream, Start_bit(1), Parity(10), Stop_bit(11), ACK_bit(12)
       
        disable_interrupts(INT_EXT);        //disable external interrupt B0 on falling edge

        output_low(PS2Key_Clk);                 //host forces PS2 clock line low.
        delay_us(35);                                        //After approx. 35us, the host pulls PS2 data line low
        output_low(PS2Key_Data);                //This sequence of event signals the keyboard that
                                                                        //the host is about to transfer a command
        delay_us(125);                                        //The clock signal is released and pulled high by the keyboard's pullup
        PS2Key_ClkTris = 1;                                //resisitor after the falling edge of the data signal

        /* Transfer of data from host to keyboard will start approx. 1ms after the rising edge of the clock */
        /* shift bit to PS2Key_Data on every falling edge of the PS2Key_Clk line */
        do
        {        while (input(PS2Key_Clk))
                        ; //hold when PS2Key_Clk is high
                output_bit(PS2Key_Data, cmd&0x01);
                cmd = cmd>>1;               
                //PS2Key_DataTris=1;
                PS2Key_bit_Ix++;
        }         while(PS2Key_bit_Ix<=12);

        PS2Key_bit_Ix = 0;
        /* send data from host complete */
        PS2Key_DataTris = 1;                        //release data line, reset to input

        ext_int_edge(0, H_TO_L);                //set external interrupt to falling edge
        enable_interrupts(INT_EXT);                //release PS2 KBD clock line. driven high by PS2 KBD
}

/*
**************************************************************************************************
*                                                                        SEE IF ANY KEY IN BUFFER       
* Description:         This function checks to see if a key was pressed
* Arguments:           none
* Returns:                   TRUE if a key has been pressed
*                                FALSE if no key pressed
**************************************************************************************************
*/

BOOLEAN PS2KeyHit(void)
{
        BOOLEAN hit;

        //OS_ENTER_CRITICAL();
        hit = (BOOLEAN)(PS2KeyNRead > 0)? TRUE : FALSE;
        //OS_EXIT_CRITICAL();
        return(hit);
}

/*
*********************************************************************************************************
*                                  PS2 KEYBOARD DRIVER INITIALIZATION
*
* Description : This function initializes the PS2 driver.
* Arguments   : None.
* Returns     : None.
*********************************************************************************************************
*/

void PS2KeyInit(void)
{
        PS2KeyNRead         =0;                                //Clear the number of keys read
        PS2KeyBufInIx         =0;                                //Clear the key codes inserted at the beginning of the buffer
        PS2KeyBufOutIx        =0;                                //Clear the key codes removed at the beginning of the buffer
        PS2_BREAKCODE        =FALSE;
        PS2_SHIFT                =FALSE;

        PS2Key_DataTris =1;                                //Set Data line an input
        PS2Key_ClkTris        =1;                                //Set clock line an input

        ext_int_edge(0, H_TO_L);                //set external interrupt to falling edge
        enable_interrupts(INT_EXT);                //enable external interrupt B0
}

/*
*********************************************************************************************************
*                                     PS2 KEYBOARD INTERRUPT HANDLER
* Description:  This function is called by an interrupt handler (e.g. B0 EXT INT on falling edge)
*                                 Detect the clock pulse (High_to_Low) for new bit
*                                Total 11 bits for a complete frame (keyboard -> Host)
* Arguments  :         none
* Returns    :         none
* Notes      :         Put a scan code to PS2KeyBuf[] if a valid byte acquired
*                                Set PS2KeyNRead then
*********************************************************************************************************
*/

void PS2KeyIntHandler(void)
{
        BOOLEAN        PS2Key_Data_State;        //Temp variable for Data pin, PS2Key_Data_State
        BOOLEAN PS2Key_Clk_State;
        BOOLEAN        PS2Status_Parity;        //Parity bit       
               
                PS2Key_Data_State = input(PS2Key_Data);
                PS2Key_Clk_State  = input(PS2Key_Clk);
                PS2Key_bit_Ix++;

                if (PS2Key_bit_Ix==PS2Key_START)
                  {                //  First bit, PS2Key_START = 1 as defined under ps2key.h
                         if (PS2Key_Data_State || PS2Key_Clk_State)        PS2Key_bit_Ix=0;
                                //        Start bit clock is a high_to_low transition.
                         //        Start bit is a low bit. If data pin or Clk pin high for the Start bit,
                                //  it must be a false trigger from RB0, thus setting PS2Key_bit_Ix=0
                         PS2Key_Code=0;                               
                         PS2Status_Parity=0;       

                }
                else if (PS2Key_bit_Ix==PS2Key_PARITY)
                {                //  Parity bit, PS2Key_PARITY = 10 as defined under ps2key.h
                                PS2Status_Parity = PS2Key_Data_State;
                }
                else if (PS2Key_bit_Ix==PS2Key_STOP)
                {                // Stop bit (PS2Key_STOP = 11), put key in buffer
                                // Put valid byte in PS2KeyBuf[]
                                 PS2KeyBufIn (PS2Key_Code);                               
                         PS2Key_bit_Ix=0;
                }
                else
                {                // For all bits from 2, 3...9 (total 8-bit)
                        PS2Key_Code = PS2Key_Code >> 1;
                           if (PS2Key_Data_State)
                                        PS2Key_Code = PS2Key_Code | 0x80;
                  }
}



出0入0汤圆

发表于 2011-2-3 16:21:08 | 显示全部楼层
虽然不用PIC,但是喜欢你的小猫,顶一下

出0入0汤圆

发表于 2011-2-3 16:43:29 | 显示全部楼层
新年快乐.thanks.

出0入0汤圆

发表于 2011-3-10 13:56:37 | 显示全部楼层
很有价值!

出0入0汤圆

发表于 2011-3-10 14:55:15 | 显示全部楼层
好东西,先mark一下,谢谢

出0入0汤圆

发表于 2011-4-27 15:16:57 | 显示全部楼层
mark

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-5-5 21:43

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

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