Este documento presenta un tutorial sobre cómo escribir en un LCD usando un teclado matricial con un PIC. Explica cómo conectar y controlar el LCD y el teclado, así como cómo usar el temporizador Timer0 del PIC para evitar rebotes del teclado. También incluye código C que muestra cómo leer las teclas, mostrar los caracteres en el LCD y usar interrupciones del Timer0 para bloquear el teclado durante 30 ms después de cada pulsación.
Tutorial Arduino MFC y Puerto serie. Interfaz creado con Visual Studio Community 2017 que puedes controlar el puerto serie a Arduino encendiendo y apagando un Led, manejar el LC.
MFC en C++ hoy en día se usa muy poco, aún lo he visto en algunas universidades en España que lo emplea como enseñanza.
Se merece un toque actual con Arduino, a pesar quela tecnología MFC es complicada. Este tutorial te guía paso a paso hasta lograr el objetivo, ser capaz de cambiar el estado de un Led.
Más información: http://electronica-pic.blogspot.com.es/2017/07/arduino-mfc-y-puerto-serie.html
Tutorial Arduino MFC y Puerto serie. Interfaz creado con Visual Studio Community 2017 que puedes controlar el puerto serie a Arduino encendiendo y apagando un Led, manejar el LC.
MFC en C++ hoy en día se usa muy poco, aún lo he visto en algunas universidades en España que lo emplea como enseñanza.
Se merece un toque actual con Arduino, a pesar quela tecnología MFC es complicada. Este tutorial te guía paso a paso hasta lograr el objetivo, ser capaz de cambiar el estado de un Led.
Más información: http://electronica-pic.blogspot.com.es/2017/07/arduino-mfc-y-puerto-serie.html
Diseño y demostración de un dimmer digital, basado en la plataforma Arduino.
Dimmer con 100 niveles de atenuación, y capaz de escoger el sector o LED que uno desee encender.
Codigo donwload https://www.dropbox.com/s/04fisp5lzk9d25y/Dimmer_Sistemas_Digitales.ino
Timer PIC Los temporizadores o Timers son una de las características más importantes para un programador de sistemas embebidos. Cada aplicación que diseñamos involucrará de alguna manera una aplicación de tiempo, como encender o apagar algún dispositivo después de un intervalo de tiempo específico. A diferencia de simplemente usar el delay_ms() del CCS C, los timers son mucho más versátiles y precisos, dado que con el macro de delay_ms() lo que hacemos es detener la ejecución del PIC, sin embargo con el timer, podemos continuar nuestra ejecución y realizar el conteo o temporización en segundo plano. El microcontrolador PIC18F4550 tiene 4 temporizadores: 1. Timer 0 (8 bits) 2. Timer 1(16 bits) 3. Timer 2(8 bits) 4. Timer 3(16 bits) o configurable como contador
1. TUTORIAL V
OBJETIVOS
• Crear códigos en C de mayor complejidad.
• Aprender instrucciones básicas de manejo de LCD estándar.
• Realizar el Quinto Proyecto: Escritura en LCD usando teclado matricial.
• Aplicar conceptos vistos en prácticas anteriores.
• Aprender a usar el modulo Timer0 del PIC.
PROYECTO 5: Escritura en LCD usando Teclado Matricial.
En este proyecto vamos a usar el teclado matricial, que ya sabemos como manejar,
para introducir datos que serán visualizados en LCD. Además haremos uso del modulo
timer0 del PIC para evitar los rebotes del teclado.
El LCD, Liquid Cristal Display ó Pantalla de cristal líquido que vamos a usar en este
proyecto es uno de control LCD estándar de 14 pines, tal como el Hitachi HD44780. En
realidad es un poco complejo explicar a fondo como funciona internamente el LCD
(además que en Internet hay buenos documentos sobre ello) por lo que nos limitaremos
a como conectarlo al PIC y como es el código en C que lo controla.
La distribución de pines del LCD con el que vamos a trabajar es:
Pin1 es Vss, se conecta a tierra
Pin2 es Vdd, se conecta a V+. Puede ser de 2,7 a 5,5 V.
Pin3 es VEE, sirve para configurar el contraste, siendo máximo si se conectado a Vss.
Para dar mayor control se le puede adaptar algún potenciómetro de 5 o 10 K para
una graduación manual del contraste.
Pin4 es RS, Bit de Control de selección de registro que permite definir si la información
del bus de datos es un comando o un número. Lo vamos a conectar a RC4 en el
PIC16F877A.
Pin5 es R/W, Bit de Control de Lectura Escritura. En este caso se conecta a Tierra para
que siempre sea escritura.
Pin6 es EN, Bit de control de Habilitación. Es un pin para validar el dato, que lo vamos a
conectar al pin RC5 del PIC.
Pines7 a 10 se pueden dejar al aire sin ningún problema.
Pines11 a 14 se conectan al PIC en RC0 a RC3 respectivamente.
Todas estas conexiones se detallan en su respectivo diagrama al final del tutorial,
En cuanto al control del LCD, el PICC Lite cuando es instalado copia en la carpeta de
instalación en el disco duro una llamada samples, en la que están los controles
estándar del LCD en 2 archivos: lcd.c y lcd.h.
En el primero encontramos los distintos comandos que debemos colocar en nuestros
códigos para indicarle al LCD que haga cierta acción, ellos son:
lcd_init(void) //Inicializa el LCD
2. lcd_clear(void) // Permite Borrar todo el contenido visualizado en el LCD.
lcd_write(unsigned char c) //Permite escribir en el LCD un Byte
lcd_puts(const char * s) //Permite escribir una cadena de caracteres.
lcd_putch(char c) //Permite escribir un solo carácter al LCD.
lcd_goto(unsigned char pos) //Pone el cursor en la posición indicada
Además en este archivo se puede configurar los pines del micro que van a conectar a
los pines “RS” y “EN” en las dos líneas siguientes:
static bit LCD_RS @ ((unsigned)&PORTA*8+2); // Register select
static bit LCD_EN @ ((unsigned)&PORTA*8+3); // Enable
En vez de PORTA podemos poner cualquier puerto del micro de E/S digital, lo de 2 y 3
indican los pines respectivos del puerto.
En lcd.h viene a ser el archivo de cabecera del lcd.c que usualmente no se modifica y
se incluye como header file en el proyecto que se este elaborando.
Ahora bien veamos lo del Timer0:
El Timer0 es un registro de 8 bits que permite contar pulsos. El PIC16F877A también
tiene Timer1 de 16 bits y Timer2 de 8 bits. Lo interesante del registro Timer0 es que al
ser de 8 bits solo puede contar pulsos de 0 a 255 (ya que 28
=256 valores posibles)
El punto es que para ese registro existe una interrupción asociada a su
desbordamiento, es decir, es posible configurar el PIC para que genere una interrupción
cuando ese “contador” interno llegue a su limite (=255+1) También es notable el hecho
que la base del tiempo sobre la cual el Timer0 lleva su cuenta es configurable.
Veamos los registros asociados al Timer0 y su configuración:
El registro TMR0 como tal lleva el número del conteo.
El registro INTCON (que ya le hemos configurado varias veces algunos de sus bits en
tutoriales anteriores, -los sombreados en gris-) nos servirá para habilitar interrupciones
globales con el bit1, y por desbordamiento del Timer0 con el bit5. Además con el bit2
podremos saber en que momento ocurre ese desbordamiento, ya que ese bit es la
bandera respectiva TMR0IF.
El registro OPTION_REG es también muy importante ya que nos va permitir configurar:
3. • La fuente del reloj que el timer0 usa, que puede ser por:
Temporizador, con frecuencia igual a la del cristal/4.
Contador, de pulsos que entren por el pin RA4/T0CK1, el pin 6 del PIC16F877A.
Esto se configura con el bit 5 del registro, el bit T0CS. Para esta práctica lo
ponemos en 0 para que trabaje como temporizador.
• El prescaler. El bit 3 lo ponemos en 0
para indicarle al microcontrolador que
queremos el prescaler habilitado para
el modulo Timer0 y no para el
Watchdog. Los bits PS2:PS0 permiten
configurar la tasa a la cual se realiza
el conteo del Timer0, que solo aplica
en modo Temporizador. Esto es
obvio, ya que es desconocida la
frecuencia a la que llegaran los pulsos
por el pin RA4 en modo Contador, por
lo que no aplica configurar una tasa
de conteo más alta. Esto se ve en la
tabla adjunta.
PS2 PS1 PS0 Tasa en TMR0
000 1:2
001 1:4
010 1:8
011 1:16
100 1:32
101 1:64
110 1:128
111 1:256
Otro de los puntos importantes es que el registro TMR0 puede ser inicializado en
cualquier valor de 0 a 255 con el fin de tener un control de tiempo entre el arranque del
contador y su desbordamiento. Veamos 2 ejemplos para ilustrar esto:
Primer Ejemplo: supongamos el Timer0 como contador de personas que entran a un
auditorio con capacidad para 150 personas para una conferencia, con el objetivo de
tener un control riguroso.
Se configura el modulo como se ha descrito activando interrupciones por
desbordamiento en Timer0 y además se inicializa el Timer0 en 256 – 150 = 156 (Se
dice que 156 es el complemento a 2 de 150). Al entrar la última persona ocurre una
interrupción cuya atención puede ser cerrar las puertas del auditorio para que no entren
mas personas.
Segundo Ejemplo: Configuremos el Timer0 para que después de presionar una tecla
del teclado matricial de 4x4 conectado al puerto B del micro (que tiene asociada
interrupción por cambio de estado en puerto B) deshabilite el teclado por espacio de 30
milisegundos para evitar los rebotes que suponemos se dan en ese espacio de tiempo.
Es decir, por software vamos corregir el problema de los rebotes.
Sean T: Periodo y F: Frecuencia
Foscilador = 4 Mhz
Finterna = Foscilador/4 = 4Mhz/4 = 1 Mhz
4. Tinterna=1/Finterna = 1/ 1Mhz = 1 x 106
segundos
Delay(s) = Prescaler * (256 – TMR0)* Tinterna.
Donde Prescaler * (256 – TMR0) es la cantidad de pulsos que puede contar
TMR0 antes de desbordarse. Como queremos un delay en milisegundos
entonces:
Delay(ms) = Prescaler*(256 – TMR0)* Tinterna*1000
Despejando de esta expresión TMR0, y teniendo en cuenta que Delay(ms) = 30 para
este caso y suponiendo un Prescaler de 128 tenemos:
TMR0 = 256 – _____Delay(ms)_______
(1000*Prescaler* Tinterna)
TMR0 = 256 - _______30______ = 256 – 139
1000* 128 * 1x106
Se inicializa TMR0 en 139 para que al llegar a 255 con un Prescaler de 128, hayan
transcurrido 30 milisegundos. Cuando ocurra una interrupción por cambio de estado en
puerto B (es decir se haya presionado una tecla) inicializaremos el TMR0 en 139,
habilitaremos interrupción por desbordamiento del TMR0 y deshabilitaremos por cambio
de estado en puerto B. Esto lo que hace es bloquear el teclado para que el PIC no lea
los rebotes durante 30 ms.
Cuando vuelva y ocurra otra interrupción, será por desbordamiento del TMR0, en cuyo
momento deshabilitaremos interrupción por desbordamiento de TMR0 y habilitaremos
interrupción por Puerto B para que el teclado vuelva y funcione. Parece un poco
complicado en palabras, pero el código en C es bastante sencillo como veremos a
continuación:
#include <pic.h>
#include <stdlib.h>
#include "delay.h"
#include "delay.c"
unsigned char valor=0, TECLA=0;
void interrupt inter(void)
{ //Inicio de Atención a interrupciones
if (RBIE==1) //Pregunto si el teclado está activado
{ //En caso que así sea entonces...
TECLA=PORTB; //Lea lo que haya en puerto B y mándelo a “TECLA”
5. TRISB=0b00001111; //Configure como salidas los pines RB4 a RB7 y...
// ...como entradas los pines RB0 a RB3.
PORTB=TECLA; //Escriba sobre el puerto el dato que leyó
TECLA=PORTB; //Vuelva y lea el estado del PORTB...
//... y guárdelo en TECLA
TRISB=0b11110000; //Configure como salidas los pines RB0 a RB7...
//...y como entradas RB4 a RB7 (Configuración Inicial)
PORTB=0; //RB0 a RB3 envían 0 (Configuración Inicial)
If (TECLA==0b01110111) //Codificación TECLA a valor del Teclado
valor=1;
if (TECLA==0b10110111)
valor=2;
if (TECLA==0b11010111)
valor=3;
if (TECLA==0b01111011)
valor=4;
if (TECLA==0b10111011)
valor=5;
if (TECLA==0b11011011)
valor=6;
if (TECLA==0b01111101)
valor=7;
if (TECLA==0b10111101)
valor=8;
if (TECLA==0b11011101)
valor=9;
if (TECLA==0b10111110)
valor=0;
RBIF=0; //Bandera de Interrupciones por puerto B en 0
RBIE=0; //Deshabilita Interrupciones por Cambio de estado en Puerto B
TMR0=139; //Cargue el Timer0 con 139
T0IE=1; //Habilite interrupciones por desbordamiento de Timer0.
} //Fin parte afirmativa del if
else //Sino está habilitado el teclado entonces...
{ //La interrupción fue por Timer0 por lo que:
T0IE=0; //Deshabilto interrupción por desbordamiento de Timer0
RBIE=1; //Habilito el teclado nuevamente
T0IF=0; //Pongo la bandera de la interrupción por Timer0 en 0.
}
}
void main (void)
{
TRISC=0b11000000; //Bus de datos display
6. TRISB=0b11110000; //RB0 a RB3 como salidas y RB4 a RB7 como entradas
INTCON=0b10001000; //Habilita Interrupciones Globales y...
//...por cambio de estado en Puerto B, además banderas a 0.
OPTION=0b00000110; //Pull up activada, Prescaler 128, Prescaler a Timer0,
// Timer0 como temporizador,
DelayMs(10);
lcd_init(); //Inicialización LCD
lcd_clear(); //Limpiar LCD
lcd_goto(0x0); //Ir al origen
for(;;)
{ //Inicio for
if (CONTA==15) //Si llega al limite de línea superior…
lcd_goto(0x40); //…Vaya al primer espacio de la segunda línea
if (CONTA==31) //Si llega al limite de segunda línea…
{
CONTA=0; //Ponga CONTA a cero y…
lcd_goto(0x0); //Vaya al primer espacio de la primer línea del LCD
}
CONTA++; //Aumente en 1 CONTA
lcd_putch(VALOR+0x30); //Escriba el carácter VALOR, 0x30 para que…
//coincida con el ASCII de los dígitos.
} //Fin for
} //Fin Main
Copiamos este código en un Nuevo proyecto, lo compilamos y lo probamos en un
circuito como el mostrado en el diagrama de conexiones.