Bascom AT89051Keyboard
$regfile = "reg51.dat"
$crystal = 11059200
$baud = 9600
Dim B1 As Byte , B2 As Byte , N As Byte , Status As Byte , Key As Byte
Dim Caps As Bit , Caps_lock As Bit , Ctrl As Bit , Alt As Bit , Tmp As Bit
Dim Temp As String * 1
Declare Sub Tx_byte(b1 As Byte)
Declare Sub Rx_byte
Declare Sub Kbd_status
Kbd_data Alias P1.1 ' connected with 4K7 pull up resistor
Kbd_clk Alias P1.0 ' connected with 4K7 pull up resistor
Buzzer Alias P3.7 ' for details see BASCOM51 documentation
Res_sw Alias P3.5 ' optional output (see code)
Dim Frequency As Const 2048
Dim Duration As Const 50
Dim L_shift As Const &H12
Dim R_shift As Const &H59
Dim Ctrl_key As Const &H14
Dim Alt_key As Const &H11
Dim Caps_key As Const &H58
Dim Scroll_key As Const &H7E
'--[Beginning of Program]---
Reset Kbd_clk ' disable the Keyboard
Waitms 100
Do
Tx_byte &HFF ' reset the Keyboard and wait
Rx_byte ' till the Keyboard answer with
If B1 = &HFA Then Exit Do ' acknowledge byte
If B1 = &HAA Then Exit Do ' or Power On Self Test OK code
Loop
Print
Print "*** AT PC Keyboard Interface ***"
Print " Test epi coba saja "
Print
' KBD LED: Status.0 - Scroll Lock, Status.1 - Num Lock, Status.2 - Caps Lock
Status = 2 ' initially Num Lock On
Kbd_status
Do ' KEY variable will hold ASCII value of pressed key
Key = 0 ' initial value
Rx_byte ' read scan code from PC keyboard into B1
Select Case B1
Case Ctrl_key:
Set Ctrl ' mark that CTRL key is pressed
B1 = 0
Case Alt_key:
Set Alt ' same as above but for ALT key ...
B1 = 0
Case L_shift:
Set Caps ' same as above but for Left SHIFT key ...
B1 = 0
Case R_shift:
Set Caps ' same as above but for Right SHIFT key ...
B1 = 0
Case &HE0: ' extended codes are not handled!
B1 = 0
Case &HF0: ' BREAK CODE is detected (key depressed)
Rx_byte ' read again to see which key is depressed
If B1 = L_shift Then ' and keep tracking flags...
Reset Caps
Elseif B1 = R_shift Then
Reset Caps
End If
If B1 = Ctrl_key Then
Reset Ctrl
Elseif B1 = Alt_key Then
Reset Alt
End If
B1 = 0
Case Caps_key: ' in a case of CAPS LOCK key
Caps_lock = Caps_lock Xor 1 ' there must be calculated status of it's LED
Status = Status Xor 4
Kbd_status ' and then we must send it to keyboard
B1 = 0
Case Scroll_key: ' I use combination of Ctrl + Alt + ScrLock
Tmp = Ctrl And Alt ' keys to generate reset signal...
If Tmp = 1 Then
Reset Res_sw ' ...for my host controller
Status = Status Xor 1 ' (Scroll Lock LED will lit and buzzer beeps)
Kbd_status
Sound Buzzer , Duration , 512
Waitms 100
Sound Buzzer , Duration , 512
Waitms 100
Sound Buzzer , Duration , 512
Waitms 100
Set Res_sw
Status = Status Xor 1 ' turn off Scroll Lock LED
Kbd_status
End If
B1 = 0
Case Else: ' handling of "printable" characters
If B1 > 131 Then ' this program handles only lower part
B1 = 0 ' of ASCII code table (with exception of
End If ' function keys - see lookup table)
If Caps = 1 Then
Key = Lookup(b1 , With_shift) ' one table is for SHIFT + key combination
Else
Key = Lookup(b1 , No_shift) ' and another is for key WITHOUT SHIFT
End If
If Caps_lock = 1 Then
If Caps = 0 Then ' if CAPS LOCK was ON and there is no
Temp = Chr(key) ' SHIFT + key combination, then convert
Temp = Ucase(temp) ' pressed key into upper case letter
Key = Asc(temp)
End If
End If
End Select
If B1 <> 0 Then
Print Key
'Print Chr(key); ' and print pressed key
End If
Waitms 10
Print "lewat"
' dummy delay ...
Loop
'--[Receive Byte from Keyboard]---
Sub Rx_byte
Set Kbd_clk ' enable Keyboard
mov {n},#0
jb Kbd_clk,*+0 ' wait CLK to become zero
sjmp .L_error ' if not exit via error label
Incr N ' this is counter of received bits
acall zero2one
mov a,{b1} ' prepare buffer
mov c,Kbd_data ' read DATA bit
rrc a ' read it into the buffer
mov {b1},a ' store buffer value
mov a,{n}
cjne a,#8,L_cont ' if it isn't last bit repeat
mov a,{b2} ' prepare buffer
mov c,Kbd_data ' read ODD PARITY bit
rrc a ' store it into the buffer
mov c,Kbd_data ' read STOP bit
rrc a ' store it into the buffer
rrc a ' now align bits to right...
rrc a
rrc a
rrc a
rrc a
rrc a
anl a,#3 ' extract valuable bits and
mov {b2},a ' store to buffer
' check STOP bit
anl a,#2
jz .L_error
' PARITY checking
mov a,{b1}
mov c,psw.0 ' this is EVEN PARITY
rlc a
anl a,#1
xch a,{b2}
anl a,#1
xrl a,{b2}
jz .L_error
sjmp .L_end
L_error: ' exit in case of an error
Waitms 1 ' wait end of transmission
mov a,#0
mov {b1},a
L_end:
Reset Kbd_clk ' stop the Keyboard
End Sub
Sub Tx_byte(b1 As Byte)
B2 = 8
Reset Kbd_clk ' break the Keyboard
Delay ' (safety reasons)
Delay
Delay
Delay
Delay
Delay
Reset Kbd_data ' request to send
Set Kbd_clk ' enable the Keyboard
!L_tx_data:
rrc a
mov Kbd_data,c
acall zero2one
djnz {b2},L_tx_data
mov c,psw.0 ' this is Even parity
cpl c ' and Keyboard needs Odd parity
mov Kbd_data,c ' send parity bit
acall zero2one
' STOP BIT
Set Kbd_data ' send stop bit
acall zero2one
Reset Kbd_clk ' stop the keyboard
End Sub
'--[ASM Subroutine wait for falling edge]--
!zero2one:
jnb Kbd_clk,*+0 ' wait till CLK rise
jb Kbd_clk,*+0 ' now wait till CLK fall down
ret
'-[Subroutine for sending LED status to the Keyboard]--
Sub Kbd_status:
Tx_byte &HED
Rx_byte
Tx_byte Status
Rx_byte
End Sub
' Keyboard mapping is for ordinary 101 keys keyboard (standard US layout).
No_shift:
Data "F9" , "" , "F5" , "F3" , "F1" , "F2" , "F12" , "" , "F10" , "F8"
Data "F6" , "F4" , "TAB" , "`" , "" , "" , "LAlt" , "LSh" , "" , "LCtr" , "q"
Data "1" , "" , "" , "" , "z" , "s" , "a" , "w" , "2" , ""
Data "" , "c" , "x" , "d" , "e" , "4" , "3" , "" , "" , " "
Data "v" , "f" , "t" , "r" , "5" , "" , "" , "n" , "b" , "h"
Data "g" , "y" , "6" , "" , "" , "" , "m" , "j" , "u" , "7"
Data "8" , "" , "" , "," , "k" , "i" , "o" , "0" , "9" , ""
Data "" , "." , "/" , "l" , ";" , "p" , "-" , "" , "" , ""
Data "'" , "" , "[" , "=" , "" , "" , "Caps" , "RSht" , "Enter" , "]"
Data "" , "\" , "" , "" , "" , "" , "" , "" , "" , ""
Data "BkSp" , "" , "" , "1" , "" , "4" , "7" , "" , "" , ""
Data "0" , "." , "2" , "5" , "6" , "8" , "ESC" , "NumLck" , "F11" , "+"
Data "3" , "-" , "*" , "9" , "ScrLck" , "" , "" , "" , "" , "F7"
Data 137 , 0 , 133 , 131 , 129 , 130 , 140 , 0 , 138 , 136
Data 134 , 132 , 9 , 96 , 0 , 0 , 0 , 0 , 0 , 0 , 113
Data 49 , 0 , 0 , 0 , 122 , 115 , 97 , 119 , 50 , 0
Data 0 , 99 , 120 , 100 , 101 , 52 , 51 , 0 , 0 , 32
Data 118 , 102 , 116 , 114 , 53 , 0 , 0 , 110 , 98 , 104
Data 103 , 121 , 54 , 0 , 0 , 0 , 109 , 106 , 117 , 55
Data 56 , 0 , 0 , 44 , 107 , 105 , 111 , 48 , 57 , 0
Data 0 , 46 , 47 , 108 , 59 , 112 , 45 , 0 , 0 , 0
Data 39 , 0 , 91 , 61 , 0 , 0 , 0 , 0 , 13 , 93
Data 0 , 92 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
Data 8 , 0 , 0 , 49 , 0 , 52 , 55 , 0 , 0 , 0
Data 48 , 46 , 50 , 53 , 54 , 56 , 27 , 0 , 139 , 43
Data 51 , 45 , 42 , 57 , 0 , 0 , 0 , 0 , 0 , 135
With_shift:
Data "F9" , "" , "F5" , "F3" , "F1" , "F2" , "F12" , "" , "F10" , "F8"
Data "F6" , "F4" , "TAB" , "~" , "" , "" , "LAlt" , "LSh" , "" , "LCtr" , "Q"
Data "!" , "" , "" , "" , "Z" , "S" , "A" , "W" , "@" , ""
Data "" , "C" , "X" , "D" , "E" , "$" , "#" , "" , "" , " "
Data "V" , "F" , "T" , "R" , "%" , "" , "" , "N" , "B" , "H"
Data "G" , "Y" , "^" , "" , "" , "" , "M" , "J" , "U" , "&"
Data "*" , "" , "" , "<" , "K" , "I" , "O" , ")" , "(" , ""
Data "" , ">" , "?" , "L" , ":" , "P" , "_" , "" , "" , ""
Data 34 , 0 , "" , "{" , "+" , "" , "" , "Caps" , "RSht" , "Enter" , "}"
Data "" , "|" , "" , "" , "" , "" , "" , "" , "" , ""
Data "BkSp" , "" , "" , "1" , "" , "4" , "7" , "" , "" , ""
Data "0" , "." , "2" , "5" , "6" , "8" , "ESC" , "NumLck" , "F11" , "+"
Data "3" , "-" , "*" , "9" , "ScrLck" , "" , "" , "" , "" , "F7"
Data 137 , 0 , 133 , 131 , 129 , 130 , 140 , 0 , 138 , 136
Data 134 , 132 , 9 , 126 , 0 , 0 , 0 , 0 , 0 , 0 , 81
Data 33 , 0 , 0 , 0 , 90 , 83 , 65 , 87 , 64 , 0
Data 0 , 67 , 88 , 68 , 69 , 36 , 35 , 0 , 0 , 32
Data 86 , 70 , 84 , 82 , 37 , 0 , 0 , 78 , 66 , 72
Data 71 , 89 , 94 , 0 , 0 , 0 , 77 , 74 , 85 , 38
Data 42 , 0 , 0 , 60 , 75 , 73 , 79 , 41 , 40 , 0
Data 0 , 62 , 63 , 76 , 58 , 80 , 95 , 0 , 0 , 0
Data 34 , 0 , 123 , 43 , 0 , 0 , 0 , 0 , 13 , 125
Data 0 , 124 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
Data 8 , 0 , 0 , 49 , 0 , 52 , 55 , 0 , 0 , 0
Data 48 , 46 , 50 , 53 , 54 , 56 , 27 , 0 , 139 , 43
Data 51 , 45 , 42 , 57 , 0 , 0 , 0 , 0 , 0 , 135
'--[End of Program]--
$crystal = 11059200
$baud = 9600
Dim B1 As Byte , B2 As Byte , N As Byte , Status As Byte , Key As Byte
Dim Caps As Bit , Caps_lock As Bit , Ctrl As Bit , Alt As Bit , Tmp As Bit
Dim Temp As String * 1
Declare Sub Tx_byte(b1 As Byte)
Declare Sub Rx_byte
Declare Sub Kbd_status
Kbd_data Alias P1.1 ' connected with 4K7 pull up resistor
Kbd_clk Alias P1.0 ' connected with 4K7 pull up resistor
Buzzer Alias P3.7 ' for details see BASCOM51 documentation
Res_sw Alias P3.5 ' optional output (see code)
Dim Frequency As Const 2048
Dim Duration As Const 50
Dim L_shift As Const &H12
Dim R_shift As Const &H59
Dim Ctrl_key As Const &H14
Dim Alt_key As Const &H11
Dim Caps_key As Const &H58
Dim Scroll_key As Const &H7E
'--[Beginning of Program]---
Reset Kbd_clk ' disable the Keyboard
Waitms 100
Do
Tx_byte &HFF ' reset the Keyboard and wait
Rx_byte ' till the Keyboard answer with
If B1 = &HFA Then Exit Do ' acknowledge byte
If B1 = &HAA Then Exit Do ' or Power On Self Test OK code
Loop
Print "*** AT PC Keyboard Interface ***"
Print " Test epi coba saja "
' KBD LED: Status.0 - Scroll Lock, Status.1 - Num Lock, Status.2 - Caps Lock
Status = 2 ' initially Num Lock On
Kbd_status
Do ' KEY variable will hold ASCII value of pressed key
Key = 0 ' initial value
Rx_byte ' read scan code from PC keyboard into B1
Select Case B1
Case Ctrl_key:
Set Ctrl ' mark that CTRL key is pressed
B1 = 0
Case Alt_key:
Set Alt ' same as above but for ALT key ...
B1 = 0
Case L_shift:
Set Caps ' same as above but for Left SHIFT key ...
B1 = 0
Case R_shift:
Set Caps ' same as above but for Right SHIFT key ...
B1 = 0
Case &HE0: ' extended codes are not handled!
B1 = 0
Case &HF0: ' BREAK CODE is detected (key depressed)
Rx_byte ' read again to see which key is depressed
If B1 = L_shift Then ' and keep tracking flags...
Reset Caps
Elseif B1 = R_shift Then
Reset Caps
End If
If B1 = Ctrl_key Then
Reset Ctrl
Elseif B1 = Alt_key Then
Reset Alt
End If
B1 = 0
Case Caps_key: ' in a case of CAPS LOCK key
Caps_lock = Caps_lock Xor 1 ' there must be calculated status of it's LED
Status = Status Xor 4
Kbd_status ' and then we must send it to keyboard
B1 = 0
Case Scroll_key: ' I use combination of Ctrl + Alt + ScrLock
Tmp = Ctrl And Alt ' keys to generate reset signal...
If Tmp = 1 Then
Reset Res_sw ' ...for my host controller
Status = Status Xor 1 ' (Scroll Lock LED will lit and buzzer beeps)
Kbd_status
Sound Buzzer , Duration , 512
Waitms 100
Sound Buzzer , Duration , 512
Waitms 100
Sound Buzzer , Duration , 512
Waitms 100
Set Res_sw
Status = Status Xor 1 ' turn off Scroll Lock LED
Kbd_status
End If
B1 = 0
Case Else: ' handling of "printable" characters
If B1 > 131 Then ' this program handles only lower part
B1 = 0 ' of ASCII code table (with exception of
End If ' function keys - see lookup table)
If Caps = 1 Then
Key = Lookup(b1 , With_shift) ' one table is for SHIFT + key combination
Else
Key = Lookup(b1 , No_shift) ' and another is for key WITHOUT SHIFT
End If
If Caps_lock = 1 Then
If Caps = 0 Then ' if CAPS LOCK was ON and there is no
Temp = Chr(key) ' SHIFT + key combination, then convert
Temp = Ucase(temp) ' pressed key into upper case letter
Key = Asc(temp)
End If
End If
End Select
If B1 <> 0 Then
Print Key
'Print Chr(key); ' and print pressed key
End If
Waitms 10
Print "lewat"
' dummy delay ...
Loop
'--[Receive Byte from Keyboard]---
Sub Rx_byte
Set Kbd_clk ' enable Keyboard
mov {n},#0
jb Kbd_clk,*+0 ' wait CLK to become zero
' START bit
jnb Kbd_data,L_cont ' if START bit is zero continuesjmp .L_error ' if not exit via error label
' DATA bits
!L_cont:Incr N ' this is counter of received bits
acall zero2one
mov a,{b1} ' prepare buffer
mov c,Kbd_data ' read DATA bit
rrc a ' read it into the buffer
mov {b1},a ' store buffer value
mov a,{n}
cjne a,#8,L_cont ' if it isn't last bit repeat
' PARITY bit
acall zero2onemov a,{b2} ' prepare buffer
mov c,Kbd_data ' read ODD PARITY bit
rrc a ' store it into the buffer
' STOP bit
acall zero2onemov c,Kbd_data ' read STOP bit
rrc a ' store it into the buffer
rrc a ' now align bits to right...
rrc a
rrc a
rrc a
rrc a
rrc a
anl a,#3 ' extract valuable bits and
mov {b2},a ' store to buffer
' check STOP bit
anl a,#2
jz .L_error
' PARITY checking
mov a,{b1}
mov c,psw.0 ' this is EVEN PARITY
rlc a
anl a,#1
xch a,{b2}
anl a,#1
xrl a,{b2}
jz .L_error
sjmp .L_end
L_error: ' exit in case of an error
Waitms 1 ' wait end of transmission
mov a,#0
mov {b1},a
L_end:
Reset Kbd_clk ' stop the Keyboard
End Sub
'--[Transmit Byte to Keyboard]--
Sub Tx_byte(b1 As Byte)
B2 = 8
Reset Kbd_clk ' break the Keyboard
Delay ' (safety reasons)
Delay
Delay
Delay
Delay
Delay
Reset Kbd_data ' request to send
Set Kbd_clk ' enable the Keyboard
' START BIT
acall zero2one
' DATA BITS
mov a,{b1}!L_tx_data:
rrc a
mov Kbd_data,c
acall zero2one
djnz {b2},L_tx_data
' PARITY BIT
mov a,{b1} ' calculate parity bitmov c,psw.0 ' this is Even parity
cpl c ' and Keyboard needs Odd parity
mov Kbd_data,c ' send parity bit
acall zero2one
' STOP BIT
Set Kbd_data ' send stop bit
acall zero2one
' KBD ACK BIT
acall zero2oneReset Kbd_clk ' stop the keyboard
End Sub
'--[ASM Subroutine wait for falling edge]--
!zero2one:
jnb Kbd_clk,*+0 ' wait till CLK rise
jb Kbd_clk,*+0 ' now wait till CLK fall down
ret
'-[Subroutine for sending LED status to the Keyboard]--
Sub Kbd_status:
Tx_byte &HED
Rx_byte
Tx_byte Status
Rx_byte
End Sub
'--[Scan Code to ASCII conversion table]--
' Ini Untuk Lookup tabel untuk menghendel keyboard' Keyboard mapping is for ordinary 101 keys keyboard (standard US layout).
No_shift:
'(
Data ""Data "F9" , "" , "F5" , "F3" , "F1" , "F2" , "F12" , "" , "F10" , "F8"
Data "F6" , "F4" , "TAB" , "`" , "" , "" , "LAlt" , "LSh" , "" , "LCtr" , "q"
Data "1" , "" , "" , "" , "z" , "s" , "a" , "w" , "2" , ""
Data "" , "c" , "x" , "d" , "e" , "4" , "3" , "" , "" , " "
Data "v" , "f" , "t" , "r" , "5" , "" , "" , "n" , "b" , "h"
Data "g" , "y" , "6" , "" , "" , "" , "m" , "j" , "u" , "7"
Data "8" , "" , "" , "," , "k" , "i" , "o" , "0" , "9" , ""
Data "" , "." , "/" , "l" , ";" , "p" , "-" , "" , "" , ""
Data "'" , "" , "[" , "=" , "" , "" , "Caps" , "RSht" , "Enter" , "]"
Data "" , "\" , "" , "" , "" , "" , "" , "" , "" , ""
Data "BkSp" , "" , "" , "1" , "" , "4" , "7" , "" , "" , ""
Data "0" , "." , "2" , "5" , "6" , "8" , "ESC" , "NumLck" , "F11" , "+"
Data "3" , "-" , "*" , "9" , "ScrLck" , "" , "" , "" , "" , "F7"
')
Data 0Data 137 , 0 , 133 , 131 , 129 , 130 , 140 , 0 , 138 , 136
Data 134 , 132 , 9 , 96 , 0 , 0 , 0 , 0 , 0 , 0 , 113
Data 49 , 0 , 0 , 0 , 122 , 115 , 97 , 119 , 50 , 0
Data 0 , 99 , 120 , 100 , 101 , 52 , 51 , 0 , 0 , 32
Data 118 , 102 , 116 , 114 , 53 , 0 , 0 , 110 , 98 , 104
Data 103 , 121 , 54 , 0 , 0 , 0 , 109 , 106 , 117 , 55
Data 56 , 0 , 0 , 44 , 107 , 105 , 111 , 48 , 57 , 0
Data 0 , 46 , 47 , 108 , 59 , 112 , 45 , 0 , 0 , 0
Data 39 , 0 , 91 , 61 , 0 , 0 , 0 , 0 , 13 , 93
Data 0 , 92 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
Data 8 , 0 , 0 , 49 , 0 , 52 , 55 , 0 , 0 , 0
Data 48 , 46 , 50 , 53 , 54 , 56 , 27 , 0 , 139 , 43
Data 51 , 45 , 42 , 57 , 0 , 0 , 0 , 0 , 0 , 135
With_shift:
'(
Data ""Data "F9" , "" , "F5" , "F3" , "F1" , "F2" , "F12" , "" , "F10" , "F8"
Data "F6" , "F4" , "TAB" , "~" , "" , "" , "LAlt" , "LSh" , "" , "LCtr" , "Q"
Data "!" , "" , "" , "" , "Z" , "S" , "A" , "W" , "@" , ""
Data "" , "C" , "X" , "D" , "E" , "$" , "#" , "" , "" , " "
Data "V" , "F" , "T" , "R" , "%" , "" , "" , "N" , "B" , "H"
Data "G" , "Y" , "^" , "" , "" , "" , "M" , "J" , "U" , "&"
Data "*" , "" , "" , "<" , "K" , "I" , "O" , ")" , "(" , ""
Data "" , ">" , "?" , "L" , ":" , "P" , "_" , "" , "" , ""
Data 34 , 0 , "" , "{" , "+" , "" , "" , "Caps" , "RSht" , "Enter" , "}"
Data "" , "|" , "" , "" , "" , "" , "" , "" , "" , ""
Data "BkSp" , "" , "" , "1" , "" , "4" , "7" , "" , "" , ""
Data "0" , "." , "2" , "5" , "6" , "8" , "ESC" , "NumLck" , "F11" , "+"
Data "3" , "-" , "*" , "9" , "ScrLck" , "" , "" , "" , "" , "F7"
')
Data 0Data 137 , 0 , 133 , 131 , 129 , 130 , 140 , 0 , 138 , 136
Data 134 , 132 , 9 , 126 , 0 , 0 , 0 , 0 , 0 , 0 , 81
Data 33 , 0 , 0 , 0 , 90 , 83 , 65 , 87 , 64 , 0
Data 0 , 67 , 88 , 68 , 69 , 36 , 35 , 0 , 0 , 32
Data 86 , 70 , 84 , 82 , 37 , 0 , 0 , 78 , 66 , 72
Data 71 , 89 , 94 , 0 , 0 , 0 , 77 , 74 , 85 , 38
Data 42 , 0 , 0 , 60 , 75 , 73 , 79 , 41 , 40 , 0
Data 0 , 62 , 63 , 76 , 58 , 80 , 95 , 0 , 0 , 0
Data 34 , 0 , 123 , 43 , 0 , 0 , 0 , 0 , 13 , 125
Data 0 , 124 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
Data 8 , 0 , 0 , 49 , 0 , 52 , 55 , 0 , 0 , 0
Data 48 , 46 , 50 , 53 , 54 , 56 , 27 , 0 , 139 , 43
Data 51 , 45 , 42 , 57 , 0 , 0 , 0 , 0 , 0 , 135
'--[End of Program]--