Teclado Matricial con LCD
En
esta ocasión veremos como hacer uso de un Teclado Matricial con una pantalla LCD que son de los elementos mas utilizados para implementar una interfaz de usuario en un sistema electrónico.
La programación se realizara utilizando MPLABX y el compilador XC8 ambos disponibles en la pagina de microchip. Aquí dejo los enlaces de las versiones utilizadas para nuestro ejemplo: <MPLABX v6.20> <XC8 v2.45>
Mencionar también que es necesario contar con conocimientos mínimos sobre programación en lenguaje C y el uso de microcontroladores PIC16.Introducción al Tema
Con el objetivo de mostrar como hacer uso de un teclado matricial y una pantalla LCD, implementaremos en nuestro circuito una interfaz de usuario que permite validar una clave numérica de cuatro dígitos, mostrando los respectivos mensajes de solicitud y validación en la pantalla LCD.
Es importante mencionar que existe en internet una amplia informacion de las características y usos de estos dos dispositivos, por lo que recomiendo revisar algunas de estas referencias.
Referencia <Teclado Matricial 1> y <Teclado Matricial>
Referencia <Pantalla LCD 1> y <Pantalla LCD 2 >
Considerando la necesidad de implementar una interfaz de usuario con Teclado Matricial y Pantalla LCD he descrito un resumen de estos dispositivos considerando el circuito que se montara para la practica.
Teclado Matricial 4x4
La figura 1, muestra la disposición interna de un teclado matricial 4x4, es decir cuatro filas y cuatro columnas, conformando así un total de 16 pulsadores o botones. Notara que el principio de funcionamiento es bastante simple, por ejemplo si presionamos el botón 3 entrara en contacto la fila 0[ROW0] con la columna 2[COL2], y se mantendrá cerrado hasta liberar el botón.
Fig1. Teclado Matricial 4x4 |
Bajo este principio consideraremos para fines prácticos que las columnas son las salidas y las filas son las entradas del Microcontrolador (MCU), por lo tanto conectar un Teclado Matricial 4x4 requiere al menos 8 pines del MCU.
Las figuras 2 y 3, muestran la distribución de pines de algunos Teclados que mas se comercializan, pero debe considerar que esta informacion debe verificarse con la hoja de datos que proporciona el fabricante.
Fig2. Teclado Matricial tipo Rígido |
Fig3. Teclado Matricial tipo Membrana |
Considerando estos aspectos describiremos los procedimiento y funciones de la librería keypad que utilizaremos.
- KBSetup(): Configura el Puerto donde se conectara el teclado, es importante mencionar que se debe editar las siguientes definiciones en la cabecera keypad.h
#define KB_PORT PORTB //Puerto asociado
#define KB_TRIS TRISB //Registro Tris asociado
/* END USER PORT DEFINITIOS */
La disposición del teclado con relación a los pines del puerto asignado, es que los cuatro bits de menor peso(salidas) corresponden a las columnas y los cuatro de mayor peso serán(entradas) las filas, recuerde que las filas necesitas de resistencias pull-ups.
- KBScan(): Efectúa un ciclo con barrido de ceros en las columnas (walking zeros) para detectar si existe un botón presionado haciendo lectura de las entradas, esta función retorna cero si no hay un botón presionado. En caso de presionar un botón del teclado la función retorna un código binario(res) que indica la posición(fila, columna) de la matriz. Considerando que un ciclo de barrido requiere pocos ciclos de reloj, es necesario llamar a la función continuamente hasta que el valor de retorno sea diferente a cero, una vez recibido el código del botón, también es importante considerar que el teclado deberá liberarse para evitar una validación continua, a continuación se muestra un ejemplo simple de como leer un botón y esperar hasta que el botón se libere.
if(res != 0) //Si el resultado, es diferente de 0
{ /* Codigo para boton presionado */
valor = KBGetValue(res); //Convierte el codigo a numero
while(KBScan()) {}; //Espera liberacion del boton
}
- KBGetChar(n): Esta función se utiliza para convertir el código binario del teclado que retorna la función KBScan a un carácter de tipo ascii, si el código no corresponde con un carácter valido, la función devuelve '?'.
- KBGetValue(n): A diferencia de la anterior función, este convierte el código binario del teclado en un numero decimal, si el código no
corresponde con un numero valido, la función devuelve 0xFF.
La Pantalla LCD 20x2
La configuracion de pines para la pantalla LCD corresponde con la distribución que se muestra en la figura 4.
Fig4. Mapa de pines del LCD |
GND: Conexión a tierra 0V
VCC: Alimentación a 5V
VEE: Contraste 0V-5V
RS: Selector modo comando o dato
R/W: Selector Lectura o Escritura
EN: Señal de habilitación
DBx: Bus datos paralelo 8-bit/4-bit
Led+: Ánodo LED para luz de fondo
Led-: Cátodo LED para luz de fondo
Una ventaja de estos módulos LCD, es que cuentan con el modo de operación paralelo de cuatro bit (4-bit mode) que sumado a las lineas de control RS y EN, necesitaremos únicamente 6 pines del MCU para su uso.
Las capacidades que tiene le modulo LCD van mas allá de lo que se utiliza en esta publicación, para nuestro caso el LCD lo utilizaremos solo para mostrar mensajes con los símbolos ASCII por defecto que posee en su memoria, es por esta razón que no se requieren operaciones de lectura y por lo tanto el pin de control R/W permanecerá en nivel bajo.
Para que nuestro MCU pueda mostrar mensajes en el LCD, se debe completar un proceso de inicialización de acuerdo a requerimientos de tiempo descritos en la hoja de datos del fabricante, considerando de forma general los tiempos máximos para la temporización las señales, la librería lcd que utilizaremos en nuestra implementación, contiene una sección de código para definir estos valores de acuerdo a un modelo especifico. A continuación se describen algunos de los procedimientos de mayor uso en nuestro programa.
- LCD_Setup(): Este procedimiento configura el puerto asociado al los pines del LCD, donde es posible definir los cuatro pines de menor peso de cualquier puerto del MCU y de forma separadas los dos pines de control RS y EN. En segunda instancia este procedimiento lleva a cabo la inicialización del modulo LCD, siendo por defecto la siguiente configuracion:
2) Incremento de posición automático;
3) Muestra el cursor sin destellar;
4) Limpia la pantalla e inicializa el cursor.
La definición del puerto asociado a los pines del LCD y los valores de temporización se lleva a cabo modificando las siguientes lineas de código en la cabecera lcd.h. Por defecto los cuatro pines DB4 al DB7 del LCD corresponden con los primeros cuatro bits del puerto en el PIC, es posible cambiar la asignación a los últimos cuatro bits del puerto agregando la #define LCD_UPPER_DB en la cabecera.
/* USER PORT DEFINITION */
#define LCD_PORT PORTD //Puerto asociado
#define LCD_TRIS TRISD //Registro Tris asociado
#define LCD_RS PORTDbits.RD4 //Pin RS Asociado
#define LCD_EN PORTDbits.RD5 //Pin EN Asociado
#define LCD_RS_TRIS TRISDbits.TRISD4 //Pin Tris RS
#define LCD_EN_TRIS TRISDbits.TRISD5 //Pin Tris EN
#ifndef _XTAL_FREQ
#define _XTAL_FREQ 8000000 //Define Frecuencia
#endif
/* END USER PORT DEFINITIONS */
- LCD_WriteCMD(Cmd): Este procedimiento permite enviar un comando de la lista de definiciones al modulo LCD, siendo algunos ejemplos de uso, los siguientes:
- LCD_WriteMsg(*str): El procedimiento sirve para mostrar un mensaje de texto en la pantalla LCD, considerando que el mensaje iniciara en la posición que tiene el cursor. El contenido del mensaje(str) corresponde a un arreglo de caracteres con carácter nulo al final(null_string).
- LCD_WriteChar(data): El procedimiento muestra en la pantalla LCD y en la posición del cursor, un único carácter val, el dato(data) debe formar parte de la tabla de caracteres ascii.
- LCD_WriteNum(num, padn):
A diferencia del anterior procedimiento, este muestra en el LCD desde la posición del cursor un valor decimal entero de 16-bits(val), mismo que puede alinearse con una cantidad de ceros a la izquierda (padn).
- LCD_GotoXY(col, row): El procedimiento permite posicionar el cursor en la pantalla LCD, considerando una distribución de filas y columnas donde las filas(row) representan la cantidad de lineas que generalmente son:
- 0: Linea 1
- 1: Linea 2
- 2: Linea 3
- 4: Linea 4
Esquema del Circuito
Diagrama de circuito elaborado en ISIS Proteus V8.0
Fig5. Esquema del circuito electrónico |
Programa del Microcontrolador
El programa que implementaremos para ensayar el Teclado Matricial y pantalla LCD tendrá como propósito, mostrar en la pantalla un Mensaje de solicitud de contraseña "PASSWORD", para que el usuario introduzca con el teclado una contraseña de cuatro dígitos y luego validar con el código "3022", y dependiendo de esta validación se mostrara un mensaje de "CORRECTO" o "ERROR". El proceso que sigue el programa se ilustra en el diagrama de la figura 6.
Fig6. Secuencia del programa |
/*Programa Principal*/
void main(void)
{
setupMCU(); //Configuracion del PIC
LCDSetup(); //Inicia el modulo LCD
KBSetup(); //Inicia el KeyPad
while(1)
{
if(tick1ms) //Se valida cada 1ms
{
tick1ms = 0;//Limpia bandera
taskLED(); //Tarea destello LED
taskAPP(); //Tarea de la Aplicación
}
}
}
/*Tarea de la Aplicacion*/
void taskAPP(void)
{
static uint8_t keycnt, state = 0; //variables no volátiles
static uint16_t cnt = 0; //variable contador
uint8_t res, value; //variables temporales
switch(state)
{
case 0: //S0-Muestra mensaje
LCDGotoXY(0,0); //Posiciona el cursor linea 1
LCDWriteMsg(" PASSWORD");
LCDGotoXY(1,0); //Posiciona el curso linea 2
LCDWriteMsg(" [ ]");
LCDGotoXY(1,3); //Posiciona linea 2, col 3
cnt = 0; //inicia contador de ms
keycnt = 0; //Inicia contador de dígitos
state = 1; //carga estado 1
break;
case 1: //S1-Lectura del teclado
res = KBScan(); //Lectura del Teclado
if(res) //Si hay dato valido
{
if(cnt++ > 99) //Repite para confirmación del botón
{
value = KBGetChar(res);//Recupera valor a char
LCDWriteChar(value); //Escribe valor en pantalla
state = 2; //Carga estado 2
}
} else cnt = 0;
break;
case 2: //Contador de dígitos ingresados
password[keycnt] = value; //Agrega dígito al password
keycnt++; //Incrementa contador de dígitos
if(keycnt > 3) //Mas de tres dígitos recibidos
{
password[keycnt] = 0;
state = 4; //Carga estado 4 para validar password
}
else state = 3; //Carga estado 3 para recibir otro dígito
break;
case 3: //Espera liberación del botón
if(!KBScan()) state = 1; //Lectura del siguiente dígito
break;
case 4: //Compara contraseña
LCDGotoXY(1,0); //Posiciona Cursor linea 2
res = (uint8_t) strcmp("3022", password); //Compara
if(res == 0) LCDWriteMsg(" Correcto"); //Código correcto
else LCDWriteMsg(" Error "); //Código incorrecto
state = 5; //Carga estado 5
break;
case 5: //Genera retardo antes de reiniciar
if(cnt++ > 1999) //Espera hasta 2000ms
{
LCDWriteCMD(LCD_CLEAR); //Limpia la pantalla
state = 0; //Carga estado 0
}
break;
}
}
Funcionamiento
Una vez cargado el programa en el PIC16F, el circuito comienza a destellar el LED una vez por segundo, esto indica que el programa se encuentra en funcionamiento normal, así mismo la pantalla LCD mostrara el mensaje "PASSWORD", solicitando ingresar la contraseña, entonces puede ingresar los dígitos utilizando el teclado, en el instante que ingrese el cuarto dígito, se procederá a validar el código y mostrar en la pantalla si es "Correcto" o "Error", este mensaje se mantendrá un par se segundos para luego reiniciar el proceso, donde se pedirá nuevamente ingresar otra contraseña. La figura 7 muestra la implementación física del circuito.
Fig7. Implementacion del circuito |
Conclusiones
Se
verifico correctamente el funcionamiento del Teclado Matricial y la pantalla LCD con el PIC16F887, completando así el propósito de esta
publicación.
Aquí dejo
los enlaces para que puedas descargar el proyecto MPLABX, mismo que se encuentran comprimidos con gzip,
Atte. Pablo Zárate Arancibia
email: pablinza@me.com / pablinzte@gmail.com, @pablinzar
Santa Cruz de la Sierra - Bolivia
No hay comentarios.:
Publicar un comentario