You are on page 1of 10

COMO HACER UNA MATRIZ DE LED 8x8

En principio el lenguaje utilizado es BASIC y el programa picsimulator ide, el pic16f628a con


cristal interno, las bases para entender la programacin se encuentran en mi primer post:
http://www.taringa.net/posts/ciencia-educacion/5817733/programacion-de-microcontroladores-
pic-en-basic-y-simulacion.html
Empezamos primero con el circuito de la matriz de led 8x8, primero la matriz:
(con todo el respeto a los de neoteo, utilizo sus imgenes)



Observando la imagen los nodos (positivos) se conectan horizontalmente formando las filas y
los ctodos (negativos) se conectan verticalmente formando las columnas teniendo 8 filas y 8
columnas. Para encender un led hay que alimentar con positivo en la fila y negativo en la
columna (explicado abajo).

La matriz en el proteus, como la utilizaremos y como encender un led es la siguiente:



Como mencionamos arriba se alimenta con positivo a las filas y negativo a las columnas.
El circuito de toda la matriz es el siguiente:



Este es el circuito de simulacin que lo usaremos para todas las explicaciones (se puede
observar una resistencia de 10k conectada a ra4 ya que esta NO es una salida cmos necesita
la resistencia, sin esta ra4 no funciona como salida, las resistencias conectadas a los
colectores de los transistores son solo por simulacin ya que el bc548 a mi no me trabaja sin
ellas y todo el tiempo bota negativo pero en el pcb no se utilizan) y ahora el pcb, realizado en
pcbwizard.








Aqu presento el diagrama de conexin:


El PIC utilizado en esta ocacin es el PIC16F88 por ser muy fcil de implementar y contar con
oscilador interno.

La lnea Load se conecta al pin B0 del PIC, Clk al B1, dClm a B2 y dLin a B3.

La lista de componentes es mas cuantiosa que variada pues esta compuesta por:
R1-R8 8 x Resistencias de 220
R9-R16 8 x Resistencias de 3,9K
Q1-Q8 8 x Transistores BC547 o similar

2 x 74HC595

64 x LED rojo de 5mm brillo standard

El cdigo, escrito en CCS C, para probar el hardware es el que sigue a continuacin, solo he
dejado las letras pertinentes a PICROBOT, ya que sino se hace muy largo y repetitivo para
mostrarlo como ejemplo, pero desde este link te puedes descargar el cdigo completo con
las letras en maysculas A-Z, el .HEX, el .COF para simularlo en el ISIS de Proteus y el .DSN
con el diseo.

Hay dos versiones del cdigo en este paquete, matriz8x8Q y matriz8x8. La primera es para
cuando se usen los transistores a los ctodos de los LED y la segunda si los ctodos van
directamente a las salidas del registro de desplazamiento encargado de controlar las
columnas.

La nica diferencia entre las dos versiones es que la primer versin (Q) no invierte y la
segunda si lo hace, las salidas del registro encargado de controlar las filas.

Se podra haber solucionado el problema declarando o no una macro instruccin dirn
algunos, despus de todo lo nico que vara es un caracter de una versin a otra, pero para no
confundir, y como este es un ejemplo sencillo, decid hacerlo as. En un futuro ejemplo de la
implementacin tal vez incluya una macro instruccin.
/*********************************************************************
****
**
**
** Ejemplo bsico para controlar una matriz de 8x8 LEDs con PIC.
**
**
**
** (c) 2010 Gerardo Ariel Ramrez
**
** picblog@hotmail.com
**
** http://picrobot.blogspot.com/
**
**
**
**********************************************************************
****
**
**
** Microcontrolador: PIC16F88 Oscilador: Interno - 8 MHz
**
** Lenguaje: CCS C
**
**
**
**********************************************************************
***/

#include <16f88.h> // Tipo de microcontrolador
#fuses INTRC_IO,MCLR // Oscilador interno, MCLR activo
#fuses NOPUT,NOBROWNOUT // Sin Brownout reset ni Power up timer
#use fast_io(all) // La configuracin de los puertos solo se
hace al principio.
#use delay(clock=8M) // Velocidad del oscilador interno 8 MHz

#define Load PIN_B0 // Load (STCP ambos integrados) B0
#define Clk PIN_B1 // Clock (SHCP ambos integrados) B1
#define dClm PIN_B2 // Data para las columnas (DS integrado 1) BC2
#define dLin PIN_B3 // Data para las lineas (DS integrado 2) B3

char Memoria[96]; // 96 Bytes para la memoria (0 - 95)
char Visor[8]; // 8 para el visor (8 columnas)

int1 flag; // Flags de control
int1 flag2;
int indx; // Indice donde almacenar las nuevas
columnas.
int line; // Linea que a mostrar.
int time; // Variables para el control de
int ptime; // la velocidad de desplazamiento.
int t; // Variable auxiliar.

void CargaMem(char Ascii);
void GuardaClm(char c);

#int_rtcc
void isr(){
int Mul=128; // Cada vez que ocurre la interrupcion
if(++line>7)Line=0; // selecciona la siguiente linea, si se pasa
de 7 vuelve a 0.

if(++ptime>5){ // Suma 1 a ptime. Si se pasa de 20
ptime=0; // lo pone en 0 y suma 1 a time.
if(++time>200){ // Si se pasa de 200
time=0; // lo pone en 0
Flag=true; // y activa el flag.
}
}


for(t=0;t<8;t++){ // Bucle 0 - 7 (Lineas)

output_bit(dLin,!!(Visor[Line]&Mul)); // dLin es seteado con el
valor
// del bit de la fila
actual.
if (Line==t)output_high(dClm); // Si Line es igual a t
// activa el bit
correspondiente
else output_low(dClm); // a la columna, sino lo
desactiva.

output_low(Clk); //
output_high(Clk); // Rota el contenido interno del 74HC595.

Mul>>=1; // Divide la mascara que compara con Visor[]
(128,64,32...)
}
output_low(Load);
output_high(Load);// El contenido interno del integrado pasa a
las salidas.

}
void main(){
int k;
set_tris_a(0x00);
set_tris_b(0x00);
for (k=0;k<8;k++){
Visor[k]=0;
}
for (k=0;k<96;k++){
Memoria[k]=0;
} // Limpia la memoria y el visor

flag=true; // Activo el flag para que cargue la memoria

setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); // Configuracin del
Timer0
enable_interrupts(int_rtcc); // Interrupcion por
Timer0
enable_interrupts(global); // Interrupciones
globales

do{
if (Flag){ // Si el flag est activado
flag2=true; // Activa el flag2

for (k=0;k<8;k++){ // Pasa el contenido de las primeras
8
visor[k]=Memoria[k]; // columnas en memoria al visor
}

for (k=0;k<95;k++){ // Rota el contenido de toda la
memoria
Memoria[k]=Memoria[k+1];// a la izquierda 1=1+1, 2=2+1,
n=n+1...

if (Memoria[k]!=0){Flag2=false;} // Si hay alguna columna
que no
// est vaca desactiva
el flag2
}
Memoria[95]=0; // Limpia la ultima columna de la
memoria

if (Flag2){ // Si flag2 est activo
indx=7; // a partir de la columna 7
CargaMem("PICROBOT"); // escribe PICROBOT
}
Flag=false; // Desactiva el flag

}
}while (true); // Bucle infinito


}

void GuardaClm(char c){
if (indx<94){
Memoria[indx]=c; // Guarda la columna en la ubicacin actual
de memoria
indx++; // y aumenta el indice
}
}


void CargaMem(char ascii){ // Carga la memoria con el caracter
deseado
switch (ascii){

case('B'):
GuardaClm(0b01111111);
GuardaClm(0b01111111);
GuardaClm(0b01001001);
GuardaClm(0b01001001);
GuardaClm(0b01111111);
GuardaClm(0b00110110);
break;

case('C'):
GuardaClm(0b00111110);
GuardaClm(0b01111111);
GuardaClm(0b01000001);
GuardaClm(0b01000001);
GuardaClm(0b01100011);
GuardaClm(0b00100010);
break;

case('I'):
GuardaClm(0b01000001);
GuardaClm(0b01000001);
GuardaClm(0b01111111);
GuardaClm(0b01111111);
GuardaClm(0b01000001);
GuardaClm(0b01000001);
break;

case('O'):
GuardaClm(0b00111110);
GuardaClm(0b01111111);
GuardaClm(0b01000001);
GuardaClm(0b01000001);
GuardaClm(0b01111111);
GuardaClm(0b00111110);
break;

case('P'):
GuardaClm(0b01111111);
GuardaClm(0b01111111);
GuardaClm(0b00001001);
GuardaClm(0b00001001);
GuardaClm(0b00001111);
GuardaClm(0b00000110);
break;

case('R'):
GuardaClm(0b01111111);
GuardaClm(0b01111111);
GuardaClm(0b00001001);
GuardaClm(0b00011001);
GuardaClm(0b01111111);
GuardaClm(0b01100110);
break;

case('T'):
GuardaClm(0b00000011);
GuardaClm(0b00000001);
GuardaClm(0b01111111);
GuardaClm(0b01111111);
GuardaClm(0b00000001);
GuardaClm(0b00000011);
break;
}
GuardaClm(0b00000000);