Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
???
04/17/03 22:20
Read: times


 
#43667 - AT keyboard again
HI all,
I know that this has been discussed many times, but none of the previous seams to awnser my problem.
I've already wrote the routines to check for keypresses and send data to the keyboard, I can reset it and read the 0xAF ack back, set typematic and etc... But after I do this I keep getting 0s from the keyboard like forever...!
I didnt use Ints for my routines, there is a check_keyb routine that check for keypresses, and all other times the keyb is disabled (clock line low).
Here is my asm source, please help me!
Thanks, Gabriel Ortiz Lour

If this is bad you can get it here:
-> www.gsoftcreations.kit.net/kb.asm
--------------- kb.asm ---------------
.equ stack, 0x50
.equ DelayX_Val, 0x20 ; Val of DelayX

; LCD Vars
.equ LcdStat, 0x21 ; Controls BackLight & Cmd/Dat of LCD

; Keyboard vars
.equ KB_OK, 0x45
.equ KB_DATA, 0x46

;------------------
; Defines
;------------------
;XXXXXXXXXXXXXXXXXXXXXXXX LCD XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
.equ _LCD, P1 ; LCD conected to P1
.equ _LCD_RS, 0x10 ; Val of pin P1.4 (Cmd / Data)
.equ _LCD_RW, 0x20 ; Val of pin P1.5 (Read / Write)
.equ _LCD_BL, 0x80 ; Val of pin P1.7 (Back Light)
.flag _LCD_EN, P1.6 ; Enable Pin
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
;XXXXXXXXXXXXXXXXXXXXXXXX KeyBoard XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
.flag KEYB_DATA, P1.5 ; AT Keyboard data
.flag KEYB_CLOCK, P3.2 ; AT Keyboard Clock
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

;********************************************************
; Initial Jumps
;********************************************************
.org 0x00 ;locate routine at 00H
ljmp Start ;jump to START

.org 0x03 ;external interrupt 0
reti
.org 0x0B ;timer 0 interrupt
reti
.org 0x13 ;external interrupt 1
reti
.org 0x1B ;timer 1 interrupt
reti
.org 0x23 ;serial port interrupt
reti

;**************************************************************************
.org 0x2B ;locate of the program beginning
;**************************************************************************

; *************************
; DelayMS = 100.368921 us
; Destroy: r7.
; *************************
DelayMS:
mov r7, #91
MSLoop:
djnz r7, MSLoop
ret

;*******************************
; DelayHS: Delays DelayX_Val * 100us.
; Destroy: r6.
;*******************************
DelayX:
mov r6, DelayX_Val
DXLoop:
acall DelayMS
djnz r6, DXLoop
ret

;*******************************
; DelayHS: Half Second Delay.
; Destroy: r5, r6 & r7.
;*******************************
DelayHS:
mov r5, #19 ; 19 * 256 * 100us =~ 0.5 s
mov r6, #0x00
HSLoop:
acall DelayMS
djnz r6, HSLoop
djnz r5, HSLoop
ret

get_dptr:
movx a, @dptr
inc dptr
ret

;---------------------
; Keyboard Routines:
;---------------------
;*************************************
; InitKeyb: c=1 if ACK OK
;*************************************
CheckACK:
mov a, KB_DATA
cjne a, #0xFA, CheckACK2
setb c
ret
CheckACK2:
clr c
ret
;*************************************
; InitKeyb:
;*************************************
InitKeyb:
mov KB_OK, #0
mov r1, #0xFF
acall Write_Keyb
acall Check_Keyb
acall CheckACK
jnc InitKeyb

mov r1, #0xF4 ; Enable
acall Write_Keyb
acall Check_Keyb
acall CheckACK
jnc KeybErr

mov r1, #0xF3 ; Set Typematic
acall Write_Keyb
acall Check_Keyb
acall CheckACK
jnc KeybErr
mov r1, #0x00 ; Typematic = 250 ms / 30 cps
acall Write_Keyb
acall Check_Keyb
acall CheckACK
jnc KeybErr

mov KB_OK, #1
KeybErr:
ret

;*************************************
; Zero2One:
;*************************************
Zero2One:
jnb KEYB_CLOCK, *
jb KEYB_CLOCK, *
ret

;*************************************
; Check_Keyb:
;*************************************
Check_Keyb:
setb KEYB_CLOCK ; CLOCK & DATA high = Idle Pos
mov r0, #50
CheckAgain:
jnb KEYB_CLOCK, KeyHit
djnz r0, CheckAgain ; check r0 times
sjmp KeyEnd
KeyHit:
jnb KEYB_DATA, KeyHit2 ; Start bit must be 0
KeyEnd:
clr KEYB_CLOCK ; disable keyb
clr c ; c=0 = no keypress
ret
KeyHit2:
mov r0, #8 ; 8 bits
mov r1, #0 ; r1 = return key
KeyHit3:
acall Zero2One
mov a, r1
mov c, KEYB_DATA
rrc a
mov r1, a
djnz r0, KeyHit3

acall Zero2One ; Parity bit
clr a
mov c, KEYB_DATA
rlc a
acall Zero2One ; Stop bit
mov c, KEYB_DATA
rlc a ; acc.0 = stop, acc.1 = parity

clr KEYB_CLOCK
mov KB_DATA, r1
setb c
ret

;*************************************
; Write_Keyb: Send r1 to the kb
;*************************************
Write_Keyb:
mov r0, #8 ; 8 bits to receive
clr KEYB_CLOCK ; break the Keyboard
acall DelayMS ; (safety reasons)
clr KEYB_DATA ; request to send
setb KEYB_CLOCK ; enable the Keyboard
acall Zero2One ; Start Bit
mov a, r1 ; Data Bits
TxData:
rrc a
mov KEYB_DATA, c
acall Zero2One
djnz r0, TxData

mov a, r1 ; calculate parity bit
mov c, psw.0 ; this is Even parity
cpl c ; and Keyboard needs Odd parity
mov KEYB_DATA, c ; send parity bit
acall Zero2One

setb KEYB_DATA ; send stop bit
acall Zero2One

acall Zero2One
mov c, KEYB_DATA ; ACK bit
clr KEYB_CLOCK ; stop the keyboard
ret

;-----------------------
; LCD Routines:
;-----------------------
;********************************************************************
; Envia o ACC para o LCD
;********************************************************************
LcdCmd2: anl a, #0x0F ; Zera nibble superior
orl a, LcdStat ; Status da Back Light e Cmd/DAT
mov _LCD, a ; P1 = data[0..3] + controle[4..6]
;
setb _LCD_EN ; Liga o Enable do LCD
nop ; Espera um pouco
clr _LCD_EN ; Desliga o pino de Enable do LCD
;
acall DelayX ;
;
ret ; Retorna


;********************************************************************
; Envia Comandos ou Dados no ACC para o LCD nibble por nibble
; Para enviar dados faz um AND do LcdStat com _LCD_RS
; Destroy: DelayX_Val & r5 (r6 & r7 [DelayX])
;********************************************************************
LcdCmd: mov DelayX_Val, #15 ; 1.5 ms DelayX
mov R5, A ; R5 = Backup do A
swap A ; Troca os nibbles do A
acall LcdCmd2 ; envia o nibble mais sig.
mov A, R5 ; Backup do A de volta
acall LcdCmd2 ; envia o nibble menos sig.
;
ret ; Retorna

;********************************************************************
; Inicializa o LCD para 4 bits de dados, 2 linhas e 16 colunas
;********************************************************************
LcdInit:
mov A, #03h ; Envia 0x03 3 vezes
acall LcdCmd2 ;
acall LcdCmd2 ;
acall LcdCmd2 ;
;
mov A, #02h ; Envia 0x02
acall LcdCmd2 ;
;
mov A, #28h ; Envia 0x28 nibble por nibble
acall LcdCmd ;
mov A, #06h ; Envia 0x06 nibble por nibble
acall LcdCmd ;
mov A, #01h ; Envia 0x01 nibble por nibble
acall LcdCmd ;
mov A, #0Fh ; Envia 0x0F nibble por nibble
acall LcdCmd ;
;
mov a, #0x0C ; Desliga o cursor
acall LcdCmd
ret ; Retorna

;********************************************************************
; Envia a strz apontada pelo DPTR para o LCD
;********************************************************************
LcdPrint: orl LcdStat, #_LCD_RS; Enviando caracteres
;
LcdPLoop: clr a ; Zera o index
movc a, @a+dptr ; Pega o BYTE da vez
jz LcdFim ; Se BYTE = 0 retorna
acall LcdCmd ; Envia o comandos/caractere
inc dptr ; Aponta para o proximo BYTE
ajmp LcdPLoop ; Proximo BYTE
;
LcdFim: xrl LcdStat, #_LCD_RS; De volta aos comandos
ret ; Retorna


;********************************************************************************************
; DispNum mostra o valor do ACC no LCD
;
; LcdStat tem que jah ta com o orl _LCD_RS
;********************************************************************************************
DispNum:
mov b, #100
div ab
jz DispNoCent
add a, #48 ; to ASCII
acall LcdCmd
DispNoCent:
mov a, b
mov b, #10
div ab
add a, #48 ; to ASCII
acall LcdCmd
mov a, b
add a, #48 ; to ASCII
acall LcdCmd
ret

;**********************************
; Init: Initalizes all devices
;**********************************
Init:
clr KEYB_CLOCK ; Clock line in kb inhibit pos
setb KEYB_DATA ; Data line in idle pos

mov PSW, #0x00
mov TCON, #0x00
mov SCON, #0x00

mov LcdStat, #0x00

mov DelayX_Val, #200 ; 20 ms delay for the RC reset
acall DelayX ;

acall LcdInit
acall InitKeyb

ret

;*************************************************************************
;==========================--------------------------
; Main Routine:
;==========================--------------------------
;*************************************************************************
Start:
mov SP, #stack
acall Init

mov a, KB_OK
jz KBNotOK

Inicio:
mov a, #0x01
acall LcdCmd ; Clear Lcd
mov dptr, #msg010 ; G Soft Creations on line 1
acall LcdPrint

mov a, #0xC0
acall LcdCmd
mov r4, #5
Loop:
acall Check_Keyb ; Check for keypress
jnc Loop ; if c=0 no key
mov a, KB_DATA
orl LcdStat, #_LCD_RS
acall DispNum ; display key
mov a, #' '
acall LcdCmd
xrl LcdStat, #_LCD_RS

djnz r4, Loop ; display 5 keys at time
mov a, #0xC0
acall LcdCmd
mov r4, #5
ajmp Loop

;---------------------
; Error on KB
;---------------------
KBNotOK:
mov a, #0x01
acall LcdCmd ; Clear Lcd
mov dptr, #msgERR ; KB Error Msg
acall LcdPrint
SSSTOP:
ajmp SSSTOP ; Infinite Loop


msg010: .db "G Soft Creations", 0
msgERR: .db "Erro no KB - FIM", 0


List of 4 messages in thread
TopicAuthorDate
AT keyboard again            01/01/70 00:00      
   Got it to work            01/01/70 00:00      
      RE: Got it to work            01/01/70 00:00      
         RE: Got it to work            01/01/70 00:00      

Back to Subject List