AT/PS2 Keybord - PIC Interface?


Results 1 to 40 of 74

Threaded View

  1. #13
    mytekcontrols's Avatar
    mytekcontrols Guest


    Did you find this post helpful? Yes | No

    Arrow Installment #3b: KBmain module (2nd half)

    Here is the 2nd and final piece of the KBmain module, which is responsible for the keyboard keyscan-to-ascii decoding process. This code covers all the subroutines utilized within the first part.

    The KBmain Module Part B:
    Code:
    ;===============================================================================
    ; scrl -    Toggle Status of Scroll lock and Echo to Keyboard
    ;===============================================================================
    
    scrl:
        pscrlck = 1            'set flag to prevent routine recall
        LED = (LED ^ %001)     'toggle Scroll lock flag
        Goto LEDshow
    
    ;===============================================================================
    ; nums -    Toggle Status of Num lock and Echo to Keyboard.
    ;===============================================================================
        
    nums:
        pnumlck = 1            'set flag to prevent routine recall
        LED = (LED ^ %010)     'toggle Num lock flag
        Goto LEDshow
    
    ;===============================================================================
    ; caps -    Toggle Status of Caps lock and Echo to Keyboard.
    ;===============================================================================
    
    caps:
        pcaplck = 1            'set flag to prevent routine recall
        LED = (LED ^ %100)     'toggle Caps lock flag
        Goto LEDshow
    
    ;===============================================================================
    ; extend -  An Extended key has been pressed.
    ;===============================================================================    
    
    extend:
        KBextend = 0
        Gosub getbuf
        Select Case scancode
        Case $F0        'an extended key has been released
        KBrelextend = 1
        Goto KBexit
        
        Case $11        'Right Alt pressed
        R_alt = 1
        
        Case $14        'Right Ctrl pressed
        R_ctrl = 1
        
        Case $5A        'Enter key on Numpad pressed
        ascii = $0D
        Goto dec_done
        
        Case $4A        '"/" on Numpad pressed
        ascii = "/"
        Goto dec_done
    
        Case $71        'Delete on Nav keys pressed
        keycode = $4A
        Goto navkey1
        End Select
        
        If scancode > $83 Then KBexit         'exceeds table boundry
        Gosub keycode_tbl                     'translate to keycode
        If keycode = $80 Then KBexit          'value not defined in table
        If keycode < $31 Then KBexit          'not a navigation key
        enav = 1
    navkey:
        If keycode = $45 Then KBexit          'ignore numpad 5 key
        If numlock = 1 Then
            If ctrl = 0 Then
                If shift = 0 Then
                    If keycode = $4A Then     ' if delete then...
                    ascii = "."               ' make as period
                    Goto dec_done
                    Endif
                Endif
            Endif
        Endif
        If keycode < $4A Then Goto navkey2
    
    navkey1:    
        keycode = keycode - $19               're-index for table read
        Goto KBmain1
    
    navkey2:
        ascii = keycode + $50                   'normal key
        If shift = 1 Then
            If enav or keycode < $40 Then
            ascii = keycode + $70 'shift modified key
            Else
            ascii = keycode - $10 're-index for numbers 0-9
            Endif
            enav = 0
        Endif
        If ctrl = 1 Then  ascii = keycode + $90 'ctrl modified key
        Goto dec_done
    
    ;===============================================================================
    ; release - A Key has been Released.
    ;===============================================================================        
    
    release:
        KBrelease = 0
        gosub getbuf    
        Select Case scancode
        Case $12        'Left shift key released
        Lshift = 0
        
        Case $59        'Right shift key released
        Rshift = 0
    
        Case $14        'Left Ctrl key released
        L_ctrl = 0
        
        Case $11        'Left Alt key released
        L_alt = 0
        
        Case $58        'Caps lock key released
        pcaplck = 0
        
        Case $7E        'Scroll lock key released
        pscrlck = 0
        
        Case $77        'Num lock key released
        pnumlck = 0
        End Select
       
        Goto KBexit
    
    ;===============================================================================
    ; rel_ext - An Extended Key has been Released.
    ;===============================================================================    
    
    rel_ext:
        KBrelextend = 0
        Gosub getbuf    
        Select Case scancode
        Case $11        'Right Alt key released
        R_alt = 0
        
        Case $14        'Right Ctrl key released
        R_ctrl = 0
        End Select
    
        Goto KBexit
    
    ;===============================================================================
    ; LEDshow - Copies the 3 LSB of the LED register to the keyboard for the
    ;           keyboard's Status LEDs (i.e.; Num Lock, Caps Lock, Scroll Lock).
    ;===============================================================================
    
    LEDshow:
        scancode = $ED
        Gosub putkey
        scancode = (LED & %111)
        Gosub putkey
        If init = 1 Then
        init = 0
        Return
        Endif
        Goto KBexit
        
    ;===============================================================================
    ;                                     _putkey
    ;                             Host to Keyboard Protocol
    ;             ___    _   _   _   _   _   _   _   _   _   _   _   _   ___
    ;       CLOCK    |__| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_|
    ;
    ;       DATA       |  S | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | P | E |ACK|
    ;
    ;          S = start bit = 0    P = odd parity   E = stop bit = 1   ACK =0
    ;                      data valid on falling edge of clock
    ;===============================================================================
    putkey:
        parity = 1                  'set-up parity register (odd parity)
        
                                    'Let's initiate a com request to the keyboard.
                                    
        Low KBCLK                   'pull clock line low.
        Pauseus 35                  'pause 35uSec...
        Low KBDAT                   'pull data line low.
        Pauseus 125                 'pause 125uSec longer...
        Input KBCLK                 'then release the clock line.
        
                                    'we have now signaled the keyboard
                                    'that we wish to send data to it
                                    'so let's do it!
    
        For bitcnt = 1 To 8         'set for 8 data bits
        Gosub sendbit               'send DATA BIT
        If scancode.0 = 0 Then nextbit  'if not a 1 then continue
        parity = parity + 1         'else, add up total # of 1's
    nextbit:
        scancode = scancode >> 1    'shift out next bit
        Next bitcnt
        scancode.0 = parity.0
        Gosub sendbit               'send PARITY BIT
        scancode.0 = 1
        Gosub sendbit               'send STOP BIT
                                    'all data bits sent so...
        Input KBDAT                 'release the data line
        Pauseus 100                 'and wait for ACK BIT to pass.
        Return                      'DONE --- Scancode sent to keyboard!!!
    
        
    sendbit:
    ' time-out counter --- requires keyboard response, else bail out!
        Pauseus TOcntDLY            'determines delay for each count
        KB_timeout = KB_timeout + 1
        If KB_timeout = TOvalue Then
        Return
        Endif
    
    ' looking for keyboard clock line to go low, then send data bit to it!
        If KBCLK = 1 Then sendbit   'loop until clock line goes low
        KBDAT = scancode.0          'send data bit
        KB_timeout = 0
    clkhigh:
        If KBCLK = 0 Then clkhigh   'loop until clock line goes high   
        Return
    Here are the port I/O assignments that I used on my PIC18F2525:
    Code:
    KBCLK   VAR PORTB.2 ; INT2
    KBDAT   VAR PORTB.3
    Actually any port pin can be used for the KBDAT I/O, and any port pin capable of generating an interrupt on a high-to-low transition could be used for KBCLK (with the proper changes in the interrupt code). Both ports are used for bi-directional communications with the keyboard, and should both be provided with 4.7K pull-up resistors to +5 Vdc. No initialization is required for either of these ports (it is all handled from within the KBmain module).

    Here is the pin-out for the mini-din plug used on a typical PS2 keyboard (I hope those guys in the Proton area don't mind me borrowing this):
    <img src="http://www.picbasic.co.uk/forum/attachment.php?attachmentid=603&stc=1&d=1131493312 ">

    And here is a test routine to see if everything is working properly:
    Code:
    DEFINE HSER_TXSTA 20h
    DEFINE HSER_BAUD 9600
    
    A var byte
    B var byte
    temp var byte
    
    '============================================
    ' Test Routine
    '============================================
    mainloop:
        Gosub KBmain                ' Do keyboard decode routine and if
                                    ' a key has been pressed then a jump
                                    ' will be made to "modstart_prnt2scrn".
        Goto mainloop               ' Else, keep looping!
    
    
    modstart_prnt2scrn:
        If keydec Then              ' check if decoded key is present
        keydec = 0                  ' If so... reset key decoded flag,
        Gosub dec2hex               ' create 2 digit hex value from ascii,
                                    ' and send formatted info out RS232.
                                    
                                    ' serial output example: ascii = A ($41)
                                     
        hserout["ascii = ",ascii," ($",A,B,")",$0D,$0A]
        Endif
        Return
    
    
    dec2hex:
        temp = ascii/16
        Gosub dec2hex_tbl
        A = temp
        temp = ascii//16
        Gosub dec2hex_tbl
        B = temp
        Return
    dec2hex_tbl:    
        Lookup temp,["0123456789ABCDEF"],temp
        Return
    And this concludes the last of our series on Interfacing a PS2 Keyboard to your PIC

    P.S. Let me know if I missed something. I all stripped this stuff out of a much larger program that I wrote, and hopefully I got all the bits.
    Attached Images Attached Images  
    Last edited by mytekcontrols; - 9th November 2005 at 01:47.

Similar Threads

  1. MXcom "C-BUS" interface to PIC question
    By tcbcats in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 1st May 2014, 04:59
  2. Interface a pic with a Iphone/Itouch
    By Luckyborg in forum General
    Replies: 1
    Last Post: - 6th May 2009, 17:02
  3. 4 pin 4 x 4 keypad interface using pic basic pro
    By dunlao_john in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 15th January 2009, 06:21
  4. USB Interface using PIC
    By Tissy in forum mel PIC BASIC Pro
    Replies: 21
    Last Post: - 22nd May 2006, 17:04
  5. Serial Pic to Pic using HSER
    By Chadhammer in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 12th March 2005, 00:14

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts