El documento describe cómo crear una matriz LED de 8x8 controlada por un microcontrolador PIC18F2550. Explica que las matrices LED se usan comúnmente para mostrar mensajes publicitarios o informativos de manera dinámica. Luego detalla los pasos para construir el circuito, que incluye el microcontrolador, un registro de desplazamiento 74HC164 para multiplexar las filas y columnas de la matriz, y otros componentes. También incluye el código del programa para el microcontrolador para mostrar letras u otros patrones en la matriz LED.
1. Las matrices hoy en día han tomado un gran
auge en la publicidad de las grandes tiendas de
nuestra ciudad, donde se puede apreciar la
publicidad de sus productos, tomando en
cuenta que algunas veces es tedioso estar
usando papel para la realización de informar a
los clientes las ofertas existentes en ese día.
Hay matrices donde se puede cambiar el texto
fácilmente por medio de la computadora
optimizando el tiempo de publicar su producto.
Cuando vemos las matrices hablando de las más
sencillas que son las que solo muestra un texto
y después lo cambia, nos preguntamos ¿Cómo
lo hacen?, ¿Estará difícil realizar una matriz? Las
respuestas pueden ser más que fáciles, ya que
si usted es electrónico entenderá la lógica que
conlleva la construcción de una matriz de led
estática (Solo mostrar texto).
Primero que nada hay que definir ¿Que es una
matriz?
Es unn cartel formado por varias filas y
columnas de LEDs, convenientemente
programado, puede servir para pasar mensajes
publicitarios, decorar nuestra habitación,
ordenador o lo que se nos ocurra. No solo se
trata de un proyecto más que interesante para
llevarlo a cabo como hobbysta, sino que puede
resultar interesante como un producto
comercializable. Es que estas matrices, que en
algunos países se las conoce como “cartel de
LEDs” o “Publik”, son un recurso muy
frecuentemente utilizado con fines publicitarios
o informativos.
Para gastar lo menos posible vallamos a
construir una simple matriz de led 8x8
utilizando la técnica de multiplicación como
vimos en el proyecto anterior, pero en este casi
el multiplexor no será el microcontrolador que
lo haga sino otro circuito el 74HC164 que es un
registro de corrimiento de 8 bit, el Micro solo
hará la tarea de enviar pulsos para que el IC
74HC164 haga la tarea de multiplexar la matriz.
El material a usar es el siguiente:
Cantidad Material
1 PIC18F2550
1 74HC164
8 2N2222A
1 Matriz de Led 8x8 (ánodo común)
8 Resis. 330 ohm
8 Resis. 1kohm
1 7805
2 Cap. 100uF
Crearemos una simple
matrix de led de 8x8
2. [PRACTICA # 2] 15 de diciembre de 2010
PROYECTO #2 Página 108
Vallamos primero por pasos, tenemos primero que nada el diagrama de nuestra matriz donde muestra
como son las conexiones de nuestra matriz.
Como vemos en la imagen de la Izquierda tenemos que hay 8
led conectado por el ánodo, entonces sabemos que cada
columna es de ánodo común, esto da entender que debemos de
proporcionarle corriente positiva (+5) mientras que cada fila
están conectado los cátodos, entonces debemos de poner a
cero (a tierra) para que fluya una corriente de positivo a tierra,
para encender cualquier led de la matriz.
Por ejemplo se envía un dato en la fila:
11111110
Y tenemos en la columna un dato:
10000000
En hace que solo un pixel encienda:
Si hacemos un corrimiento en la columna, hará que el pixel empiece a moverse hacia la última columna
para hacer esto tenemos el IC 74HC164 que es un registro de corrimiento de 8 bits.
Donde su configuración básica es poner el pin de RST a positivo para habilitar el corrimiento, mientras
que los pines DSA,DSB deben ser unidos y solo tener uno en común para suministrar el dato a correr,
puede ser 0 o 1, el pin de Clock será los pulsos que harán el efecto de corrimiento, este pin será
manipulado por el Microcontrolador.
1 0 0 0 0 0 0 0
0
1
1
1
1
1
1
1
3. [PRACTICA # 2] 15 de diciembre de 2010
PROYECTO #2 Página 109
Entonces en el Microcontrolador será el
responsable de administrar el dato en los pines
DSA,DSB cuando sea necesario, y también será el
que generara los pulsos de corrimiento, si
deseamos también usar otro pin del Micro para
poder resetear el 74HC164 en el pin RST, lo
podemos hacer.
Cada vez que una columna sea puesta a 1
debemos de colocar el dato en la fila, después
que la columna haga un corrimiento, se debe de
colocar el siguiente dato en la columna
correspondiente, al hacer eso, pero a una
velocidad moderada, podemos decir a 1Khz, se
podrá apreciar la figura en la matriz, ya que el ojo
humano solo puede captar parpadeo antes de los
60 Hz después de esta frecuencia el ojo humano
no puede percibir tal parpadeo.
Como vemos en la imagen de alado, se puede apreciar una letra ‘A’, los
datos de la fila, se están multiplexando cada vez que es generado el
corrimiento, cada columna contiene un dato en la fila, los datos estarán
guardados en un arreglo de 8 byte, cada vez que sea necesario este
arrojara el dato que corresponda a cada columna. Como sabemos para
mostrar tal letra se está realizando las acciones a una frecuencia de 1Khz
o menos. Lo más importante es que no genere parpadeos ya que puede
afectar a largo plazo la vista humana, y generar en nosotros dolor de
cabeza, es recomendable que las letras que se muestren estén a una
frecuencia suficientemente estable y veloz para que no produzca tales dolores en nosotros.
Se ha creado una función en C para realizar la función de enviar los pulsos de corrimiento para el circuito
74HC164.
//---------------------------------------------------------
//FUNCION DE TE PERIMITE ENVIAR UN CERO O UNO /
//---------------------------------------------------------
void SEND_DATA(unsigned char DATA){
DATO=DATA;
CLOCK=0;
__delay_us(2);
CLOCK=1;
}
4. [PRACTICA # 2] 15 de diciembre de 2010
PROYECTO #2 Página 110
Cuando queramos enviar una transición de 0 a 1 para hacer el corrimiento, solo debemos de llamar a la
función SEND_DATA(con el valor a enviar) .
Ej.
Antes de la funcion
0 0 0 0 0 0 0 0
SEND_DATA(1) ; realiza el corrimiento del dato 1.
Despues de la funcion
1 0 0 0 0 0 0 0
Después de enviar el dato 1, podemos enviar 8 ceros, para hacer el corrimiento del dato 1 hacia toda la
fila. Esto se puede hacer usando simplemente un ciclo for que cuente de 0 a 7.
0 1 0 0 0 0 0 0
0 0 1 0 0 0 0 0
0 0 0 1 0 0 0 0
…
0 0 0 0 0 0 0 0
Cada vez que surja un corrimiento se debe de cargar el valor que corresponda a dicha columna en este
caso se tomara un puerto completo del microcontrolador.
Los datos estarán guardados en un arreglo de 8 byte, cada byte corresponde al valor que debe de tener
la columna. Para sacar los valores y guardarlos en el arreglo es muy simple, tenemos un software
llamado ‘control de matriz de led 8x8’
0
for(Letra=0;Letra<8;Letra++){
__delay_ms(2);
SEND_DATA(0);//Corrimiento de columnas
}
0
0
0
1
5. [PRACTICA # 2] 15 de diciembre de 2010
PROYECTO #2 Página 111
Software para matriz de Leds
Este software nos permitirá dibujar en una matriz 8x8, al tener nuestra letra o lo que vallamos hacer
solo presionaremos el botón ‘Valores’
Los datos que aparecen a un lado son los
valores que necesitamos para mostrar la letra
‘A’ en la matriz, entonces copiamos estos
valores y pegamos en nuestra variable.
Ahora bien te preguntaras como o cuando
llamamos a las variables cada vez que sea
necesario en nuestro programa, es muy
simple como ya hemos visto el corrimiento
de datos anteriormente solo basta de agregar
las líneas de:
unsigned char arreglo[8]={ 0, 252, 254, 51, 51, 51, 254, 252};//A
while(1){
for(Letra=0;Letra<8;Letra++){
PORTB=~arreglo[Letra];//saca el valor de la fila
__delay_ms(2);
SEND_DATA(0);//Corriemiento de columnas
}
SEND_DATA(1);//Inicializa columnas
}
6. [PRACTICA # 2] 15 de diciembre de 2010
PROYECTO #2 Página 112
La conexión de la Matriz se puede ver a continuación:
Como vemos la conexión se una matriz de Leds de ánodo común en las filas y cátodo común en las
columnas. He usado 8 transistores en cada fila para que entregue toda la corriente y así pueda iluminar
más.
RB0~RB7 corresponden a los 8 pines del PUERTO B del microcontrolador, mientras de C0~C7
corresponden a los 8 pines del circuito de corrimiento (74HC164).
7. [PRACTICA # 2] 15 de diciembre de 2010
PROYECTO #2 Página 113
El esquema completo podemos apreciarlo a continuación;
El programa que contiene el Microcontrolador es el siguiente:
////////////////////////////////////////////////////////
// Simple Matriz ////
//Autor: george.manson.69 ////
//Lugar: Mexico ////
//Compilador: HI TECH PIC18 (LITE MODE) ////
////////////////////////////////////////////////////////
#include<htc.h>
/////////////////////////////////////////////////////////////
//Configuracion para trabajar Con oscilador interno de 8Mhz
__CONFIG(1,INTIO & FCMDIS & IESODIS & PLLDIV5 & PLLPOSTDIV2 & CPUDIV1 & USBOSC);
/////////////////////////////////////////////////////////////
__CONFIG(2,VREGDIS & PWRTEN & BORDIS & WDTDIS & BORV45 & WDTPS32K);
__CONFIG(3,PBDIGITAL & LPT1DIS & MCLREN);
__CONFIG(4,STVRDIS & LVPDIS & ICPORTDIS & DEBUGDIS);
__CONFIG(5,UNPROTECT);
__CONFIG(6,UNPROTECT);
__CONFIG(7,UNPROTECT);
8. [PRACTICA # 2] 15 de diciembre de 2010
PROYECTO #2 Página 114
//////////////////////////////
//Frecuencia FOSC 8Mhz
//////////////////////////////
#define _XTAL_FREQ 8000000
//////////////////////////////
//Definiciones
//////////////////////////////
#define CLOCK RC1
#define DATO RC0
#define RESET1 RC2
//////////////////////////////
//Variable Globales //
//////////////////////////////
unsigned char MAX;
unsigned char Letra;
unsigned char ALFA[]={0, 252, 254, 51, 51, 51, 254, 252};//A
//---------------------------------------------------------
//FUNCION DE TE PERIMITE ENVIAR UN CERO O UNO /
//---------------------------------------------------------
void SEND_DATA(unsigned char DATA){
DATO=DATA;
CLOCK=0;
__delay_us(2);
CLOCK=1;
}
//----------------------------------------------------------
//FUNCION DE BORRADO /
//----------------------------------------------------------
void CLEAR(void){
for(MAX=1;MAX<=8;MAX++){ //8 ES EL MAXIMO DE->
SEND_DATA(1); //->COLUMNAS
}
}
/////////////////////////////////////////////////
//Funcion de interrupcion
//Si no se usa simplemente no hacemos nada...
//Esto sirve para direccionar lo los datos
//en un lugar muy cercano al Inicio de la memoria
//de datos
////////////////////////////////////////////////
static void interrupt
isr(void){}
//////////////////////////////
//FUNCION PRINCIPAL
//////////////////////////////
void main(void){
OSCCON=0x70;
NOP();NOP();NOP();NOP();
//////////////////////////////////////////////////////////////////////
// Configuracion de Puertos
///
//////////////////////////////////////////////////////////////////////
TRISB=0x00;//SALIDA PARA FILA DE LA MATRIX
TRISC=0x00;//RX=ENTRADA,TX=SALIDA
/*---------------------Fin de Conf. Puertos-------------------------*/
9. [PRACTICA # 2] 15 de diciembre de 2010
PROYECTO #2 Página 115
GIE=0; //INTERRUPCIONES GLOBALES DesACTIVADAS
PEIE=0; //DesACTIVA INTERURPCIONES POR PERIFERICOS
///////////////////////////////////////////////////////////////////////
// FUNCION PRINCIPAL ///
///////////////////////////////////////////////////////////////////////
RESET1=1;
CLEAR(); //Limpia columnas
SEND_DATA(1);//Inicializa columnas
while(1){
for(Letra=0;Letra<8;Letra++){
PORTB=~ALFA[Letra]; //saca el valor de la fila
__delay_ms(2); //espera un tiempo para vizualizar
SEND_DATA(0); //Corriemiento de columnas
}
SEND_DATA(1);//Inicializa columnas
}
}
/*-------------------------------Fin-----------------------------------*/
Imagen del Proyecto Con Matriz de 8x8
10. [PRACTICA # 2] 15 de diciembre de 2010
PROYECTO #2 Página 116
Ahora en día es muy importante manipular cualquier cosa electrónica como son los motores,
servomotores, puertas electrónicas, cámaras, por medio de la computadora, por supuesto no era de
esperarse el uso de esta tecnología para los carteles de LED, es muy frecuente tener la necesidad de
cambiar algún texto en un tablero de LED o una animación.
Este Proyecto consta de hacer precisamente la función de manipular nuestra matriz de led vía serial, en
este caso tenemos el software “Control de Matrix 8x8”, el funcionamiento es sencillo, en el programa
haremos la figura que deseamos, al tenerla sacaremos los valores, presionaremos el botón “Valores”
para adquirir los respectivos datos, al tener esto solo debemos de conectar el Serial, dirigiremos nuestro
mouse a “Serial” y después “config.Serial”.
Configuraremos el COM disponible en nuestra PC, y elegiremos a los baudios a 19200, después haremos
click en “Aplicar” y “Conectar”.
Solo bastara de conectar el nuestro circuito hecho junto con el
MAX232 en los pines RC6 y RC7.
Pero antes explicare cómo funciona el programa que debe de
tener el Microcontrolador. Por lógica debemos de usar una
interrupción por USART, cuando surja dicha interrupción se
debe de tomar 8 byte que corresponden a los 8 byte del
programa y depositarlos en la variable que se usa en la función
principal.
La configuración del Serial debe de ser a 19200 baudios ya que con una buena velocidad disminuye el
cambio o parpadeo de la matriz.
Siguiendo con nuestro
circuito armado
11. [PRACTICA # 2] 15 de diciembre de 2010
PROYECTO #2 Página 117
Como debemos de conectarlo a la computadora se debe de tener convertidor de RS232 a TTL, para
hacer esto tener el Circuito MAX232, su conexión se presenta a Continuación.
NOTA
El conector DB9 debe ser de tipo Hembra.
También se recomienda soldar solo el Max232 en una tablilla para diseños futuros ya que se le facilitara
al usuario la posibilidad de hacer menos trabajos de armar y armar nuevamente en el Protoboard.
///////////////////////////////////////////////////////////////////////
// Configuracion del USART ///
///////////////////////////////////////////////////////////////////////
OpenUSART(USART_TX_INT_OFF &//Interrupcion por Transmision apagado
USART_RX_INT_ON &//Interrupcion por Recepcion Apagado
USART_ASYNCH_MODE &//Modo Asincronico
USART_EIGHT_BIT &//8-bit de transmision
USART_CONT_RX &//Recepcion Continua
USART_BRGH_HIGH, //Alta velocidad de baudios
25); //para alta Velocidad:
// FOSC / (16 * (spbrg + 1))
// spbrg=(FOS/baud*16)-1
//Para baja Velocidad:
// FOSC / (64 * (spbrg + 1))
/*---------------------Fin de Conf. USART----------------------------*/
12. [PRACTICA # 2] 15 de diciembre de 2010
PROYECTO #2 Página 118
Esquema Completo se da a continuación:
El programa que contiene el Microcontrolador es el siguiente:
////////////////////////////////////////////////////////
// Control de Matrix 8x8 ////
//Autor: george.manson.69 ////
//Lugar: México ////
//Compilador: HI TECH PIC18 (LITE MODE) ////
////////////////////////////////////////////////////////
#include<htc.h>
/////////////////////////////////////////////////////////////
//Configuración para trabajar Con oscilador interno de 8Mhz
__CONFIG(1,INTIO & FCMDIS & IESODIS & PLLDIV5 & PLLPOSTDIV2 & CPUDIV1 & USBOSC);
/////////////////////////////////////////////////////////////
__CONFIG(2,VREGDIS & PWRTEN & BORDIS & WDTDIS & BORV45 & WDTPS32K);
__CONFIG(3,PBDIGITAL & LPT1DIS & MCLREN);
__CONFIG(4,STVRDIS & LVPDIS & ICPORTDIS & DEBUGDIS);
__CONFIG(5,UNPROTECT);
__CONFIG(6,UNPROTECT);
__CONFIG(7,UNPROTECT);
//////////////////////////////
//Frecuencia FOSC 8Mhz
13. [PRACTICA # 2] 15 de diciembre de 2010
PROYECTO #2 Página 119
//////////////////////////////
#define _XTAL_FREQ 8000000
//////////////////////////////
//Definiciones
//////////////////////////////
#define CLOCK RC1
#define DATO RC0
#define RESET1 RC2
//////////////////////////////
//Variable Globales //
//////////////////////////////
unsigned char MAX;
unsigned char CONT;
unsigned char Letra;
unsigned char ALFA[]={255, 255, 255, 227, 227, 255, 255, 255};//A
//---------------------------------------------------------
//FUNCION DE TE PERIMITE ENVIAR UN CERO O UNO /
//---------------------------------------------------------
void SEND_DATA(unsigned char DATA){
DATO=DATA;
CLOCK=0;
__delay_us(2);
CLOCK=1;
}
//----------------------------------------------------------
//FUNCION DE BORRADO /
//----------------------------------------------------------
void CLEAR(void){
for(MAX=1;MAX<=8;MAX++){ //8 ES EL MAXIMO DE->
SEND_DATA(1); //->COLUMNAS
}
}
//-----------------------------------------------------------
// HABILITADOR /
//-----------------------------------------------------------
void HABILITO(void){
if(CONT==0) SEND_DATA(1); //ENVIO DATA 0 O 1
else SEND_DATA(0);
}
/////////////////////////////////////////////////
//Funcion de interrupción
//Si no se usa simplemente no hacemos nada...
//Esto sirve para direccionar lo los datos
//en un lugar muy cercano al Inicio de la memoria
//de datos
////////////////////////////////////////////////
static void interrupt
isr(void){
///////////////////////////////////////////////
//Al recibir 8 bytes los toma para guardarlos
//en la variable que hace que mantenga el
//la imagen en la matriz 8x8
///////////////////////////////////////////////
if(RCIF){
getsUSART(ALFA,8);//Toma 8 bytes
14. [PRACTICA # 2] 15 de diciembre de 2010
PROYECTO #2 Página 120
RCIF=0;//Reset a interrupcion por recepcion
}
}
//////////////////////////////
//FUNCION PRINCIPAL
//////////////////////////////
void main(void){
OSCCON=0x70;
NOP();NOP();NOP();NOP();
//////////////////////////////////////////////////////////////////////
// Configuracion de Puertos ///
//////////////////////////////////////////////////////////////////////
TRISB=0x00;//SALIDA PARA FILA DE LA MATRIX
TRISC=0x80;//RX=ENTRADA,TX=SALIDA
/*---------------------Fin de Conf. Puertos-------------------------*/
///////////////////////////////////////////////////////////////////////
// Configuracion del USART ///
///////////////////////////////////////////////////////////////////////
OpenUSART(USART_TX_INT_OFF &//Interrupcion por Transmision apagado
USART_RX_INT_ON &//Interrupcion por Recepcion Apagado
USART_ASYNCH_MODE &//Modo Asincronico
USART_EIGHT_BIT &//8-bit de transmision
USART_CONT_RX &//Recepcion Continua
USART_BRGH_HIGH, //Alta velocidad de baudios
25); //para alta Velocidad:
// FOSC / (16 * (spbrg + 1))
// spbrg=(FOS/baud*16)-1
//Para baja Velocidad:
// FOSC / (64 * (spbrg + 1))
/*---------------------Fin de Conf. USART----------------------------*/
GIE=1; //INTERRUPCIONES GLOBALES ACTIVADAS
PEIE=1; //ACTIVA INTERURPCIONES POR PERIFERICOS
///////////////////////////////////////////////////////////////////////
// FUNCION PRINCIPAL ///
///////////////////////////////////////////////////////////////////////
RESET1=1;
CLEAR();
SEND_DATA(1);
while(1){
for(Letra=0;Letra<8;Letra++){
PORTB=ALFA[Letra];//saca el valor de la fila
__delay_ms(2);
SEND_DATA(0);//Corriemiento de columnas
}
SEND_DATA(1);//Inicializa columnas
}
}
/*-------------------------------Fin-----------------------------------*/
15. [PRACTICA # 2] 15 de diciembre de 2010
PROYECTO #2 Página 121
Ejemplo de uso de Controlar una Matriz de LED via Serial
MAX232
16. [PRACTICA # 2] 15 de diciembre de 2010
PROYECTO #2 Página 122
El corrimiento o desplazamiento de letras es muy común en los panales de Leds ya que con pocas
matrices se puede hacer que aparezca un texto completo simplemente usando el desplazamiento en
estos. Para hacer el algoritmo de programación del microcontrolador se debe de entender el
procedimiento para la realización de nuestro proyecto.
Como vimos en el proyecto anterior, teníamos un arreglo donde se depositaba los 8 datos necesarios
para mostrar la letra ‘A’, ahora si deseamos que la letra empiece desplazarse en la matriz de Leds,
consta de usar una interrupción por TIMER0 para que cada 200mS podamos actualizar la matriz, cuando
la interrupción desborde a los 200mS, lo primero que hay que realizar es copiar los datos del arreglo a
un arreglo temporal que podemos nombrarlo ‘carrgelo’ , donde al ser copiado, nuevamente pasaremos
carreglo al arreglo, pero la única diferencia es que se va realizar un corrimiento de datos del arreglo
original, con un ciclo for .
Siguiendo con nuestra Matriz de Led armada, haremos lo que todos desean de las matrices de led,
hacer el corrimiento de letras.
//////////////////////////////////////////
//Ciclo for para copiar el arreglo actual
//////////////////////////////////////////
for(x=0;x<sizeof(arreglo);x++){
carreglo[x]=arreglo[x];
}
//////////////////////////////////////////
//ciclo que realizar el corrimiento
//de datos en la matriz actual
//Creando el efecto de corrimiento
//////////////////////////////////////////
for(x=0;x<sizeof(arreglo)-1;x++){
arreglo[x]=carreglo[x+1];
}
17. [PRACTICA # 2] 15 de diciembre de 2010
PROYECTO #2 Página 123
La lógica de este último es muy sencillo, cuando se halla copiado el arreglo original al segundo (carreglo)
debemos de sacar del arreglo el primer valor y recorrer todos los valores y el ultimo será donde
debemos de colocar el valor deseado.
Cuando pasa por el ciclo:
Como vemos se ha recorrido todos los datos y dejando un espacio libre donde debe de ir el dato, este
dato ultimo será aquel que este guardado en un arreglo de datos.
Se presenta el diagrama de flujo:
Esto hará el efecto de corrimiento, lo bueno de esta técnica es que si usamos una matriz 8x8 podemos
poner un texto completo sin afectar la velocidad, si lo contrario se desea usar mas matrices esto
reducirá la velocidad y causara parpadeos o letras erróneas, para solucionar esto cuando mas matrices
se use la interrupción por timer0 se debe de acortar.
Esta práctica se desea que se desplace un texto “HOLA MUNDO” en una matriz 8x8, como ya tenemos
listo nuestro circuito armado solo basta de programar nuevamente el microcontrolador para probar el
circuito:
0x02 0xff 0x3d 0x4f 0xdd 0xff 0x00 0xaa
0xff 0x3d 0x4f 0xdd 0xff 0x00 0xaa dato
Arreglo=
Arreglo=
0x02
19. [PRACTICA # 2] 15 de diciembre de 2010
PROYECTO #2 Página 125
__delay_us(2);
CLOCK=1;
}
//----------------------------------------------------------
//FUNCION DE BORRADO /
//----------------------------------------------------------
void CLEAR(void){
for(MAX=1;MAX<=8;MAX++){ //25 ES EL MAXIMO DE->
SEND_DATA(1); //->COLUMNAS
}
}
//-----------------------------------------------------------
// HABILITADOR /
//-----------------------------------------------------------
void HABILITO(void){
if(CONT==0) SEND_DATA(1); //ENVIO DATA 0 O 1
else SEND_DATA(0);
}
/////////////////////////////////////////////////
//Funcion de interrupcion
//Si no se usa simplemente no hacemos nada...
//Esto sirve para direccionar lo los datos
//en un lugar muy cercano al Inicio de la memoria
//de datos
////////////////////////////////////////////////
static void interrupt
isr(void){
//////////////////////////////////////
//Interrupcion por TIMER0
//////////////////////////////////////
if(TMR0IF){
//////////////////////////////////////////
//Ciclo for para copiar el arreglo actual
//////////////////////////////////////////
for(x=0;x<sizeof(arreglo);x++){
carreglo[x]=arreglo[x];
}
//////////////////////////////////////////
//ciclo que realizar el corrimiento
//de datos en la matriz actual
//Creando el efecto de corrimiento
//////////////////////////////////////////
for(x=0;x<sizeof(arreglo)-1;x++){
arreglo[x]=carreglo[x+1];
}
/////////////////////////////////////////
//Se agrega el dato a actualizar en la
//ultima posicion de la matriz actual
/////////////////////////////////////////
arreglo[7]=datos[c];
/////////////////////////////////////////
//comparaciones para incializar o
//sumar uno a las variables de
//columno
/////////////////////////////////////////
20. [PRACTICA # 2] 15 de diciembre de 2010
PROYECTO #2 Página 126
if(c>86) c=0;
else c++;
TMR0IF=0;
WriteTimer0(62410);//Valor para tener una interrupcion cada 200mS
}
}
//////////////////////////////
//FUNCION PRINCIPAL
//////////////////////////////
void main(void){
OSCCON=0x70;
NOP();NOP();NOP();NOP();
//////////////////////////////////////////////////////////////////////
// Configuracion de Puertos ///
//////////////////////////////////////////////////////////////////////
TRISB=0x00;//SALIDA PARA FILA DE LA MATRIX
TRISC=0x00;
/*---------------------Fin de Conf. Puertos-------------------------*/
//////////////////////////////////////////////////////////////////////
// Configuracion de Timer1 ///
//////////////////////////////////////////////////////////////////////
OpenTimer0(TIMER_INT_ON &//Interrupcion activada
T0_16BIT &//valor de 16 bit
T0_SOURCE_INT &//Corriente desde el oscilador principal
T0_PS_1_128); //Preescalar de 16
/*---------------------Fin de Conf. TIMER1--------------------------*/
INTCON|=0b00100000;//Para activar interrupcion por timer0
WriteTimer0(62410);//Valor para tener una interrupcion cada 200 mS
GIE=1; //INTERRUPCIONES GLOBALES ACTIVADAS
PEIE=1; //ACTIVA INTERURPCIONES POR PERIFERICOS
///////////////////////////////////////////////////////////////////////
// FUNCION PRINCIPAL ///
///////////////////////////////////////////////////////////////////////
RESET1=1;
CLEAR();
SEND_DATA(1);
while(1){
for(Letra=0;Letra<8;Letra++){
PORTB=~arreglo[Letra];//saca el valor de la fila
__delay_ms(2);
SEND_DATA(0);//Corriemiento de columnas
}
SEND_DATA(1);//Inicializa columnas
}
}
/*-------------------------------Fin-----------------------------------*/
NOTA
El signo “~” sirve para hacer cambiar de dato, si es 1 lo cambia por 0, esto sirve si usamos una matriz de
cátodo o ánodo común en la salida del puerto.
21. [PRACTICA # 2] 15 de diciembre de 2010
PROYECTO #2 Página 127
Este proyecto a comparación del anterior
consta de cambiar el texto de la Matrix, cuando este en corrimiento o desplazándose, y así hemos de
finalizar todo lo relacionado con Matrices.
Tenemos un programa llamado “Matrix” que fue realizado con el Software Microsoft visual C# 2010
express que realiza una función primordial en el proyecto. Su funcionamiento es sencillo, primero
conectaremos el software al serial al COM existente en nuestra computadora.
Como la velocidad de transmisión será de 19200
baudios por default, debemos de procurar que sea la
misma en el microcontrolador.
Y simplemente escribiremos el texto en el “textbox”
siempre y cuando cumpla con los 27 caracteres, esto
quiere decir que debemos de escribir como máximo
27 letras.
Después de haber armado el circuito físicamente
solo basta de conectarlo y enviar el dato.
Ahora como ya tenemos la idea de cómo
funciona, pasaremos a explicar el
funcionamiento del programa del
microcontrolador que no es más que la unión de
los 2 últimos proyectos anteriores.
Como ya hemos visto como funciona al recibir los datos por el serial y como hace el corrimiento de
letras, no es más que unir las dos ideas para desarrollar este proyecto.
27 caracteres escritos
debe de aparecer un
cero para OK
22. [PRACTICA # 2] 15 de diciembre de 2010
PROYECTO #2 Página 128
En el programa que a continuación se dara se dice que tiene un arreglo de 216 bytes que debe de tener
los datos. Como el programa “Matrix” envía 216 bytes que corresponden a que cada 8 byte es para la
letra escrita.
EJ.
Si enviamos 216 bytes entonces dividíos.
݊௧௦ =
݊௬௧
8
݊௧௦ =
216
8
= 27
El resultado si vemos es el mismo valor que corresponde al programa, que solo debemos de escribir 27
letras como máximo.
La única diferencia que vamos a tener al unir las dos ideas de los 2 últimos proyectos, es que el arreglo
de datos debe de ser de 216 ya que será el máximo de bytes necesarios para mostrar 27 letras.
El circuito es exactamente igual que el proyecto anterior, solo debemos de programar el micro con el
programa que a continuación se da.
Programa que contiene el Microcontrolador.
////////////////////////////////////////////////////////
// Corrimiento de Matrix ////
//Autor: george.manson.69 ////
//Lugar: Mexico ////
//Compilador: HI TECH PIC18 (LITE MODE) ////
////////////////////////////////////////////////////////
#include<htc.h>
/////////////////////////////////////////////////////////////
//Configuracion para trabajar Con oscilador interno de 8Mhz
__CONFIG(1,INTIO & FCMDIS & IESODIS & PLLDIV5 & PLLPOSTDIV2 & CPUDIV1 & USBOSC);
/////////////////////////////////////////////////////////////
__CONFIG(2,VREGDIS & PWRTEN & BORDIS & WDTDIS & BORV45 & WDTPS32K);
__CONFIG(3,PBDIGITAL & LPT1DIS & MCLREN);
__CONFIG(4,STVRDIS & LVPDIS & ICPORTDIS & DEBUGDIS);
__CONFIG(5,UNPROTECT);
__CONFIG(6,UNPROTECT);
__CONFIG(7,UNPROTECT);
//////////////////////////////
//Frecuencia FOSC 8Mhz
//////////////////////////////
#define _XTAL_FREQ 8000000
//////////////////////////////
//Definiciones
//////////////////////////////
#define CLOCK RC1
#define DATO RC0
#define RESET1 RC2
23. [PRACTICA # 2] 15 de diciembre de 2010
PROYECTO #2 Página 129
//////////////////////////////
//Variable Globales //
//////////////////////////////
unsigned char MAX;
unsigned char CONT;
unsigned char Letra,c,f,x;
unsigned char arreglo[8]={255, 255, 255, 227, 227, 255, 255, 255};//A
unsigned char carreglo[8];
unsigned char datos[216];
//---------------------------------------------------------
//FUNCION DE TE PERIMITE ENVIAR UN CERO O UNO /
//---------------------------------------------------------
void SEND_DATA(unsigned char DATA){
DATO=DATA;
CLOCK=0;
__delay_us(2);
CLOCK=1;
}
//----------------------------------------------------------
//FUNCION DE BORRADO /
//----------------------------------------------------------
void CLEAR(void){
for(MAX=1;MAX<=8;MAX++){ //25 ES EL MAXIMO DE->
SEND_DATA(1); //->COLUMNAS
}
}
//-----------------------------------------------------------
// HABILITADOR /
//-----------------------------------------------------------
void HABILITO(void){
if(CONT==0) SEND_DATA(1); //ENVIO DATA 0 O 1
else SEND_DATA(0);
}
/////////////////////////////////////////////////
//Funcion de interrupción
//Si no se usa simplemente no hacemos nada...
//Esto sirve para direccionar lo los datos
//en un lugar muy cercano al Inicio de la memoria
//de datos
////////////////////////////////////////////////
static void interrupt
isr(void){
//////////////////////////////////////
//Interrupción por TIMER0
//////////////////////////////////////
if(TMR0IF && TMR0IE){
//////////////////////////////////////////
//Ciclo for para copiar el arreglo actual
//////////////////////////////////////////
for(x=0;x<sizeof(arreglo);x++){
carreglo[x]=arreglo[x];
}
//////////////////////////////////////////
//ciclo que realizar el corrimiento
//de datos en la matriz actual
24. [PRACTICA # 2] 15 de diciembre de 2010
PROYECTO #2 Página 130
//Creando el efecto de corrimiento
//////////////////////////////////////////
for(x=0;x<sizeof(arreglo)-1;x++){
arreglo[x]=carreglo[x+1];
}
/////////////////////////////////////////
//Se agrega el dato a actualizar en la
//ultima posición de la matriz actual
/////////////////////////////////////////
arreglo[7]=datos[c];
/////////////////////////////////////////
//comparaciones para inicializar o
//sumar uno a las variables de
//columna
/////////////////////////////////////////
if(c>214) c=0;
else c++;
TMR0IF=0;
WriteTimer0(62410);//Valor para tener una interrupcion cada 200 mS
}
////////////////////////////////////////
//Surge la interrupción por Recepcion
//de datos, recibiremos 216 BYTES
//Desactiva la interrupción por Timer0
////////////////////////////////////////
else if(RCIF){
TMR0IE=0;
getsUSART(datos,216);
TMR0IE=1;
}
}
//////////////////////////////
//FUNCION PRINCIPAL
//////////////////////////////
void main(void){
OSCCON=0x70;
NOP();NOP();NOP();NOP();
//////////////////////////////////////////////////////////////////////
// Configuracion de Puertos ///
//////////////////////////////////////////////////////////////////////
TRISB=0x00;//SALIDA PARA FILA DE LA MATRIX
TRISC=0x80;
/*---------------------Fin de Conf. Puertos-------------------------*/
//////////////////////////////////////////////////////////////////////
// Configuracion de Timer1 ///
//////////////////////////////////////////////////////////////////////
OpenTimer0(TIMER_INT_ON &//Interrupcion activada
T0_16BIT &//valor de 16 bit
T0_SOURCE_INT &//Corriente desde el oscilador principal
T0_PS_1_128); //Preescalar de 16
/*---------------------Fin de Conf. TIMER1--------------------------*/
///////////////////////////////////////////////////////////////////////
// Configuracion del USART ///
///////////////////////////////////////////////////////////////////////
OpenUSART(USART_TX_INT_OFF &//Interrupcion por Transmision apagado
25. [PRACTICA # 2] 15 de diciembre de 2010
PROYECTO #2 Página 131
USART_RX_INT_ON &//Interrupcion por Recepcion Apagado
USART_ASYNCH_MODE &//Modo Asincronico
USART_EIGHT_BIT &//8-bit de transmision
USART_CONT_RX &//Recepcion Continua
USART_BRGH_HIGH, //Alta velocidad de baudios
25); //para alta Velocidad:
// FOSC / (16 * (spbrg + 1))
// spbrg=(FOS/baud*16)-1
//Para baja Velocidad:
// FOSC / (64 * (spbrg + 1))
/*---------------------Fin de Conf. USART----------------------------*/
INTCON|=0b00100000;//Para activar interrupcion por timer0
WriteTimer0(62410);//Valor para tener una interrupcion cada 200 mS
GIE=1; //INTERRUPCIONES GLOBALES ACTIVADAS
PEIE=1; //ACTIVA INTERURPCIONES POR PERIFERICOS
///////////////////////////////////////////////////////////////////////
// FUNCION PRINCIPAL ///
///////////////////////////////////////////////////////////////////////
RESET1=1;
CLEAR(); //Limpia la Matriz
SEND_DATA(1);//Envia el dato para Inicializar corrimiento
//en el IC 74HC164
while(1){
for(Letra=0;Letra<8;Letra++){
PORTB=arreglo[Letra];//saca el valor de la fila
__delay_ms(2);//Tiempo de muestra
SEND_DATA(0);//Corriemiento de columnas
}
SEND_DATA(1);//Inicializa columnas
}
}
/*-------------------------------Fin-----------------------------------*/