Domingo 22 de Diciembre de 2024, 17:16
SoloCodigo
Bienvenido(a),
Visitante
. Por favor,
ingresa
o
regístrate
.
¿Perdiste tu
email de activación?
Inicio
Foros
Chat
Ayuda
Buscar
Ingresar
Registrarse
SoloCodigo
»
Foros
»
Programación Específica
»
Microcontroladores
»
Soluciones de Hard y Soft
(Moderador:
© Jonathan ©
) »
Teclado Matricial y Display 7 Segmentos - ATMEL AVR
« anterior
próximo »
Imprimir
Páginas: [
1
]
Autor
Tema: Teclado Matricial y Display 7 Segmentos - ATMEL AVR (Leído 30846 veces)
netshark
Nuevo Miembro
Mensajes: 21
Teclado Matricial y Display 7 Segmentos - ATMEL AVR
«
en:
Viernes 29 de Mayo de 2009, 22:40 »
0
EL TECLADO MATRICIAL
Implementado con un Micro ATMEL AVR ATMEGA 8535
Para entender un poco sobre el funcionamiento eléctrico de un teclado matricial, lean la siguiente presentación:
Acá la presentación:
EL_TECLADO_MATRICIAL_v1_4.pdf (1.6 MB)
Para la práctica se necesita un teclado matricial de 4X4, lo pueden comprar o fabricarlo.
Si tienen los recursos, pueden comprar el teclado, pero les costará alrededor de 135 pesos.
Una forma mucho más económica y didáctica es construirlo ustedes mismos.
Material:
- 16 pushbuttons pequeños
- 1 PCB tipo "Easy Circuit" que pueda alojar todos los botones
- Cable y soldadura
Debemos conectar los switches de forma que toda una fila de ellos tengan una terminal común, así las 4 filas cada una. Después cada columna debe tener la otra terminal común.
Se ve claramente en el diagrama:
Y si prefieren usar un display de 7 segmentos, el circuito es el siguiente:
El display de 7 segmentos está construido de la siguiente forma:
Además una sencilla tabla de cuales segmentos encender para cada número:
Teclado hecho en casa
Se tuvieron que cortar algunas pistas verticales con cutter para separar las columnas, y funciona a la perfección.
En este caso se usó un microcontrolador ATMEL ATMEGA8535
datasheet
pero puede bien ser implementado en un microcontrolador más pequeño, como el ATMEGA8 sin mucha dificultad, sólo habría que cambiar el acomodo de los puertos y el cableado, (
datasheet
)
Se implementó un programa para controlar el teclado matricial, y según la tecla que se presione, aparecerá:
1) LEDs encendidos en una tira de leds en función de la fila-columna
2) Código del 0 a la F en un display de 7 segmentos.
La tira de 10 leds sirve para ver qué tecla se presionó. De izquierda a derecha, los primeros dos leds no se utilizan, los siguientes 4 indican la columna y los ultimos 4 indican el renglón. Hay un led ROJO cercano al AVR (concretamente en el pin PD7) que se prende cuando detecta alguna tecla presionada y se apaga cuando termina la decodificación ó si descarta que se haya presionado (por si fue ruido o un falso contacto)
Ejemplo al presionar la tecla en la ultima fila de la ultima columna...
Aparecen:
Es el programa básico con decodificación de filas y columnas y tiene protección antirrebotes. Ésta es la versión que jala con la tira de LEDs:
Código: Text
;Código decodificador de teclado matricial
;Implementado por David Valencia Pesqueira en UPIITA-IPN 2009
;Profesor: Dr. Antonio Hernández Zavala
;GRUPO 4BM3
;
; El siguiente programa decodifica un teclado matricial
; de 16 teclas. Éste tipo de algoritmo está diseñado para
; detectar sólo una tecla a la vez, ya que para detectar
; más de una se requieren diodos por cada interruptor en la
; construcción del teclado matricial y éso ya queda fuera
; del enfoque didáctico de éste programa.
;
; Para más información sobre la construcción de teclados
; matriciales con diodos visitar:
; http://www.dribin.org/dave/keyboard/one_html/
;
;Historial
;v0.1 - Pruebas de las resistencias Pull-UP --- OK
;v0.2 - Probando la salida del tempscan
;v0.3 - Nueva estructura de tempscan -- OK
;v0.4 - Salida por tira de leds en PORTA -- OK
;
;Hardware en un ATMEL ATMega 8535
;El teclado está conectado de la siguiente manera:
;
; COLUMNAS
; 0 1 2 3
;
; FILAS 0 X X X X PC4
;
; 1 X X X X PC5
;
; 2 X X X X PC6
;
; 3 X X X X PC7
;
; PC0 PC1 PC2 PC3
;
;######################################################
;CABECERA
.include "m8535def.inc"
;######################################################
;Vector de Interrupciones
.org 0x00
rjmp reset ;interrupción de Reset
;
;######################################################
;Variables Globales
;La variable tempscan se acomoda de la siguiente forma
;tempscan = [fila3,fila2,fila1,fila0,col3,col2,col1,col0]
;Son "banderas" que se prenden para indicar en qué fila
; y qué columna se halla la tecla.
.def tempscan=r17
.def temp=r16
;Rutina Principal
reset:
;inicializar pila
cli
ldi temp,low(ramend)
out spl,temp
ldi temp,high(ramend)
out sph,temp
sei
rjmp init
init:
;Inicializar Puertos
;Este código emplea el puerto C, con los bits 0 al 3 para las columnas
;y los bits 4 al 7 para las filas.
;Inicia con las filas como salidas con ceros y las columnas como entradas
;que se mantienen en un nivel alto mientras no estén conectadas
;Para lograr esto, se habilitan las "resistencias pull-up" que conectan
;el pin deseado hacia VCC.
;Para hacerlo se declaran los pines como entradas (DDRC=0) pero
;enviamos 0xFF al registro PORTC para activarlas.
;Declarando al nibble alto como salida y al bajo como entrada
ldi temp,0b11110000
out DDRC,temp
;Activando las resistencias pull-up en la parte baja
ldi temp,0x0F
out PORTC,temp
;Si se presiona una tecla, el "0" de alguna fila será
;detectado por las columnas, y entonces comienza el
;proceso de decodificación.
ldi temp,0b10000000
out DDRD,temp
;Puerto D como salida para cuando detecta tecla
ser temp
out DDRA,temp
;Nibble bajo del puerto A como salida
clr temp
out PORTA,temp
clr tempscan ;Borra el resultado del escaneo
rjmp begin
begin:
clr temp
out PORTD,temp
;Probar si algun botón fue presionado
in temp,PINC
cpi temp,0x0F ;Si hay algun cero en las columnas, buscar la tecla
brne antirrebotes
rjmp begin
antirrebotes:
;Esta rutina espera un corto periodo de tiempo mientras el interruptor
;se estabiliza para evitar que el micro detecte la misma tecla varias
;veces al igual que posible ruido.
;Vuelve a leer las entradas
ser temp
out PORTD,temp
rcall delay
in temp,PINC
cpi temp,0x0F
;Si detecta el cero de nuevo, procesa la detección
brne deteccion
;Si fue un falso contacto, vuelve a empezar
rjmp begin
;FIN DE ANTIRREBOTES
deteccion:
clr tempscan
;inicializamos el código de escaneo temporal
ldi tempscan,0x00
;Buscar las columnas
colscan:
sbis pinc,0 ;prueba la columna 0
ldi tempscan,0x01
sbis pinc,1 ;prueba la columna 1
ldi tempscan,0x02
sbis pinc,2 ;prueba la columna 2
ldi tempscan,0x04
sbis pinc,3 ;prueba la columna 3
ldi tempscan,0x08
cpi tempscan,0x00 ;si no halló la columna, repetir
breq init
;Ahora que se encontró la columna, tienen que invertirse
;los sentidos del nibble bajo y el alto para buscar la
;fila
rcall invertir
;Ahora invertidos, buscaremos si alguna fila está
;baja
in temp,PINC
cpi temp,0xF0 ;Si hay algun cero en las columnas, buscar la tecla
brne filadetectada
rjmp init ;Si no hay fila con cero, devuelve los puertos
;a su estado original y reinicia el programa
filadetectada:
;Buscar la fila
filascan:
ldi temp,0x10
sbis pinc,4 ;Prueba la fila 0
rjmp col0
sbis pinc,5 ;Prueba la fila 1
rjmp col1
sbis pinc,6 ;Prueba la fila 2
rjmp col2
sbis pinc,7 ;Prueba la fila 3
rjmp col3
rjmp init ;Si no halla la fila, reinicia
;A continuación se escribirá el valor correspondiente
;a la fila, se usa el comando ROL para multiplicar por 2
;pero se limpia antes la bandera de acarreo para evitar
;que se sume y entregue valores erróneos.
col0:
add tempscan,temp
rjmp fincol
col1:
ldi temp,0x20
add tempscan,temp
rjmp fincol
col2:
ldi temp,0x40
add tempscan,temp
rjmp fincol
col3:
ldi temp,0x80
add tempscan,temp
rjmp fincol
fincol:
;Toca procesar el código temporal para sacarlo
;por los leds, en este caso sale en 4 leds en puertoA
out PORTA,tempscan
clr tempscan
rcall desinvertir ;devolver los puertos al estado original
rjmp begin
;Subrutinas
delay:
cli
;Respaldar variables globales en la pila
push r16
push r17
;Inicia secuencia de retraso
loop0: ldi r17,0x04
loop1: ldi r16,0xFF
loop2: dec r16
brne loop2
dec r17
brne loop1
sei
;Restaurar las variables desde la pila
pop r17
pop r16
ret
invertir: ;Inversión de los pines
ldi temp,0b00001111
out DDRC,temp
;Activando las resistencias pull-up en la parte alta
ldi temp,0xF0
out PORTC,temp
;Ahora la parte alta es entrada con pullup y la parte
;baja son salidas con ceros
ret
desinvertir: ;Devolver los pines al estado inicial
ldi temp,0b11110000
out DDRC,temp
;Activando las resistencias pull-up en la parte alta
ldi temp,0x0F
out PORTC,temp
;Ahora la parte baja es entrada con pullup y la parte
;alta son salidas con ceros
ret
;FIN DEL PROGRAMA TECLADO MATRICIAL
Esta otra versión saca qué tecla fue presionada en un display de 7 segmentos:
Aquí unas fotos:
Código: Text
;Código decodificador de teclado matricial
;Implementado por David Valencia Pesqueira en UPIITA-IPN 2009
;Profesor: Dr. Antonio Hernández Zavala
;GRUPO 4BM3
;
; El siguiente programa decodifica un teclado matricial
; de 16 teclas. Éste tipo de algoritmo está diseñado para
; detectar sólo una tecla a la vez, ya que para detectar
; más de una se requieren diodos por cada interruptor en la
; construcción del teclado matricial y éso ya queda fuera
; del enfoque didáctico de éste programa.
;
; Para más información sobre la construcción de teclados
; matriciales con diodos visitar:
; http://www.dribin.org/dave/keyboard/one_html/
;
;Historial
;v0.1 - Pruebas de las resistencias Pull-UP --- OK
;v0.2 - Probando la salida del tempscan
;v0.3 - Nueva estructura de tempscan -- OK
;v0.4 - Salida por tira de leds en PORT_DISP -- OK
;v0.5 - Salida por tira de leds en 4 pines de PORT_DISP -- OK
;
;Hardware en un ATMEL ATMega 8535
;El teclado está conectado de la siguiente manera:
;
; COLUMNAS
; 0 1 2 3
;
; FILAS 0 X X X X PC4
;
; 1 X X X X PC5
;
; 2 X X X X PC6
;
; 3 X X X X PC7
;
; PC0 PC1 PC2 PC3
;
;######################################################
;CABECERA
.include "m8535def.inc"
;######################################################
;EQUIVALENCIAS
;Puerto para el teclado
.equ PORT_K=PORTC
.equ PIN_K=PINC
.equ DDR_K=DDRC
;Puerto de salida para el display de Siete Segmentos
.equ PORT_DISP=PORTA
.equ DDR_DISP=DDRA
;######################################################
;Vector de Interrupciones
.org 0x00
rjmp reset ;interrupción de Reset
;
;######################################################
;Variables Globales
;La variable tempscan se acomoda de la siguiente forma
;tempscan = [-,-,-,-,fila01,fila00,col01,col00]
;Son "banderas" que se prenden para indicar en qué fila
;y qué columna se halla la tecla.
;
.def tempscan=r17
.def temp=r16
;Rutina Principal
reset:
;inicializar pila
cli
ldi temp,low(ramend)
out spl,temp
ldi temp,high(ramend)
out sph,temp
sei
rjmp init
init:
;Inicializar Puertos
;Este código emplea el puerto C, con los bits 0 al 3 para las columnas
;y los bits 4 al 7 para las filas.
;Inicia con las filas como salidas con ceros y las columnas como entradas
;que se mantienen en un nivel alto mientras no estén conectadas
;Para lograr esto, se habilitan las "resistencias pull-up" que conectan
;el pin deseado hacia VCC.
;Para hacerlo se declaran los pines como entradas (DDR_K=0) pero
;enviamos 0xFF al registro PORT_K para activarlas.
;Declarando al nibble alto como salida y al bajo como entrada
ldi temp,0b11110000
out DDR_K,temp
;Activando las resistencias pull-up en la parte baja
ldi temp,0x0F
out PORT_K,temp
;Si se presiona una tecla, el "0" de alguna fila será
;detectado por las columnas, y entonces comienza el
;proceso de decodificación.
ldi temp,0b10000000
out DDRD,temp
;Puerto D como salida para cuando detecta tecla
ser temp
out DDR_DISP,temp
;Puerto A como salida
ldi temp,0b00000010 ;Enviar un guion al puerto A
out PORT_DISP,temp
clr tempscan ;Borra el resultado del escaneo
rjmp begin
begin:
clr temp
out PORTD,temp
;Probar si algun botón fue presionado
in temp,PIN_K
cpi temp,0x0F ;Si hay algun cero en las columnas, buscar la tecla
brne antirrebotes
rjmp begin
antirrebotes:
;Esta rutina espera un corto periodo de tiempo mientras el interruptor
;se estabiliza para evitar que el micro detecte la misma tecla varias
;veces al igual que posible ruido.
;Vuelve a leer las entradas
ser temp
out PORTD,temp
rcall delay
in temp,PIN_K
cpi temp,0x0F
;Si detecta el cero de nuevo, procesa la detección
brne deteccion
;Si fue un falso contacto, vuelve a empezar
rjmp begin
;FIN DE ANTIRREBOTES
deteccion:
clr tempscan
;inicializamos el código de escaneo temporal
ldi tempscan,0x00
;Buscar las columnas
colscan:
sbis PIN_K,0 ;prueba la columna 0
ldi tempscan,0x00
sbis PIN_K,1 ;prueba la columna 1
ldi tempscan,0x01
sbis PIN_K,2 ;prueba la columna 2
ldi tempscan,0x02
sbis PIN_K,3 ;prueba la columna 3
ldi tempscan,0x03
;Ahora que se encontró la columna, tienen que invertirse
;los sentidos del nibble bajo y el alto para buscar la
;fila
rcall invertir
;Ahora invertidos, buscaremos si alguna fila está
;baja
in temp,PIN_K
cpi temp,0xF0 ;Si hay algun cero en las columnas, buscar la tecla
brne filadetectada
rjmp init ;Si no hay fila con cero, devuelve los puertos
;a su estado original y reinicia el programa
filadetectada:
;Buscar la fila
filascan:
sbis PIN_K,4 ;Prueba la fila 0
rjmp fila0
sbis PIN_K,5 ;Prueba la fila 1
rjmp fila1
sbis PIN_K,6 ;Prueba la fila 2
rjmp fila2
sbis PIN_K,7 ;Prueba la fila 3
rjmp fila3
rjmp init ;Si no halla la fila, reinicia
;A continuación se escribirá el valor correspondiente
;a la fila, se usa el comando ROL para multiplicar por 2
;pero se limpia antes la bandera de acarreo para evitar
;que se sume y entregue valores erróneos.
fila0:
ldi temp,0x00
add tempscan,temp
rjmp fincol
fila1:
ldi temp,0x04
add tempscan,temp
rjmp fincol
fila2:
ldi temp,0x08
add tempscan,temp
rjmp fincol
fila3:
ldi temp,0x0C
add tempscan,temp
rjmp fincol
fincol:
;Toca procesar el código temporal para sacarlo
;por los leds, en este caso sale en 4 leds en puertoA
;out PORT_DISP,tempscan
rcall desinvertir ;devolver los puertos al estado original
rcall scantoseven ;Mandar al display 7 segmentos
rjmp begin
;Subrutinas
delay:
cli
;Respaldar variables globales en la pila
push r16
push r17
;Inicia secuencia de retraso
loop0: ldi r17,0x20
loop1: ldi r16,0xFF
loop2: dec r16
brne loop2
dec r17
brne loop1
sei
;Restaurar las variables desde la pila
pop r17
pop r16
ret
invertir: ;Inversión de los pines
ldi temp,0b00001111
out DDR_K,temp
;Activando las resistencias pull-up en la parte alta
ldi temp,0xF0
out PORT_K,temp
;Ahora la parte alta es entrada con pullup y la parte
;baja son salidas con ceros
ret
desinvertir: ;Devolver los pines al estado inicial
ldi temp,0b11110000
out DDR_K,temp
;Activando las resistencias pull-up en la parte alta
ldi temp,0x0F
out PORT_K,temp
;Ahora la parte baja es entrada con pullup y la parte
;alta son salidas con ceros
ret
scantoseven: ;Convierte el escaneo a display 7 segmentos catodo común
;Revisar el cableado del display en las hojas adjuntas
;El bit mas alto va al segmento "a" hasta el "g" y luego el punto decimal.
cpi tempscan,0x00
breq cero
cpi tempscan,0x01
breq uno
cpi tempscan,0x02
breq dos
cpi tempscan,0x03
breq tres
cpi tempscan,0x04
breq cuatro
cpi tempscan,0x05
breq cinco
cpi tempscan,0x06
breq seis
cpi tempscan,0x07
breq siete
cpi tempscan,0x08
breq ocho
cpi tempscan,0x09
breq nueve
cpi tempscan,0x0A
breq letraA
cpi tempscan,0x0B
breq letraB
cpi tempscan,0x0C
breq letraC
cpi tempscan,0x0D
breq letraD
cpi tempscan,0x0E
breq letraE
cpi tempscan,0x0F
breq letraF
rjmp guion
cero:ldi temp,0b11111100
rjmp sacarsegmentos
uno:ldi temp,0b01100000
rjmp sacarsegmentos
dos:ldi temp,0b11011010
rjmp sacarsegmentos
tres:ldi temp,0b11110010
rjmp sacarsegmentos
cuatro:ldi temp,0b01100110
rjmp sacarsegmentos
cinco:ldi temp,0b10110110
rjmp sacarsegmentos
seis:ldi temp,0b10111110
rjmp sacarsegmentos
siete:ldi temp,0b11100000
rjmp sacarsegmentos
ocho:ldi temp,0b11111110
rjmp sacarsegmentos
nueve:ldi temp,0b11110110
rjmp sacarsegmentos
letraA:ldi temp,0b11101110
rjmp sacarsegmentos
letraB:ldi temp,0b00111110
rjmp sacarsegmentos
letraC:ldi temp,0b10011100
rjmp sacarsegmentos
letraD:ldi temp,0b01111010
rjmp sacarsegmentos
letraE:ldi temp,0b10011110
rjmp sacarsegmentos
letraF:ldi temp,0b10001110
rjmp sacarsegmentos
guion:ldi temp,0b00000010
sacarsegmentos: ;enviar al display siete segmentos
out PORT_DISP,temp
ret
;FIN DEL PROGRAMA TECLADO MATRICIAL
Espero el programa sea claro y cualquier duda por favor dejen un mensaje en este tema.
Tweet
«
última modificación: Martes 27 de Octubre de 2009, 22:31 por netshark
»
© Jonathan ©
Moderador
Mensajes: 1671
Nacionalidad:
Re: Teclado Matricial y Display 7 Segmentos - ATMEL AVR
«
Respuesta #1 en:
Sábado 30 de Mayo de 2009, 23:08 »
0
Gracias netshark por este interesante post, esta muy bien detallado y facilita mucho la construcción de la placa y la comprensión del código. Por trabajo estoy bastante ausente del foro y veo que ya no tiene la actividad que tenia hace un tiempo, al menos el subforo de microcontroladores, por eso quiero organizar algo para activar nuevamente la actividad del sitio y volver al tiempo en el que el foro se había vuelto adicción
Comienzo agradeciendo tu aporte y te motivo a que sigas haciendo este tipo de posteos, muy bueno!
EINSTEC Tecnología
«La única fuente del conocimiento es la experiencia.»
«Lo importante es no dejar de hacerse preguntas.»
netshark
Nuevo Miembro
Mensajes: 21
Re: Teclado Matricial y Display 7 Segmentos - ATMEL AVR
«
Respuesta #2 en:
Domingo 31 de Mayo de 2009, 17:27 »
0
Saludos!
Y es cierto, me ha parecido que la actividad en el foro está un poco floja, pero mi intención es ayudar poniendo mi granito de arena.
Hasta hace poco no sabía nada de electrónica, ni mucho menos de microcontroladores pero se me ha dado la programación en diversos lenguajes. Tengo compañeros en cuyas escuelas preparatorias les enseñaron a manejar PIC, AVR y otros y me imaginé que era un mundo oscuro y difícil de entender. Ahora en la universidad descubrí que es un universo bastante interesante y con un sinfín de aplicaciones.
Estoy preparando otros programas igualmente didácticos (manejo de LCD, interfaz USART con la computadora, etc) como una forma de introducirse a los microcontroladores AVR, que han tenido un increíble
boom
en la industria y no es para menos.
Una duda: Tengo en mi poder un fenomenal e-book sobre Lenguaje C para AVR, ¿Hay algún problema si lo subo a este foro?
© Jonathan ©
Moderador
Mensajes: 1671
Nacionalidad:
Re: Teclado Matricial y Display 7 Segmentos - ATMEL AVR
«
Respuesta #3 en:
Lunes 1 de Junio de 2009, 05:59 »
0
Tal como dices, hay un sinfín de aplicaciones y los limites dependen de la imaginación de cada uno, mis felicitaciones por la voluntad para armar los documentos detallados y mas aun por compartirlos con todos nosotros.
Sobre el libro de lenguaje C para AVR, es bienvenido como todo aquello que quieras compartir, tienes a disposición el servidor FTP del foro para subir archivos de gran tamaño, los datos para el acceso los encontraras en el siguiente enlace-->
viewtopic.php?t=12696
Dentro del FTP hay carpetas destinadas a las diferentes familias de microcontroladores, creo que el directorio de ATMEL esta vacio
.. luego de subir el libro si quieres puedes poner el enlace en un post para un rápido acceso desde el subforo.
netshark mil gracias y un abrazo
EINSTEC Tecnología
«La única fuente del conocimiento es la experiencia.»
«Lo importante es no dejar de hacerse preguntas.»
netshark
Nuevo Miembro
Mensajes: 21
Re: Teclado Matricial y Display 7 Segmentos - ATMEL AVR
«
Respuesta #4 en:
Miércoles 3 de Junio de 2009, 03:32 »
0
En el primer post puse las fotos del display empleando el segundo código.
Posteriormente pondré el código para lograr esto:
Stay tuned
P.D: @Einstec: Al parecer el FTP está mal, porque intenté entrar con Filezilla y me marca que está mal el password.
Imprimir
Páginas: [
1
]
« anterior
próximo »
SoloCodigo
»
Foros
»
Programación Específica
»
Microcontroladores
»
Soluciones de Hard y Soft
(Moderador:
© Jonathan ©
) »
Teclado Matricial y Display 7 Segmentos - ATMEL AVR