isso pra mim é Assembly (8051):
Quote:
NAME teclado
USING 0
readKeyboard SEGMENT CODE
RSEG readKeyboard
scankey:
mov DPTR, #gkswitch
mov A, state
rl A
jmp @A+DPTR
gkswitch:
sjmp gkcase0
sjmp gkcase1
sjmp gkcase2
sjmp gkcase3
gkcase0:
; estado 1
lcall haskey
jnc fim_estado1 ;se houver alteração no porto, então há tecla pressionada
mov state, #01h ;retorna o proximo estado
fim_estado1:
ret ; senão retorna
gkcase1:
; estado 2
mov port, #0f0h
mov R7, port ; byte lido das linhas
mov port, #0fh ; colocar porto de entrada a 0 e de saida a 1, para ler colunas
mov R6, port ; byte lido porto, referente às colunas
lcall decValidKey ;descodificar e validar tecla, retorna true ou false em CY
jc teclatrue
mov R7, #INVALID_KEY
mov state, #0h ; não há tecla válida, volta para o estado 1
ret ; não há tecla válida, sai da rotina. não há bloqueio de estado
teclatrue:
mov state, #02h ;retorna o proximo estado
ret
gkcase2:
; estado3
lcall haskey
jc fim_estado3 ; se Cy for true, mantém o estado
mov state, #03h ; retorna proximo estado
fim_estado3:
ret
gkcase3:
; estado 4
lcall haskey
jc l1_estado4 ; se há tecla...
mov state, #0 ;senão,retorna o estado 1
ret
l1_estado4:
mov state, #02h ; ...volta para o estado 3
ret
; ############# ACÇÕES ############
haskey:
clr C
mov port, #0f0h ;colocar porto de saída a 0 e de entrada a 1
mov A, port
anl A, #0f0h
cjne A, #0f0h, truekey
ret
truekey: ; retorna no acumulador o byte lido do porto, relativo ao porto de entrada
setb C
ret
;#############################################
decValidKey: ;retorna true ou false em Cy
lcall leTecla
lcall teclaToCaracter
cjne R7, #nil, validkey ;Verificar se a tecla lida é válida
clr C
ret
validkey:
setb C
ret
;##############################################
leTecla:
;R7= byte lido referente às linhas, R6=byte lido referente às colunas, retorna tecla em R4
;caso a tecla tenha sido libertada
cjne R7, #0f0h, validarcol
validarcol:
cjne R6, #0fh, desctecla
;teclaperdida:
mov R4, #INVALID_KEY ;retornar tecla invalida
ret
desctecla:
mov R4, #0
mov A, R6
swap A
clr C
L1:
rlc A
jnc fim_col
inc R4
sjmp L1
fim_col:
mov A, R7
swap A
clr C
L2:
rrc A
jnc fim_linha
push ACC
mov A, R4
add A, #4
mov R4, A
pop ACC
sjmp L2
fim_linha:
ret
;####################################
teclaToCaracter:
cjne R4, #INVALID_KEY, valid_ttc
mov A, #INVALID_KEY ; acumulador fica com tecla invalida
sjmp fim_ttc
valid_ttc: ; se tecla é válida, ver se o caracter é algarismo ou letra
clr C
mov A, R4
subb A, #0ah
jc algarismo_ttc
mov A, R4 ; se não há borrow, trata-se de uma letra
add A, #037h ; acumulador fica com o código ascii da tecla
sjmp fim_ttc
algarismo_ttc:
mov A, R4
add A, #030h ; acumulador fica com o código ascii da tecla
fim_ttc:
mov R7, A ; retorna em R7 o código ascii
ret
EXTRN IDATA(pointersF, pointersC, elements), DATA(tempkey, state, INVALID_KEY, nil, port)
EXTRN BIT(hastempkey)
PUBLIC scankey
END
Isso é o device driver de um teclado matricial 4x4, com contactos mecânicos e bouncing de 10ms.
Era uma pequena parte do meu projecto final de Arquitectura de Computadores, que consistia em projectar um sistema de gestão de fila de espera, tipo o que se vê na loja do cidadão.
Tinha de fazer a gestão de memória, implementar relógio e calendário, calcular tempo médio de atendimento e hora prevista de atendimento, controlar um dislay externo que mostrava alternadamente a última senha chamada e o tempo médio de atendimento, tinha uma modo de utilizador e modo de supervisor com palavra passe e sistema de segurança, contemplar casos de desistência, enfim, tudo o que pode ser inerente a um sistema desses...
Fiz o trabalho todo em cerca de hora e meia, enquanto ia do ISEL pra casa...
o resto foi implementação e debugging... bons tempos de fritanço :>