You are on page 1of 5

Matriz de 8x8 LED controlada con 2 shift register y PIC

Muchas personas experimentan a diario con arrays de 8x8 LED y un porcentaje de esas personas reflejan sus dudas en distintos sitios desperdigados por la red destinados a este mundillo de la electrnica y los microcontroladores.

Etiquetas: 16F88, 74xx595, 8x8, C, CCS, Circuito, Conexin, cdigo, Diagrama, Electrnica, ISIS, LED, Matrix,M atriz, Microcontrolador, PIC, Proyecto, Robtica, Shift register, Simulacin

Precisamente de una duda que se me plante hace poco por correo electrnico surgi un pequeo proyecto a modo de ejemplo de un array de 8x8 LED; El cual funciona de maravillas tanto simulado como fsicamente y es por eso que lo publico en esta ocacin. Dicho proyecto est basado en una serie de artculos anteriores dedicados a los shift register, en otras palabras es una implementacin de los registros para usarlos con una matriz de LED. 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 R9-R16 Q1-Q8

8 x Resistencias de 220 8 x Resistencias de 3,9K 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> #fuses INTRC_IO,MCLR #fuses NOPUT,NOBROWNOUT #use fast_io(all) hace al principio. #use delay(clock=8M) #define #define #define #define char char int1 int1 Load Clk dClm dLin PIN_B0 PIN_B1 PIN_B2 PIN_B3 // // // // Tipo de microcontrolador Oscilador interno, MCLR activo Sin Brownout reset ni Power up timer La configuracin de los puertos solo se

// Velocidad del oscilador interno 8 MHz // // // // Load (STCP ambos integrados) B0 Clock (SHCP ambos integrados) B1 Data para las columnas (DS integrado 1) BC2 Data para las lineas (DS integrado 2) B3

Memoria[96]; Visor[8]; flag; flag2;

// 96 Bytes para la memoria (0 - 95) // 8 para el visor (8 columnas) // Flags de control

int indx; columnas. int line; int time; int ptime; int t;

// Indice donde almacenar las nuevas // // // // Linea que a mostrar. Variables para el control de la velocidad de desplazamiento. Variable auxiliar.

void CargaMem(char Ascii); void GuardaClm(char c); #int_rtcc void isr(){ int Mul=128; if(++line>7)Line=0; de 7 vuelve a 0. if(++ptime>5){ ptime=0; if(++time>200){ time=0; Flag=true; } } for(t=0;t<8;t++){ valor // del bit de la fila actual. if (Line==t)output_high(dClm); correspondiente else output_low(dClm); desactiva. // Si Line es igual a t // activa el bit // a la columna, sino lo

// Cada vez que ocurre la interrupcion // selecciona la siguiente linea, si se pasa // Suma 1 a ptime. Si se pasa de 20 // lo pone en 0 y suma 1 a time. // Si se pasa de 200 // lo pone en 0 // y activa el flag.

// Bucle 0 - 7 (Lineas) // dLin es seteado con el

output_bit(dLin,!!(Visor[Line]&Mul));

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; } flag=true;

// Limpia la memoria y el visor // Activo el flag para que cargue la memoria

setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); Timer0 enable_interrupts(int_rtcc); Timer0 enable_interrupts(global); globales do{ if (Flag){ flag2=true; for (k=0;k<8;k++){ 8 } for (k=0;k<95;k++){ memoria n=n+1...

// Configuracin del // Interrupcion por // Interrupciones

// Si el flag est activado // Activa el flag2 // Pasa el contenido de las primeras

visor[k]=Memoria[k]; // columnas en memoria al visor // Rota el contenido de toda la

Memoria[k]=Memoria[k+1];// a la izquierda 1=1+1, 2=2+1, if (Memoria[k]!=0){Flag2=false;} // Si hay alguna columna que no // est vaca desactiva el flag2 } Memoria[95]=0; memoria if (Flag2){ indx=7; CargaMem("PICROBOT"); } Flag=false; } }while (true); } void GuardaClm(char c){ if (indx<94){ Memoria[indx]=c; de memoria indx++; } } void CargaMem(char ascii){ deseado switch (ascii){ case('B'): GuardaClm(0b01111111); GuardaClm(0b01111111); GuardaClm(0b01001001); GuardaClm(0b01001001); GuardaClm(0b01111111); GuardaClm(0b00110110); // Si flag2 est activo // a partir de la columna 7 // escribe PICROBOT // Desactiva el flag // Limpia la ultima columna de la

// Bucle infinito

// Guarda la columna en la ubicacin actual // y aumenta el indice

// Carga la memoria con el caracter

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); }