Tutoriales

Curso Básico AVR AT90S1200 - Página 3


Programa para uso de teclado de matriz de 4x4
 
Ahora les va un programa que lee la presión de una tecla en un teclado 4x4.

Les pongo un poco de teoría respecto al teclado y cómo está conectado.

Una buena manera de ahorrar líneas de entrada al micro es, en lugar de dedicar una línea exclusiva por cada tecla utilizada, emplear un teclado matricial. El teclado matricial se caracteriza por estar cada una de las teclas conectada a dos líneas (una columna y una fila) que la identifican. De este modo el número de teclas que pueden conectarse es el producto de filas por el de columnas.



La técnica de programación requiere tanto de entradas como de salidas. Las filas están conectadas a las patillas de salida y las columnas a las de entrada.

Se comienza el testeo colocando a ‘0’ la primera fila, y a ‘1’ las restantes. Si la tecla pulsada estuviese en la columna ‘0’, ésta colocaría en su línea un ‘0’ lógico. Bastará con hacer un muestreo de las columnas, buscando el 0, para saber la tecla exacta que fue pulsada en la matriz.

Si no es pulsada ninguna tecla en una fila, las entradas se encuentran en estado flotante, razón por la que son necesarias las resistencias de polarización internas, que mantienen las entradas a nivel alto.

En nuestro caso, yo conecté las resistencias a tierra. Por lo tanto, lo que se busca es un UNO en las líneas de entrada.

Las instrucciones nuevas que este programa tiene son:

sbic pinb,5
Brinca la siguiente instrucción si el bit 5 del puerto B está en CERO.
SI fuera sbis, brinca la sig. inst. si el bit 5 del port b está en UNO.

Es importante decirles que los AVR at90s1200 tienen sólo 3 saltos a subrutina. Este programa que escribí no tiene ni un sólo salto a subrutina, así que si lo van a implementar en otro programa en dónde hagan uso de un teclado pues sólo llamarían a la lectura del teclado y gastarían un nivel de pila.

El programa es:

---------------------
;programa teclado 4x4 rapid switch
;pb0, pb1, pb2, pb3 Salidas matriz
;pb4, pb5, pb6, pb7 Entradas matriz
;pd0, pd1, pd2, pd3 Salidas LEDS
;pd4 salida estado tecla presionada (E)
 
 
; pb4 pb5 pb6 pb7
; | | | |
;pb0 -> 0 1 2 3
;pb1 -> 4 5 6 7
;pb2 -> 8 9 a b
;pb3 -> c d e f
 
 
.include "1200def.inc"
 
SER R16 ;FF
OUT DDRD,R16 ;PtoD Salida
LDI R16,$0F ;00001111
OUT DDRB,R16 ;PtoB 4sal 4ent
 
clr r16
 
out PORTD,r16 ;borra PtoD
OUT PORTB,r16 ;borra PtoB
 
inicio: clr r16
clr r17 ;Registro mandado a ptoD
clr r18 ;registro del contador de barrido
clr r19 ;indicador de línea actual de barrido
linea1: ldi r16,$01
out portb,r16 ;rb0=1 línea 1 activa
rjmp barrido ;va a checar presión de tecla
linea2: inc r19
inc r18 ;en subrutina barrido, la primer línea
;no hace incremento, por eso se
;incrementa aquí
ldi r16,$02
out portb,r16 ;rb1=1 línea 2 activa
rjmp barrido
linea3: inc r19 ;incrementa indicador de línea
inc r18
ldi r16,$04
out portb,r16 ;rb2=1 línea 3 activa
rjmp barrido
linea4: inc r19 ;incrementa indicador de línea
inc r18
ldi r16,$08
out portb,r16 ;rb3=1 línea 4 activa
rjmp barrido
nopresion: clr r16 ;pon E y LEDS a cero
out portd,r16 ;no hubo presión
rjmp inicio
 
barrido: sbic pinb,4 ;si rb4=0 no hay presión
rjmp presion
inc r18 ;siguiente tecla
sbic pinb,5
rjmp presion
inc r18 ;siguiente tecla
sbic pinb,6
rjmp presion
inc r18 ;siguiente tecla
sbic pinb,7
rjmp presion
rjmp quelinea ;no hubo presión en X línea
 
presion: mov r17,r18 ;r17=r18
out portd,r17 ;saca tecla y E por portd
sbi portd,4 ;pd4=1 es decir E=1
rjmp inicio ;que ya no haga barrido
 
quelinea: cpi r19,$00 ;determina en que línea de barrido va
breq linea2 ;va a línea 2
cpi r19,$01
breq linea3
cpi r19,$02
breq linea4
cpi r19,$03
breq nopresion ;se va a limpiar ptod

-----------------------------



Al final lo que hace el programa es determinar si se presionó una tecla. Si se presionó, enciende la salida E (pd4) y saca la tecla por pd0, pd1, pd2, pd3. Si se presionara el CERO sólo encendería E y pd0, pd1, pd2, pd3 estarían apagadas. Si se presionara la tecla F encendería E y todas las demás: 1111 = 15 = F.

Declaración de variables

No uso la declaración de variables para los registros del AVR, pero les explico unas directivas para usarlas:

Si quieres definir pines:
.equ RxD =0; En este caso el pin 0 se llama RxD
.equ TxD =1; En este caso el pin 1 se llama TxD

Si quieres renombrar registros:
.def contbit =R16
def temporal =R17

Y se usan normalmente:
cbi PORTD,TxD; el pin 1 se pone a cero
ldi contbit,$aa; Carga el R16 con AA