📄 interfacing the pc's keyboard.htm
字号:
<P>Remember the KBD Clock line? If you take it low, the keyboard will buffer
any keys pressed. The Keyboard will only attempt to send when both the Data
and Clock lines are idle (high). As it can take considerable time to decode
the keys pressed, we must stop the keyboard from sending data. If not, some of
the data may be lost or corrupted. </P></FONT><PRE> Receive ldx #08 ;Number of Bits
clr PAR ;Clear Parity Register
bclr clk,DDRA ;Clear to Send
brset clk,PORTA,* ;wait on idle Clock
brset data,PORTA,Receive ;False Start Bit, Restart
</PRE><FONT face=ARIAL>
<P>The program, will keep the KBD Clock line low, unless it is ready to accept
data. We will use a loop to retrieve the data bits from the keyboard, thus we
will load index register X with the number of bits be want to receive. PAR
will be used to verify the parity bit at the end of the transmission. We must
clear this first. </P>
<P>We can then place the KBD Clock line in the idle state so that the keyboard
will start transmitting data if a key has been pressed. The program then loops
while the clock line is Idle. If the KBD clock goes low, the loop is broken
and the KBD Data pin is read. This should be the start bit which should be
low. If not we branch to the start of the receive routine and try again.
</P></FONT><PRE> Recdata ror byte
jsr highlow ;Wait for high to low Transition
brset data,PORTA,Recset
bclr 7,byte
jmp Recnext
Recset bset 7,byte
inc PAR
Recnext decx
bne Recdata ;Loop until 8 bits been received
</PRE><FONT face=ARIAL>
<P>Once the start bit has been detected, the 8 data bits must follow. The data
is only valid on the falling edge of the clock. The subroutine highlow shown
below will wait for the falling edge of the clock. </P></FONT><PRE> highlow brclr clk,PORTA,* ;Loop until Clk High
brset clk,PORTA,* ;Loop until Clk Low
rts
</PRE><FONT face=ARIAL>
<P>After the falling edge we can read the level of the KBD Data line. If it is
high we can set the MSbit of the byte or if it is clear, we can clear it. You
will notice if the bit is set, we also increment PAR. This keeps track of the
number of 1's in the byte and thus can be used to verify the Parity Bit. Index
register X is decremented as we have read a bit. It then repeats the above
process, until the entire 8 bits have been read. </P></FONT><PRE> lda PORTA ; MSb is Parity.
rola ; Shift MSbit to LSbit.
rola ; thru carry
eor PAR
and #$01
beq r_error
</PRE><FONT face=ARIAL>
<P>After the 8 data bits, comes the dreaded parity bit. We could ignore it if
we wanted to, but we may as well do something about it. We have been keeping a
tally of the number of 1's in PAR. The keyboard uses odd parity, thus the
parity bit should be the complement of the LSbit in memory location, PAR. By
exclusive OR-ing PAR with the Parity Bit, we get a 1 if both the bits are
different. I.e a '1' if the parity bit checks out. </P>
<P>As we are only interested in the LSbit we can quite happy XOR the
accumulator with PAR. Then we single out the LSb using the AND function. If
the resultant is zero, then a parity error has occurred and the program
branches to r_error. </P></FONT><PRE> jsr highlow
brclr data,PORTA,r_error ;Stop Bit Detection
bset clk,DDRA ;Prevent Keyboard from sending data
;(Clear to Send)
rts
</PRE><FONT face=ARIAL>
<P>After the Parity Bits comes the Stop Bit. Once again we can ignore it if we
desire. However we have chosen to branch to an error routine if this occurs.
The stop bit should be set, thus an error occurs when it is clear. </P></FONT><PRE> r_error lda #$FE ;Resend
sta byte
jsr Transmit
jmp Receive ;Try again
</PRE><FONT face=ARIAL>
<P>What you do as error handling is up to you. In most cases it will never be
executed. In fact I don't yet know if the above error handling routine works.
I need to program another HC705 to send a false parity bit. I've tried it out
in close proximity to the Washing Machine, but I really need a controlled
source! </P>
<P>When an error occurs in the Parity or Stop Bit we should assume that the
rest of the byte could have errors as well. We could ignore the error and
process the received byte, but it could have unexpected results. Instead the
keyboard has a resend command. If we issue a resend (FE) to the keyboard, the
keyboard should send the byte back again. This is what occurs here. </P>
<P>You may notice that we branch to the error routine which transmits a resend
command straight away, without waiting for the corrupt transmission to finish.
This is not a problem, as the keyboard considers any transmission to be
successful, if the 10th bit is sent, i.e. the parity bit. If we interrupt the
transmission before the parity bit is sent, the keyboard will place the
current byte in it's buffer for later transmission. </P>
<P>Reading a byte doesn't really require bi-directional data and clock lines.
If you can process the byte fast enough then no handshaking (RTS) is required.
This means you no longer need to fiddle with the Data Direction Register. I
have successfully done this with the HC705, outputting only scan codes on a
parallel bus. But as you can imagine, you must be quick in order to catch the
next transmission. </P><B><FONT size=+2>Writing Bytes to the
Keyboard.</FONT></B>
<HR>
<P>The following routine given here is a generic one which can be used for
your own purposes. During normal execution of this program the KBD clock line
should be low, to prevent data being sent when the MCU isn't ready for it.
However in this example, we take low the KBD clock line and wait for the 64uS
which is pointless as the line is already low and has been like this for quite
some time, since the end of the last transmission or reception. </P></FONT><PRE> transmit ldx #$08 ;8 Data Bits
bset clk,DDRA ;Set Clock Low
lda #$13 ;Delay 64uS
jsr delay
clra ;Clear Parity Register
bset data,DDRA ;Set Data Low
bclr clk,DDRA ;Release Clock Line
jsr highlow
</PRE><FONT face=ARIAL>
<P>The program then initiates the Host to Keyboard transmission by taking the
KBD data line low and releasing the KBD clock line. We must then wait for a
high to low transition on the KBD clock, before we load the first bit on the
KBD data line. </P></FONT><PRE> loop ror byte
bcs mark
space bset data,DDRA ; Clear Bit
jmp next
mark bclr data,DDRA ; Clear Bit
inca ; Parity Calculation
next jsr highlow ; Wait for high to low transition
decx
bne loop
</PRE><FONT face=ARIAL>
<P>The loading of the individual bits on the KBD data line is done in very
similar fashion to the read cycle. The X register is used to keep track of the
number of bits sent. Also simular to the read cycle, we increment the
accumulator so we can calculate the parity bit later on. </P></FONT><PRE> and #$01
bne clr_par
set_par bclr data,DDRA
jmp tr_ackn
clr_par bset data,DDRA
tr_ackn jsr highlow
</PRE><FONT face=ARIAL>
<P>After the data bits have been sent, it is now time to send the parity bit.
Unlike the read cycle, we can't ignore the parity bit. If we do the keyboard
will issue a resend (FE) command if the parity bit is incorrect, a 50%
probability! </P></FONT><PRE> bclr data,DDRA ;Release Data Line
jsr highlow
brset data,PORTA,error ;Check for Ack
brclr clk,PORTA,* ;Wait for idle line
bset clk,DDRA ;Prevent Keyboard from sending data
;(Clear to Send)
rts
</PRE><FONT face=ARIAL>
<P>Once the Parity bit has been set and the falling edge of the KBD clock
detected, we must release the KBD data line, and wait for another falling edge
of the KBD clock to see if the Keyboard has acknowledged the byte. The
keyboard does this by pulling the KBD data line low. If it is not low, then
the program branches to an error handler. If all has been successful, the MCU
pulls down the KBD clock, to prevent it from transmitting. </P></FONT><PRE> error lda #$FF ;Reset
sta byte
jsr transmit
rts
</PRE><FONT face=ARIAL>
<P>We have taken a harsher approach to handing any transmit errors. Ideally we
should wait for the keyboard to send a resend command and then retransmit the
byte. However what we have done is to issue a reset to the keyboard. So far
I've never had an error, however if this starts to become a problem, then a
better error handler could be written. </P><BR><B><FONT size=+2>Download
Source Code</FONT></B>
<HR>
<UL><BR>
<LI><A href="http://www.beyondlogic.org/keyboard/keybrd05.zip">Download
Keybrd05.zip </A>- Source code for 68HC705J1A (20,604 Bytes)<BR><BR>
<LI><A href="http://www.beyondlogic.org/keyboard/keylst.htm">View .Lst
(List) File</A> <BR></LI></UL><BR><FONT size=+2><B>Links to other
information.</B></FONT> <BR>
<HR>
<UL><BR>
<TABLE>
<TBODY>
<TR>
<TD vAlign=top><FONT face=ARIAL>
<LI><A href="http://www.ezl.com/~rsch/projects.htm">Two Line
Mini-Terminal</A> </FONT></LI></TD>
<TD><FONT face=ARIAL>Roger Schaefer has developed a Mini RS-232
Terminal using the 68HC11. As an input device the terminal uses a
<B>standard IBM compatible PC keyboard.</B> In a normal full duplex
mode the controller converts the keyboard scan codes to ASCII and
transmits them to the RS-232 output. Input from the RS-232 is
displayed on the LCD. <BR><BR></FONT></TD></TR></TBODY></TABLE></UL></UL>
<HR>
<CENTER>
<TABLE width="90%" border=0>
<TBODY>
<TR>
<TD width="20%" bgColor=blue height=25><FONT face=ARIAL color=white><B>
<CENTER><A id=TITLEBLOCK
href="http://www.beyondlogic.org/index.html#PARALLEL">Parallel
Ports</A></CENTER></B></FONT></TD>
<TD width="20%" bgColor=blue height=25><FONT face=ARIAL color=white><B>
<CENTER><A id=TITLEBLOCK
href="http://www.beyondlogic.org/index.html#SERIAL">Serial / RS-232
Ports</A></CENTER></B></FONT></TD>
<TD width="20%" bgColor=blue height=25><FONT face=ARIAL color=white><B>
<CENTER><A id=TITLEBLOCK
href="http://www.beyondlogic.org/index.html#INTERRUPTS">Interrupts</A></CENTER></B></FONT></TD>
<TD width="20%" bgColor=blue height=25><FONT face=ARIAL color=white><B>
<CENTER><A id=TITLEBLOCK
href="http://www.beyondlogic.org/index.html#ATKEYBOARDS">AT Keyboard
Ports</A></CENTER></B></FONT></TD>
<TD width="20%" bgColor=blue height=25><FONT face=ARIAL color=white><B>
<CENTER><A id=TITLEBLOCK
href="http://www.beyondlogic.org/index.html#USB">USB</A></CENTER></B></FONT></TD></TR></TBODY></TABLE>
<HR>
<FONT size=2>Copyright 1999-2000 <A
href="mailto:cpeacock@senet.com.au(Craig%20Peacock)">Craig Peacock </A>- Monday
28th February 2000.
<HR>
</CENTER></FONT></FONT></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -