PIC Microcontroller PC PS2 Keyboard I/O

By Jinx

http://home.clear.net.nz/pages/joecolquitt/pic_keyboard.html

PC keyboard capture/emulation



The object of this project is to capture keys of a standard AT keyboard. They
can be stored, compiled as strings, and re-transmitted either to the PC or to
some other device, as the original key presses or as extracted commands

For example, the PIC could capture strings, and perform actions

Such as

sc:1329:040810[enter] to set the PIC's clock-calendar to 1:29pm, 4th August 2010
ky:[F1]a:1000:050810[enter] to simulate pressing F1 then 'a' at 10:00am on 5th August 2010
ir:94:2030:060810[enter] to send the number 94 by infra-red at 8:30pm on the 6th

[ ] indicates the code for a special key. [F1] has the value 0x05 for instance.
[enter] may not always be suitable for the string terminator. Perhaps [Esc] or
'<' or [Tab] for example as alternates



Circuit Schematic


This is the proof-of-concept prototype. The second version will be based on an
18F2520, which has more RAM/Flash. Also the timing will be crystal-derived for
more accurate long-term timekeeping

During development I used a header in parallel with the keyboard's wires, rather
than connect the circuit in the final in-line configuration. This allowed signals to
be read by an analyser and also the circuit power could be controlled during
programming and amendments






This is the timing diagram of the 'f' key, as sent from the keyboard to the PC
and its release, some 300ms later. 'F0' is 'any key released', '2b' tells the
PC that it was the 'f' key



Here is the PIC simulation of an 'f' key press



Note that the PIC does not have the same lengthy Clock low after the Stop bit. As
I guess it, the real keyboard holds Clock low to prevent the PC sending it commands,
which the PC would initiate by pulling Clock low for at least 60us

Read the PC keyboard specifications for that and more information - PC Keyboard Spec Sheet



PIC pin definitions ;

 
#define ir_data lata,0 ;infra-red drive
#define pickup porta,1 ;press to store keys
#define kbd_out lata,2 ;keyboard data out (transistor drive, ie inverted logic)
#define kbc_out lata,3 ;keyboard clock out (transistor drive, ie inverted logic)
#define send porta,4 ;press to manually transmit stored key(s)
;#define mclr porta,5 ;reset
#define led lata,6 ;LED
#define rw lata,7 ;LCD R/W
 
#define kbc_in portb,0 ;keyboard clock in, normally high
#define kbd_in portb,1 ;keyboard data in, normally high
#define en latb,2 ;LCD Enable
#define rs latb,3 ;LCD RS
;#define portb,4 ;LCD data, 4-bit mode
;#define portb,5
;#define portb,6
;#define portb,7
 
;================================================
; Receive and store key data
;================================================
 
;Keyboard Clock (kbc_in) and Data (kbd_in) normally high,
;open-collectors with pullups
 
;release clock and data lines (ie no transistor drive, resistors pull lines high)
 
 bcf kbd_out
 nop
 nop
 bcf kbc_out
 
;Data format -
 
;1 start bit, '0' 
;8 data bits, LSb first 
;1 parity bit, odd
;1 stop bit, '1'
;Data changes when clock = 1, valid when clock = 0
 
As the keyboard codes have no direct relationship to ASCII codes, the key code
is used as a pointer to its ASCII code in a table, but simply for display in
my case. The key code itself would be stored if required for re-transmission
 
In the s/w presented here, only the basic layout is shown. For example letters
are all lower case. By detecting the Shift, Alt and Ctrl keys, the corresponding
alternate layout can be displayed. This can be done by calculation, for example
 
a (lower case) = 0x61, Shift a (or A, upper case) = 0x41
b = 0x62, B = 0x42
 
and so on, or by adding more tables, still using the key value as the pointer
 
For example a Shift layout could be used to get Shift number characters - ! @ # $ etc
 
For my project, I used arbitrary conversions for non-alphanumeric keys so that
each key has a unique representation and assignment
 
;0x00 no conversion available (ie no key exists)
;0x20 to 0x7f LCD display code in ASCII
;
;0x80 to 0x8f function key, 0x80 + function key number
;0xf0 to 0xff special key, as assigned
;
;f0 Tab, f1 tilde, f2 left shift, f3 Ctrl, f4 Caps Lock, f5 right shift, f6 Enter
;f7 backslash, f8 backspace, f9 back space, fa Esc, fb Num Lock, fc Alt
;
;Note that right-hand versions of some same-name keys (eg Ctrl) are preceded by
;0xE0, as can be seen in the keyboard codes diagram below
;
;Others, such as the numeric keypad, are treated differently by the PC depending
;on the status of Lock keys. The transmitted code is still the same, only the
;interpretation (for display and usage etc) by s/w changes
 
;*******************************
 
kb_loop call data_st ;detect and get key into kbdat1
 
;================================================
; Convert key data to key name
;================================================
 
kb_dec movlw upper(kb_codes);base address = kb_codes
 movwf tblptru
 movlw high(kb_codes)
 movwf tblptrh
 movlw low(kb_codes)
 addwf kbdat1,w ;add k/b value
 movwf tblptrl
 tblrd*+
 movff tablat,temp0 ;get value from table
 
 movfw temp0
 bz no_key ;no equivalent
 movlw 0xf0
 cpfslt temp0 ;if temp0 < f0
 bra special ;else f? (special key)
 movlw 0x80
 cpfslt temp0 ;if temp0 < 80
 bra function ;else 8? (function key)
 
 call store ;store the key if necessary
 
 movfw temp0
 dispw ;otherwise, printable on LCD
 goto release ;detect either 0xf0 or another key pressed
 
special keys routines ;process (and store) special key, check release
 
function keys routine ;process (and store) function key, check release
 
store routine ;if desired, store the key in a queue for
 ;later retrieval and transmission
 
release call data_st ;get data
 movlw 0xf0 ;key release code
 xorwf kbdat1,w
 
At this point -
 
The XOR result will be 0, ie a key released. Get more data to determine
which key it was, if more than one key was down
 
For example,
 
if 'A' was pressed and released, the sequence will be 0x1c 0xf0 0x1c
 
If Left Ctrl '.', the sequence will be 0x14 0x49 0xf0 0x49 0xf0 0x14

ie Left Ctrl pressed, '.' pressed, '.' released, Left Ctrl released

Or the XOR result will be <> 0, meaning either a key is down and is repeating or a second key is pressed. Get more data. If the first key down is a special key such as Shift, Ctrl or Alt, then the next key detected may need to be looked up in an alternate conversion table. eg Shift ',' to make '<'
Include a timing routine to test for repeat. Default time before repeating starts is around 500ms. Time between repeats is the Typematic setting

;================================================ ; Receive key from PC ;================================================ ;Clock line shared with mouse, so use Data line for activity detection data_st btfsc kbd_in ;Data low, k/b is active bra $-2 ;Start bit btfsc kbc_in ;keyboard clock low bra $-2 btfss kbc_in ;end of Start bit bra $-2 movlw .8 ;data bit counter movwf temp1 clrf kbdat1 ;receiving buffer ;pick up 8 bits, data valid when clock is low kb8 rrncf kbdat1 ;shift bit through buffer, 1st time is dummy bcf bit_in ;data = default 0 btfsc kbc_in ;wait for clock = 0 bra $-2 btfsc kbd_in ;skip if data is 0 bsf bit_in ;else store 1 btfss kbc_in ;wait for clock = 1 bra $-2 decfsz temp1 ;counter bra kb8 ;Parity bit - receive, ignore btfsc kbc_in bra $-2 btfss kbc_in bra $-2 ;Stop bit - receive, ignore btfsc kbc_in bra $-2 btfss kbc_in bra $-2 return ;with key in kbdat1 ;================================================ ; Transmit key to PC ;================================================ ;1 start bit, '0' ;8 data bits, LSb first ;1 parity bit, odd ;1 stop bit, '1' ;Data changes when clock = 1, valid when clock = 0 ;Clock and data outputs are inverted by transistors ;ie PIC '1' drives transistor to ground the line ;data in temp0 transmit movwf temp0 ;byte to transmit movlw .8 movwf temp1 ;data bit counter clrf temp4 ;parity counter ;Start bit bsf kbd_out ;data line low call _17us ;hold for 17us bsf kbc_out ;clock line low call _44us ;hold for 44us bcf kbc_out ;clock line high call _17us ;5us > delay < 25us before data transition ;begin data transmission. key_loop movlw b'00000001' ;test data bit to send andwf temp0,w bnz _1bit ;data = 1 _0bit bsf kbd_out ;data = 0 (ground data line) bra bit_del _1bit bcf kbd_out ;data = 1 (release data line) incf temp4 ;parity count bit_del call _25us ;25us delay bsf kbc_out ;data valid call _44us ;hold for 44us bcf kbc_out ;clock high call _17us ;hold for 17us rrncf temp0 ;shift in next data bit decfsz temp1 ;bit counter bra key_loop movlw b'00000001' ;test parity count andwf temp4,w bz parity1 parity0 bsf kbd_out ;result odd, send '0' -> odd parity bra tx_end parity1 bcf kbd_out ;result even, send '1' -> odd parity tx_end call _25us bsf kbc_out call _44us bcf kbc_out ;Stop bit call _17us bcf kbd_out ;data line idle call _25us usec usec bsf kbc_out ;clock line low call _44us bcf kbc_out ;clock line idle return


Keyboard codes, as transmitted to PC

 
;================================================
 
;convert keyboard data to key name and/or ASCII character for PIC's use
;
;data received from keyboard
;
;00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f data received
; F9 F5 F3 F1 F2 F12 F10 F8 F6 F4 Tab ~ = key pressed
 
;10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
; Alt LSh Ctl q 1 z s a w 2 
 
;20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
; c x d e 4 3 SP v f t r 5 
 
;30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
; n b h g y 6 m j u 7 8 
 
;40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f
; , k i o 0 9 . l p - 
 
;50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f
; [ = Cap RSh Ent ] \ 
 
;60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 'n' indicates
; Bksp 1n 4n 7n numeric keypad
 
;70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f
;0n .n 2n 5n 6n 8n Esc Num F11 +n 3n *n -n
 
;80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f
; F7
 
 org kb_codes ;ASCII and special codes for keys
 
Examples -
 
;key received is 0x2d. Data at table address 0x2d is 0x72 = ASCII r
;key received is 0x78. Data at table address 0x78 is 0x8b = F11
;key received is 0x12. Data at table address 0x12 is 0xf2 = Left Shift
;key received is 0x47. Data at table address 0x47 is 0x00 = no equivalent
 
;18F table, basic layout
 
; 1 0 3 2 5 4 7 6 9 8 b a d c f e
 data 0x8900,0x8500,0x8183,0x8c82,0x8a00,0x8688,0xfc84,0x00f1 ;0x
 data 0xf900,0x00f2,0x71f3,0x0031,0x0000,0x737a,0x7761,0x0032 ;1x
 data 0x6300,0x6478,0x3465,0x0033,0x2000,0x6676,0x7274,0x0035 ;2x
 data 0x6e00,0x6862,0x7967,0x0036,0x0000,0x6a6d,0x3775,0x0038 ;3x
 data 0x2c00,0x696b,0x306f,0x0039,0x2e00,0x6c00,0x7000,0x002d ;4x
 data 0x0000,0x0000,0x3d7b,0x0000,0xf5f4,0x7df6,0xf700,0x0000 ;5x
 data 0x0000,0x0000,0x0000,0x00f8,0x3100,0x3400,0x0037,0x0000 ;6x
 data 0x2e30,0x3532,0x3836,0xfbfa,0x2b8b,0x0033,0x002a,0x002d ;7x
 data 0x0000,0x8700,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 ;8x
 
 
 
;16F table, basic layout
;
; 0 1 2 3 4 5 6 7 8 9 a b c d e f
; dt 0x00,0x89,0x00,0x85,0x83,0x81,0x82,0x8c,0x00,0x8a,0x88,0x86,0x84,0xfc,0xf1,0x00 ;0x
; dt 0x00,0xf9,0xf2,0x00,0xf3,0x71,0x31,0x00,0x00,0x00,0x7a,0x73,0x61,0x77,0x32,0x00 ;1x
; dt 0x00,0x63,0x78,0x64,0x65,0x34,0x33,0x00,0x00,0x20,0x76,0x66,0x74,0x72,0x35,0x00 ;2x
; dt 0x00,0x6e,0x62,0x68,0x67,0x79,0x36,0x00,0x00,0x00,0x6d,0x6a,0x75,0x37,0x38,0x00 ;3x
; dt 0x00,0x2c,0x6b,0x69,0x6f,0x30,0x39,0x00,0x00,0x2e,0x00,0x6c,0x00,0x70,0x2d,0x00 ;4x
; dt 0x00,0x00,0x00,0x00,0x7b,0x3d,0x00,0x00,0xf4,0xf5,0xf6,0x7d,0x00,0xf7,0x00,0x00 ;5x
; dt 0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x00,0x00,0x31,0x00,0x34,0x37,0x00,0x00,0x00 ;6x
; dt 0x30,0x2e,0x32,0x35,0x36,0x38,0xfa,0xfb,0x8b,0x2b,0x33,0x00,0x2a,0x00,0x2d,0x00 ;7x
; dt 0x00,0x00,0x00,0x87,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ;8x

Questions:

Code:


file: /Techref/microchip/io/dev/keyboard/ps2-jc.htm, 16KB, , updated: 2020年6月24日 09:34, local time: 2025年9月2日 06:02,
40.74.122.252:LOG IN

©2025 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?
Please DO link to this page! Digg it! / MAKE!

<A HREF="http://techref.massmind.org/techref/microchip/io/dev/keyboard/ps2-jc.htm"> PIC Microcontroler, Microchip PIC, PS2 Keyboard, PC keyboard capture, PC keyboard emulator</A>

After you find an appropriate page, you are invited to your to this massmind site! (posts will be visible only to you before review) Just type a nice message (short messages are blocked as spam) in the box and press the Post button. (HTML welcomed, but not the <A tag: Instead, use the link box to link to another page. A tutorial is available Members can login to post directly, become page editors, and be credited for their posts.


Link? Put it here:
if you want a response, please enter your email address:
Attn spammers: All posts are reviewed before being made visible to anyone other than the poster.
Did you find what you needed?

Welcome to massmind.org!

Welcome to techref.massmind.org!

.

AltStyle によって変換されたページ (->オリジナル) /