| ??? 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 |
| Topic | Author | Date |
| 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 |



