viernes, 12 de junio de 2009

Matriz de LEDS de 8x8


Matriz de LEDS de 8 filas y 8 columnas.

Introducción
En este proyecto veremos como diseñar y construir un display de diodos leds en forma de matriz de 8 filas por 8 columnas. El circuito incluye una memoria EEPROM externa del tipo 24C256 en la que podremos almacenar bloques de pixeles que luego seran representados por la pantalla.










Descripción del proyecto
El proyecto que desarrollaremos es una buena herramienta para el aprendizaje. El microcontrolador empleado es de los más pequeños, un PIC16F628A con 2 KBytes de memoria FLASH. Sin embargo, se puede utilizar un PIC16F627A (que tiene la mitad de memoria) o bien un PIC16F648A (que tiene el doble). Este microcontrolador puede parecer pequeño, pero es más que suficiente para poder manejar los componentes y funciones del proyecto.
Una memoria EEPROM 24C256 de 32 KBytes , a la que se accede vía I2C puede utilizarse para almacenar el contenido de 4096 pantallas, que el microcontrolador podria representar una a cotinuación de otra, a modo de video de baja resolución.
Las columnas de la matriz se seleccionan mediante un registro de desplazamiento de 8 bits de longitud, implementado a partir de un 74HC164N.

El circuito
El circuito eléctrico de este proyecto es muy sencillo. El corazón del mismo es el microcontrolador PIC16F628A.
El oscilador del PIC esta basado en un cristal de 4 MHz y dos condensadores de 22 picofaradios.
La pantalla esta construida mediante una matriz basada en 8 filas por 8 columnas de diodos LEDs, con sus ánodos controlados desde los pines del PORTB del microcontrolador, mediante un transistor 2N3906 que se encarga de proporcionar la corriente suficiente para encender los 8 LEDs de la fila.
La fila inferior corresponde al pin B0, la siguiente al B1 y asi, hasta la fila superior, que esta conectada al pin B7. Cuando querramos programar el microcontrolador, deberemos configurar todo el puerto B como salidas.
El puerto A tiene a su cargo el control del 74HC164N, que a su vez se encarga de seleccionar las columnas activas en cada momento. Entre cada salida del 74HC164N y los LEDs hemos colocado un resistor para limitar la corriente que circula por ellos. Si el brillo de los LEDs es muy bajo, puede probarse con valores mas pequeños para estos resistores. El pin DATA del 74HC164N es controlado desde A1y los pulsos de CLOCK los proporciona el pin A0.
La memoria EEPROM tambien depende del puerto A, con la línea SCL conectada al pin A2 y la línea SDA conectada al pin A3. Ambas lineas estan puestas a +V mediante resistores de 10K.
La alimentacion se ha resuelto mediante un regulador de voltaje tipo LM7805 y sus componentes asociados. Un diodo se encarga de proteger el circuito por si involuntariamente conectamos la alimentación con la polaridad invertida. La bornera es la encargada de vincular la fuente de corriente continua de entre 9V y 12V encargada de alimentar la placa.
Un pulsador, junto a una resistencia de 10K forman un circuito de reset, que tiene la capacidad de volver el circuito a su estado inicial en cualquier momento.

NOTA IMPORTANTE: En el esquema no figura la conexión del PIN 9 (RESET) del 74HC164N a +V, aunque si está contemplado en el diseño del PCB. Ese pin DEBE estar a +V para que el circuito funcione.
Lista de componentes
La lista de componentes es más bien pequeña:
  • 1 microcontrolador PIC16F628A, con su zócalo.
  • 1 memoria EEPROM 24C256, con su zócalo.
  • 1 circuito integrado 74HC164N, con su zócalo.
  • 1 regulador de voltaje LM7805
  • 4 condensadores cerámicos de 0.1 uF.
  • 2 condensadores cerámicos de 22 pF.
  • 1 xtal de 4 MHz.
  • 1 condensador electrolitico de 220uF/16V.
  • 1 diodo 1N4007.
  • 8 transistores 2N3906.
  • 8 resistores de 100 ohms.
  • 1 resistor de 10K.
  • 8 resistores de 1.5K.
  • 1 bornera de dos tornillos.
  • 64 diodos LED de 5mm, color rojo.

PCB
El circuito impreso necesario es de 80x95 milimetros, de una sola cara. Esto ha obligado a realizar una buena cantidad de puentes en el lado trasero de la placa.
Este es el aspecto del PCB.
Montaje
El montaje no requiere de ninguna técnica en especial. Una vez que tengamos el PCB listo y agujereado, procedemos a soldar los componentes. Podemos comenzar por los resistores y los LEDs. Al hacerlo, hay que tener en cuenta que los LEDs deben tener la muesca que indica el cátodo hacia el lado de los circuitos integrados. Si no lo hacemos asi, el proyecto no funcionará.
Más tarde soldaremos los zócalos, el pulsador de reset, los condensadores , el diodo 1N4007 (cuidando su orientación) y el LM7805. Por ultimo, soldaremos el cristal y pasaremos al otro lado del PCB.Aqui es donde este montaje puede diferir un poco de otros que hayas realizado. Sin embargo, tampoco es tan complicado lo que resta por hacer.
Lo primero es soldar las los dos resistores pull-up que requiere el bus I2C para funcionar. La imagen siguiente muestra donde van soldados, en rojo, los resistores mencionados.

Una vez hecho esto, debemos realizar una serie de puentes para unir los ánodos de cada fila de LEDs al colector del
transistorcorrespondiente. Deberia quedar como se ve en la foto siguiente.
Estos son los puentes a
realizar.

Ejemplo 1: TEST LED
El primer ejemplo simplemente se encarga de mostrar encendidas las filas desde la 0 a la 7, y luego enciende rectangulos de LEDs cada vez mas grandes, comenzando desde la esquina superior derecha.
Como el dato se ingresa dentro del registro de desplazamiento cuando el pulso de clock pasa de estao bajo a alto, hemos escrito dis funciones que se encargan de enviar un cero o un uno al registro. La siguiente envia el "0":
//--------------------------------------------------
//---Envia un 0 al registro de desplazamiento:
//--------------------------------------------------
void fRDD_send_data0(void){
output_low(RDD_DATA);
delay_us(2);
output_low(RDD_CLOCK);
delay_us(2);
output_high(RDD_CLOCK);
}
y esta otra envia un "1":
//--------------------------------------------------
//---Envia un 1 al registro de desplazamiento:
//--------------------------------------------------
void fRDD_send_data1(void){
output_high(RDD_DATA);
delay_us(2);
output_low(RDD_CLOCK);
delay_us(2);
output_high(RDD_CLOCK);
}

Este es el codigo completo del ejemplo 1:
//Device/Fuses/Etc.---------------------------------
#INCLUDE <16f628a.h>
#INCLUDE
#FUSES NOWDT //No Watch Dog Timer
#FUSES XT
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#use delay(clock=4000000)
//Defines------------------------------------------
#BYTE PORTA = 0x05
#BYTE PORTB = 0x06
#BYTE PORTA_TRIS = 0x85
#BYTE PORTB_TRIS = 0x86
#DEFINE RDD_DATA PIN_A1
#DEFINE RDD_CLOCK PIN_A0
#DEFINE EEPROM_SCL PIN_A2
#DEFINE EEPROM_SDA PIN_A3
//
void fConfigurar_puertos(void);
void fRDD_send_data0(void);
void fRDD_send_data1(void);
//--------------------------------------------------
//Main----------------------------------------------
//--------------------------------------------------
void main(){
int8 i,j;
fConfigurar_puertos();
output_low(RDD_CLOCK); //RELOJ = Bajo
output_low(RDD_DATA);
//
//------Dibujo las filas una a una -----
//
while (TRUE){
PORTB = 0b11111110; //Filas 1 encendida, las demas apagadas.
for (i=0;i<8;i++) j="0;j<8;j++)" portb =" (PORTB" portb =" 0b11111111;" i="0;i<8;i++)" i="0;i<8;i++)" portb =" PORTB" porta_tris =" 0b11000000;" 1="ENTRADA," 0="SALIDA" portb_tris =" 0b00000000;" 1="ENTRADA," 0="SALIDA">
#INCLUDE
#FUSES NOWDT //No Watch Dog Timer
#FUSES XT
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#use delay(clock=4000000)
//Defines------------------------------------------
#BYTE PORTA = 0x05
#BYTE PORTB = 0x06
#BYTE PORTA_TRIS = 0x85
#BYTE PORTB_TRIS = 0x86
#DEFINE RDD_DATA PIN_A1
#DEFINE RDD_CLOCK PIN_A0
#DEFINE EEPROM_SCL PIN_A2
#DEFINE EEPROM_SDA PIN_A3
//
void fConfigurar_puertos(void);
void fRDD_send_data0(void);
void fRDD_send_data1(void);
//--------------------------------------------------
//Main----------------------------------------------
//--------------------------------------------------
void main(){
int8 i,j;
fConfigurar_puertos();
output_low(RDD_CLOCK); //RELOJ = Bajo
output_low(RDD_DATA);
//
while (TRUE){
PORTB = 0b11111110; //Filas apagadas.
for (i=0;i<8;i++) j="0;j<8;j++)" j="0;j<8;j++)" portb =" (PORTB" porta_tris =" 0b11000000;" 1="ENTRADA," 0="SALIDA" portb_tris =" 0b00000000;" 1="ENTRADA," 0="SALIDA">

1 comentario: