PRÁCTICA nº
10: Conexión de un teclado.
Teclado estático: formado por dos decodificadores decimales.
Al unir los dos decodificadores con unas puertas OR y añadirles un buffer tres
estados obtenemos un dispositivo capacitado para ser conectado al puerto B y
que no tendrá problemas de choque de buses al ser controlado por un pin
específico del PIC, habilitar del teclado sin cortocircuitarse con el bus de
una LCD conectada al puerto B, por ejemplo.

Buffer tres estados,
74 HC 245. El terminal RA3 controlará la salida de datos al bus de datos que
también es usado por la LCD.

Poniendo RA3 a cero
los datos saldrán hacia el puerto B del PIC.
Hemos construido un
teclado hexadecimal ( 0 a Fh).
Hemos necesitado
cuatro integrados CMOS, unas cuantas resistencias y pulsadores sueltos; si
queremos disminuir el número de integrados, de conexiones de pulsadores y de
componentes, etc, hay un integrado llamado 74C922 que nos facilita las
conexiones. También podemos usar un teclado ya encapsulado.

El teclado encapsulado
usado tiene las siguientes conexiones y dibujado los números así:

Si observamos los
números de las teclas en el dibujo del integrado y los números del teclado,
vemos que no coinciden, por lo tanto en el software habrá que hacer
corresponder los números de las teclas del 74C922 con las del teclado.
Vamos haber que transformaciones
hay que hacer para poder ver en la pantalla LCD la tecla que pulses.

Las teclas pulsadas en
el 74c922 son las siguientes:

Por los terminales
RB0,RB1, RB2 y RB3 entrarán esas combinaciones pero por RB4,RB5,RB6 y RB7
entrará cualquier combinación que neutralizaremos haciendo una operación AND
con 0Fh. Ahora tendremos las siguientes combinaciones:

Usaremos la
instrucción RETLW para hacer una correspondencia entre esas combinaciones y las
necesarias para ser visualizadas en la pantalla LCD y correspondan a las
dibujadas en el teclado encapsulado. Las combinaciones de correspondencia son:

En ASCII el 30h es nuestro 0 decimal, el 39h es el 9, 3ch es
< y 3eh es >.
En la práctica anterior
visualizamos un mensaje:

Tecla pulsada
P I C 1 6 F 8
4 A , v . 0
En la posición de memoria 0Fh de la LCD visualizaremos la
tecla pulsada.

;------------------------------------------------------------------------------
;PROGRAMA COMPROBADO:
;Manejo de un teclado
(74C922) y una LCD.
;Escribir un mensaje y
ver la tecla que pulso en el teclado.
;------------------------------------------------------------------------------
;PIC
16F84A/ 4 MHz/
;Bits de configuración
para el programador:
;CP(protección de la
memoria de código):..............................No
;PWRTE(activación del
temporizador "Power-up"):..............No
;WDTE(activación del
"perro guardián"):...............................No
;FOSC1-FOSC0(tipo de
oscilador):........................................Xtal
;------------------------------------------------------------------------------
;PROGRAMA
LIST p=16f84A
INCLUDE "p16f84A.inc"
ORG 00h
goto inicio
ORG 10h
inicio
;Configurar los
puertos A y B.
call pa3saluno; desactivo el teclado, RA3=1
call pabconfig
;Configuración inicial
de la LCD.
call
lconfigI
;Configuración de
trabajo de la LCD.
call lconfigW
programa
call lcdPIC
progra
call pa3cero; activo el teclado con RA3=0 y hago PB
entradas
call binasc; convierto el código binario en ASCII
movwf 40h; cargo
40h con W
call vertecla; veo la tecla pulsada
call pa3saluno; desactivo el teclado, RA3=1
goto progra
;--------------------------------------
;Leer el Puerto B:
RB0,RB1,RB2 y RB3.
;y transformarlo en
ASCII.
; 0-31, 1-32, 2-33
; 4-34, 5-35, 6-36
; 8-37, 9-38, A-39
; C-3c, D-30, E-3e
; En las combinaciones
3,7,B y F
; pondré el símbolo
ffh.
;--------------------------------------
binasc
movf PORTB,0; leo
el puerto PB y lo llevo a W
andlw 0fh; pongo
a cero los bits altos y lo dejo en el W
addwf PCL,1; sumo
al contador de programa bajo lo que tenía
; el acumulador
retlw 31h; regreso
de subrutina con el W cargado con ASCII.
retlw 32h
retlw 33h
retlw 0ffh
retlw 34h
retlw 35h
retlw 36h
retlw 0ffh
retlw 37h
retlw 38h
retlw 39h
retlw 0ffh
retlw 3ch
retlw 30h
retlw 3eh
retlw 0ffh
;-----------------------------------
;Subrutina de ver la
tecla pulsada.
;-----------------------------------
vertecla
call pabconfig; subrutina de configurar Puerto A y B para
la LCD.
movlw 0fh; dirección
de visión de la tecla pulsada
call wdir; carga
dirección 0fh en la pantalla
movf 40h,0; cargo el dato en ASCII presente en
40h en W
call wdato; escribir
el símbolo en la pantalla (dirección 0fh)
call pabI0O; subrutina
de hacer los pines entradas excepto
;RA0=
E (habilitación de la pantalla)= 0, des-
;habilitada.
return
;----------------------------------------
;Subrutina para poner
un texto.
;---------------------------------------
;P I C
_ 1
6 F 8 4 A
, _ v . 0 0
lcdPIC
call
pabconfig; subrutina de configurar Puerto A y B para
la LCD.
call lclear; borrar
pantalla
call lhome; dirección
00h de la pantalla
movlw 00h; dirección
de comienzo del mensaje en la 1ª línea
call wdir; carga
dirección 00h en la pantalla
movlw 50h; P carga 50h = P (ASCII)
call wdato; escribir
el símbolo P en la pantalla (dirección 00h)
movlw 49h; I
call wdato
movlw 43h; C
call wdato
movlw 20h
call wdato
movlw 31h; 1
call wdato
movlw 36h; 6
call wdato
movlw 46h; F
call wdato
movlw 38h; 8
call wdato
movlw 34h; 4
call wdato
movlw 41h; A
call wdato
movlw 2ch; ,
call wdato
movlw 20h
call wdato
movlw 76h; v
call wdato
movlw 2eh; .
call wdato
movlw 30h; 0
call wdato
movlw 30h; 0
call wdato
call pabI0O; subrutina
de hacer los pines entradas excepto
; RA0= E (habilitación de la pantalla)=
0, des-
; habilitada.
return
;-------------------------------------------
;-------------------------------------------
;Subrutinas de la
pantalla LCD.
;-------------------------------------------
;--------------------------------------
;Subrutina de
configuración
;del puerto A y B.
;-------------------------------------
pabconfig
call pacontrol
call pbbusO
return
;---------------------------------------------
;Subrutina de
configuración inicial
;de la pantalla lCD.
;---------------------------------------------
lconfigI
call mseg20
call l8xx
call mseg6
call l8xx
call useg150
call l8xx
call l817
call ldisplay0xx
call lclear
call lmode10
return
;-------------------------------------------
;Subrutina de
configuración de la
;LCD para comenzar a
trabajar.
;-------------------------------------------
lconfigW
call ldisplay10x
call lcursorder
return
;-----------------------------------------------------
;Puerto A 3,4=
entradas, 0,1 y 2 = salidas
;y las pongo a cero.
;-----------------------------------------------------
pacontrol
call banco1
bcf TRISA,0
bcf TRISA,1
bcf TRISA,2
call banco0
bcf PORTA,0
bcf PORTA,1
bcf PORTA,2
return
;---------------------------
;PA3 como salida y a
uno:
;inhabilito teclado
;---------------------------
pa3saluno
call banco1
bcf TRISA,3
call banco0
bsf PORTA,3
return
;--------------------------------
;PA3 a cero: activo
teclado
;y PB entrada.
;--------------------------------
pa3cero
call banco1
movlw 0ffh
movwf TRISB
call banco0
bcf PORTA,3
return
;------------------------------
;Puerto B= salidas
;y las pongo a cero.
;------------------------------
pbbusO
call banco1
movlw 00h
movwf TRISB
call banco0
movlw 00h
movwf PORTB
return
;----------------------------------------------------
;Puerto B y RA2,1 =
entradas y
;la RA0 se queda como
salida a cero para
;inhabilitar la LCD.
;---------------------------------------------------
pabI0O
call banco1
movlw 0ffh
movwf TRISB
bsf TRISA,1
bsf TRISA,2
call banco0
return
;----------------------------------------
;Pulso de habilitación
del LCD.
;----------------------------------------
;Flanco de subida
lE1
nop
bcf PORTA,0
nop
bsf PORTA,0
return
;Flanco de bajada
lE2
nop
bcf PORTA,0
nop
return
;------------------
;Escribir dato.
;------------------
lwd
bsf PORTA,2
bcf PORTA,1
call lE1
return
;---------------------------
;Escribir instrucción.
;--------------------------
lwi
bcf PORTA,2
bcf PORTA,1
call lE1
return
;-----------------------------
;Escribir
instrucciones.
;-----------------------------
;De 20h a puerto B.
;----------------------------
w20pb
movf 20h,0
movwf PORTB
return
;--------------------------------------------------
;Escribir instrucción
de "No operación".
;--------------------------------------------------
lnop
movlw 00h
call winst
return
winst
movwf 20h
call lwi
call w20pb
call lE2
call useg45
return
;----------------------------------------------------
;Escribir inst. de
limpiar display y
;poner a cero el
contador de direcciones.
;----------------------------------------------------
lclear
movlw 01h
call winstt
return
winstt
movwf 20h
call lwi
call w20pb
call lE2
call mseg2
return
;---------------------------------------
;Escribir inst. de
cursor a casa.
;--------------------------------------
lhome
movlw 02h
call winstt
return
;------------------------------------------
;Escribir inst. de
modo de entrada.
;------------------------------------------
;-----------------------------------------------------------------
;El cursor se mueve
incremental (I/D= 1)
;y el display no se
desplaza automáticamente (S= 0).
;-----------------------------------------------------------------
lmode10
movlw 06h
call winst
return
;------------------------------------------------
;Escribir inst. del
control del display.
;------------------------------------------------
;------------------------------------------------------
;Display
on, D= 1; Cursor off, C= 0; B= x.
;------------------------------------------------------
ldisplay10x
movlw 0ch
call winst
return
;-----------------------------------------
;Display
off, D= 0; C= x; B= x.
;-----------------------------------------
ldisplay0xx
movlw 08h
call winst
return
;----------------------------------------------------
;Desplazar display o
mover cursor (S/C) y
;especificar dirección
(R/L).
;----------------------------------------------------
;---------------------------------------------------
;Desplazar display y
no cursor (S/C=1) a
;la derecha (R/L=1).
;---------------------------------------------------
ldisplayder
movlw 1ch
call winst
return
;------------------------------------------------
;Mover cursor y no
dispaly (S/C=0) a
;la derecha (R/L=1).
;------------------------------------------------
lcursorder
movlw 14h
call winst
return
;---------------------------------------------------------------
;Función
Set.
;Configurar la
pantalla: bus de 4 o 8 bits (DL),
;1 o 2 líneas (N) y nº
de puntos (5x10 o 5x7) (F).
;---------------------------------------------------------------
l8xx
call lwi
movlw 30h
movwf 20h
call w20pb
call
lE2
call useg45
return
l817
movlw 30h
call winst
return
;--------------------------------------------------
;Subrutina para
colocar datos seguidos
;-------------------------------------------------
wdato
movwf 20h
call lwd
call w20pb
call lE2
call useg45
return
;----------------------------------------------------
;Subrutina para
colocar datos en cualquier
;posición de la
pantalla: DDRAM address.
;----------------------------------------------------
wdir
addlw 80h
movwf 20h
call lwi
call w20pb
call lE2
call useg45
return
;------------------------------
;Retardos para la LCD.
;------------------------------
;---------------------------
;Retardo de 2 mseg.
;--------------------------
mseg2
call banco0
movlw 0ffh
movwf 30h
movlw 03h
movwf 31h
salto5s
decfsz 30h,1
goto salto5s
decfsz 31h,1
goto salto5s
return
;--------------------------
;Retardo de 6 mseg.
;--------------------------
mseg6
call banco0
movlw 0ffh
movwf 30h
movlw 08h
movwf 31h
salto41s
decfsz 30h,1
goto salto41s
decfsz 31h,1
goto salto41s
return
;---------------------------
;Retardo de 20 mseg.
;---------------------------
mseg20
call banco0
movlw 0ffh
movwf 30h
movlw 1ah
movwf 31h
salto4s
decfsz 30h,1
goto salto4s
decfsz 31h,1
goto salto4s
return
;---------------------------
;Retardo de 45 useg.
;---------------------------
useg45
call banco0
movlw 0fh
movwf 30h
salto6s
decfsz 30h,1
goto salto6s
return
;------------------------------
;Retardo de 150 useg.
;------------------------------
useg150
call banco0
movlw 32h
movwf 30h
salto61s
decfsz 30h,1
goto salto61s
return
;--------------------
;Retardo de 1 seg.
;--------------------
sg1
call banco0
movlw 0c2h
movwf 10h
movwf 11h
movlw 04h
movwf 12h
sal1
decfsz 10h,1
goto sal1
goto recarga1
sal2
decfsz 11h,1
goto sal1
goto recarga2
sal3
decfsz 12h,1
goto sal1
return
recarga1
movlw 0c2h
movwf 10h
goto sal2
recarga2
movlw 0c2h
movwf 11h
goto sal3
;------------------
;Retardo de 5 seg.
;------------------
sg5
call sg1
call sg1
call sg1
call sg1
call sg1
return
;------------------------------------------
;Subrutinas de cambios
de bancos.
;------------------------------------------
banco0
bcf STATUS,RP0
return
banco1
bsf STATUS,RP0
return
END