PDA

View Full Version : PC keyboard to ASCII



interak
- 17th February 2009, 14:52
Hi I have recently finished writing some code in PICBASIC PRO which will read a PS/2 or AT keyboard and output 7-bit ASCII.
I know that this is not new but I have searched the Internet for a complete PIC working package and could not find one. (if I could I would have used it).

I have noticed that there are quite a few people who have asked for this code and I have also found notes to say it is a trivial matter to make a PC keyboard converter program with a PIC.
It is probably easier in assembler because there is more time to read and shift data but I found that once all the keyboard functions are in the right order it works very well with PICBASIC.
I have put the details here -
http://www.interak.pwp.blueyonder.co.uk/PCtoASCII.htm

Alan

mister_e
- 17th February 2009, 16:06
Well done Interak! Sure there's a lot of people who'll learn a lot from it.

Welcome on the forum!

Archangel
- 17th February 2009, 21:30
Hi I have recently finished writing some code in PICBASIC PRO which will read a PS/2 or AT keyboard and output 7-bit ASCII.
I know that this is not new but I have searched the Internet for a complete PIC working package and could not find one. (if I could I would have used it).

I have noticed that there are quite a few people who have asked for this code and I have also found notes to say it is a trivial matter to make a PC keyboard converter program with a PIC.
It is probably easier in assembler because there is more time to read and shift data but I found that once all the keyboard functions are in the right order it works very well with PICBASIC.
I have put the details here -
http://www.interak.pwp.blueyonder.co.uk/PCtoASCII.htm

AlanHi Alan,
Welcome to the forum, and thank you for this nice Code Example. Since you posted in PDF format someone had to retype it (I did) and it is posted below with configs for MPASM. This is a project many have discussed but never really brought to fruition, I am sure many who come here will find it useful.


'************************************************* ***************
'* Name : PCtoASCII.BAS *
'* Author : Alan Paton *
'* Notice : Copyright (c) 2009 *
'* : All Rights Reserved *
'* Date : revised Jan 2009 *
'* Version : 1.0 *
'* Notes :MPASM configs added by Joe S. *
'* http://www.interak.pwp.blueyonder.co.uk/PCtoASCII.htm *
'************************************************* ***************
@MyConfig = _HS_OSC & _LVP_OFF & _WDT_OFF & _CP_OFF
@MyConfig = MyConfig & _BODEN_OFF & _MCLRE_ON & _PWRTE_ON
@ __CONFIG MyConfig
;@ device INTRC_OSC_NOCLKOUT ;use internal oscillator
; DEFINE OSC 4
CMCON = 7
DEFINE OSC 20
PBIT VAR BYTE
D VAR BYTE[12]
SC VAR BYTE
CNT VAR BYTE
J VAR BYTE
CLK VAR PORTA.0
DAT VAR PORTA.1
CL VAR BYTE
SH VAR BYTE
AC VAR BYTE
LN VAR BYTE
LB VAR BYTE
'initialise
PAUSE 1000 ' wait for keyboard to start up
TRISB = 0
TrisA = 0
SH = 0
CNT = 0
CL = 0
GOTO SCAN
START:
IF SC=$12 OR SC = $59 THEN ' shift key up
SH = 0 ' reset shift
ENDIF
IF SC = $14 THEN ' control key up
CNT = 0 ' reset control flag
ENDIF
lb = 0 'clear last-byte flag
'Setup ports to read keyboard ******************
' ************ SCAN shifts serial scancode into SC *********
SCAN:
sc = 0 ' clear scan code
TrisA.1 = 1 ' set DAT to input
TrisA.0 = 1 ' set CLK to input
' Wait for clock transistion
LP1: ' make sure clock is high
IF CLK = 0 THEN
GOTO LP1
ENDIF


LP2:
IF CLK = 1 THEN ' clock idles high
GOTO LP2 ' wait for clock to go low
ENDIF
'clock now low - Start bit of scan code
FOR J = 0 TO 9 ' get scan code

LP3:
IF CLK = 0 THEN ' make sure clock is high
GOTO LP3
ENDIF
D(J) = DAT 'read data bit
NEXT J
' shift bits into variable SC
FOR J = 7 TO 0 STEP -1 ' D(8) & D(9) are parity & stop bits
SC = SC << 1 ' shift 1 place left
SC = SC + D(J) ' set bit 0 of SC LSB = 0 MSB = 7
NEXT J

TrisA.0 = 0 ' set CLK to output
CLK = 0 ' and hold it


IF LB = 2 THEN ' last byte of up - code - don't display
GOTO START
ENDIF
IF SC = $F0 THEN ' Check for key-up code
LB = 2 ' Set last byte flag
GOTO SCAN
ENDIF
IF SC = $12 OR SC = $59 THEN ' left and right shift keys
SH = $80 ' Set shift flag
GOTO SCAN
ENDIF
IF SC = $58 THEN ' Caps lock on
GOSUB CPLOCK
GOTO SCAN
ENDIF
IF SC = $E0 THEN ' Extended keys
GOTO SCAN ' Get next byte
ENDIF
IF SC = $14 THEN ' Left control key (& right . . $EO $14 )
CNT = 2 ' Set flag
GOTO SCAN
ENDIF
' and into SCAN CODE to ACSII conversion
' **************** CONVERT TO ASCII CODE ***************************

' scan code in SC
ASCII:
IF SC = $5A THEN 'is it CR ?
AC = $0D
GOTO ASOUT ' Yes send it
ENDIF
SC = SC + SH 'SH=$80 if shift key down (0 if not)
LN = $FF ' Set List No. to high value

' convert to ASCII (codes from 20H to 7FH)
LOOKDOWN SC,[$29,$96,$9E,$5D,$A5,$BD,$52,$C6,$C5,$BE,$D5,_
$41,$4E,$49,$4A,$45,$16,$1E,$26,$25,$2E,$36,$3D,$3 E,$46,$CC,$4C,$C1,$55,_
$C9,$CA,$D2,$9C,$B2,$A1,$A3,$A4,$AB,$B4,$B3,$C3,$B B,$C2,$CB,$BA,$B1,$C4,_
$CD,$95,$AD,$9B,$AC,$BC,$AA,$9D,$A2,$B5,$9A,$54,$6 1,$5B,$B6,$CE,$A6,$1C,_
$32,$21,$23,$24,$2B,$34,$33,$43,$3B,$42,$4B,$3A,$3 1,$44,$4D,$15,$2D,$1B,_
$2C,$3C,$2A,$1D,$22,$35,$1A,$D4,$E1,$DB,$DD,$66],LN


IF LN = $FF THEN ' Scan code not found
GOTO NUMPAD ' Now check number pad
ENDIF
'matching scan code has been found
IF CNT = 2 THEN 'Is control key pressed ?
AC = LN - $40 ' Get ASCII code
GOTO ASOUT ' Send it
ENDIF
' Caps Lock On - check for the following conditions
IF LN>$40 AND LN<$5B THEN ' Caps lock on & (semi) colon selected
AC = $3A ' ASCII code for colon
GOTO ASOUT
ENDIF
GOTO AS2 ' Send out to computer keyboard port
' Check number pad
NUMPAD:
LOOKDOWN SC,[$30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$2A,$2D,$2 B,$2E,$09,$1B],AC
GOTO ASOUT
AS2:
AC = LN + $20 ' Convert List No. to ASCII

ASOUT:
PortB.7 = 1 ' Strobe - normally high - pulse low
PAUSE 2
PortB = AC ' Send ASCII code to Port B
PAUSE 2 ' Bit 7 (strobe) is zero
PortB.7 = 1
GOTO SCAN

END
' ********************* CAPS LOCK *********************************************
CPLOCK:
IF CL = 0 THEN ' Toggle caps lock
CL = 4 ' 4 is Bit 2 0000 0100
ELSE
CL = 0
ENDIF
RETURN

original source code obtained from:
http://www.interak.pwp.blueyonder.co.uk/PCtoASCII.htm

Any Typing errors are all mine !
Note: this program's author also generously provided the compiled hex code on the web site listed for those who do not own P Basic Pro compiler, making it useful to all. A heartfelt Thank You to you Alan. Your first post and it was to share something.

aratti
- 18th February 2009, 16:29
Alan, an additional welcome to the forum from my side, and thank you for the useful code you have shared.

Al.

interak
- 19th February 2009, 10:45
Hi Thanks for your kind words, it's good to know that it could be useful.
In case anyone noticed, I should mention that there is a few lines of the code which check if Caps Lock is on and if the colon/semicolon key has been pressed.
This is required when using an old 8-bit CP/M computer as it allows for changing drives when working in Caps (i.e A: C: etc) - this is a typical function of ASCII keyboards.
This code could be removed if it is not required.
Alan

interak
- 19th February 2009, 10:54
Hi again I have just noticed that the typed-in code is not quite correct at that point - it should be.....

'CAPS LOCK ON - check for the following conditions
if LN>$40 and LN<$5B then 'caps lock on & lower case selected
AC=LN
goto ASOUT
endif
if LN=$1B then 'caps lock on & (semi)colon selected
ac=$3A 'ASCII code for colon
goto asout
endif
goto as2 'send out to computer keyboard port
'check number pad

Alan

Archangel
- 19th February 2009, 16:58
Any Typing errors are all mine !

I didn't see them, but I knew they were there.
Here is the corrected code, Thank You again Alan !


'************************************************* ***************
'* Name : UNTITLED.BAS *
'* Author : [Alan Paton] *
'* Notice : Copyright (c) 2009 *
'* : All Rights Reserved *
'* Date : 2/17/2009 *
'* Version : 1.0 *
'* Notes : *
'* http://www.interak.pwp.blueyonder.co.uk/PCtoASCII.htm *
'************************************************* ***************
@MyConfig = _HS_OSC & _LVP_OFF & _WDT_OFF & _CP_OFF
@MyConfig = MyConfig & _BODEN_OFF & _MCLRE_ON & _PWRTE_ON
@ __CONFIG MyConfig
;@ device INTRC_OSC_NOCLKOUT ;use internal oscillator
; DEFINE OSC 4
CMCON = 7
DEFINE OSC 20
PBIT VAR BYTE
D VAR BYTE[12]
SC VAR BYTE
CNT VAR BYTE
J VAR BYTE
CLK VAR PORTA.0
DAT VAR PORTA.1
CL VAR BYTE
SH VAR BYTE
AC VAR BYTE
LN VAR BYTE
LB VAR BYTE
'initialise
PAUSE 1000 ' wait for keyboard to start up
TRISB = 0
TrisA = 0
SH = 0
CNT = 0
CL = 0
GOTO SCAN
START:
IF SC=$12 OR SC = $59 THEN ' shift key up
SH = 0 ' reset shift
ENDIF
IF SC = $14 THEN ' control key up
CNT = 0 ' reset control flag
ENDIF
lb = 0 'clear last-byte flag
'Setup ports to read keyboard ******************
' ************ SCAN shifts serial scancode into SC *********
SCAN:
sc = 0 ' clear scan code
TrisA.1 = 1 ' set DAT to input
TrisA.0 = 1 ' set CLK to input
' Wait for clock transistion
LP1: ' make sure clock is high
IF CLK = 0 THEN
GOTO LP1
ENDIF


LP2:
IF CLK = 1 THEN ' clock idles high
GOTO LP2 ' wait for clock to go low
ENDIF
'clock now low - Start bit of scan code
FOR J = 0 TO 9 ' get scan code

LP3:
IF CLK = 0 THEN ' make sure clock is high
GOTO LP3
ENDIF
D(J) = DAT 'read data bit
NEXT J
' shift bits into variable SC
FOR J = 7 TO 0 STEP -1 ' D(8) & D(9) are parity & stop bits
SC = SC << 1 ' shift 1 place left
SC = SC + D(J) ' set bit 0 of SC LSB = 0 MSB = 7
NEXT J

TrisA.0 = 0 ' set CLK to output
CLK = 0 ' and hold it


IF LB = 2 THEN ' last byte of up - code - don't display
GOTO START
ENDIF
IF SC = $F0 THEN ' Check for key-up code
LB = 2 ' Set last byte flag
GOTO SCAN
ENDIF
IF SC = $12 OR SC = $59 THEN ' left and right shift keys
SH = $80 ' Set shift flag
GOTO SCAN
ENDIF
IF SC = $58 THEN ' Caps lock on
GOSUB CPLOCK
GOTO SCAN
ENDIF
IF SC = $E0 THEN ' Extended keys
GOTO SCAN ' Get next byte
ENDIF
IF SC = $14 THEN ' Left control key (& right . . $EO $14 )
CNT = 2 ' Set flag
GOTO SCAN
ENDIF
' and into SCAN CODE to ACSII conversion
' **************** CONVERT TO ASCII CODE ***************************

' scan code in SC
ASCII:
IF SC = $5A THEN 'is it CR ?
AC = $0D
GOTO ASOUT ' Yes send it
ENDIF
SC = SC + SH 'SH=$80 if shift key down (0 if not)
LN = $FF ' Set List No. to high value

' convert to ASCII (codes from 20H to 7FH)
LOOKDOWN SC,[$29,$96,$9E,$5D,$A5,$BD,$52,$C6,$C5,$BE,$D5,_
$41,$4E,$49,$4A,$45,$16,$1E,$26,$25,$2E,$36,$3D,$3 E,$46,$CC,$4C,$C1,$55,_
$C9,$CA,$D2,$9C,$B2,$A1,$A3,$A4,$AB,$B4,$B3,$C3,$B B,$C2,$CB,$BA,$B1,$C4,_
$CD,$95,$AD,$9B,$AC,$BC,$AA,$9D,$A2,$B5,$9A,$54,$6 1,$5B,$B6,$CE,$A6,$1C,_
$32,$21,$23,$24,$2B,$34,$33,$43,$3B,$42,$4B,$3A,$3 1,$44,$4D,$15,$2D,$1B,_
$2C,$3C,$2A,$1D,$22,$35,$1A,$D4,$E1,$DB,$DD,$66],LN


IF LN = $FF THEN ' Scan code not found
GOTO NUMPAD ' Now check number pad
ENDIF

' Matching scan code has been found

IF CNT = 2 THEN 'Is control key pressed ?
AC = LN - $40 ' Get ASCII code
GOTO ASOUT ' Send it
ENDIF
' CAPS LOCK ON - check for the following conditions

IF LN>$40 AND LN<$5B THEN ' caps lock on & lower case selected
AC=LN
GOTO ASOUT
ENDIF
IF LN=$1B THEN ' caps lock on & (semi)colon selected
AC=$3A 'ASCII code for colon
GOTO ASOUT
ENDIF
GOTO AS2 'send out to computer keyboard port

' check number pad

NUMPAD:
LOOKDOWN SC,[$30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$2A,$2D,$2 B,$2E,$09,$1B],AC
GOTO ASOUT
AS2:
AC = LN + $20 ' Convert List No. to ASCII

ASOUT:
PortB.7 = 1 ' Strobe - normally high - pulse low
PAUSE 2
PortB = AC ' Send ASCII code to Port B
PAUSE 2 ' Bit 7 (strobe) is zero
pORTb.7 = 1
GOTO SCAN

END
' ********************* CAPS LOCK *********************************************
CPLOCK:
IF CL = 0 THEN ' Toggle caps lock
CL = 4 ' 4 IS BIT 2 0000 0100
ELSE
CL = 0
ENDIF
RETURN

interak
- 19th February 2009, 19:38
Hi Sorry Joe :( there is another bit not quite right. The PDF on the website definitely is OK because I printed it from the program listing.

Just above the CAPS LOCK ON code should be......



GOTO ASOUT 'send it
ENDIF
'''''''''''''''''''''''''insert
IF CL=0 THEN 'Caps Lock OFF
GOTO AS2 '& matching code found
ENDIF
''''''''''''''''''''''''''
'CAPS LOCK ON

circuitpro
- 1st October 2009, 17:51
Wow! Thanks! I've been looking for some sample code, and it looks like you've got it!

I did buy one of these (just to avoid the work and get my project done quickly), and must say that it works perfectly (if they only had a USB version!!) :
http://www.multilabs.net/ezKEY.html