Control de Matriz Estática

Este programa sirve para demostrar el control de una matriz de 5x7 de forma estática, se crearon 8 letras en el estándar ASCII para matrices de 5x7, la palabra escrita es "ELECTGPL " se puede modificar por cualquier letra o bien agregarle mas o quitarle algunas.
El programa se realiza en dos etapas, la principal donde se realiza el multiplexado de las columnas y se muestran los valores de cada fila a una velocidad de 10ms y la interrupción por desbordamiento del timer, dentro de la interrupción se alojan los caracteres dentro de un switch el cual servirá para ir cambiando entre cada letra, ya que al final de cada caso tiene un contador "letra++" el cual será el valor a testear por el switch, a medida que se recorra cada una de las 5 columnas se incrementara en 1 la variable letra, de esta forma pasara al siguiente paso, por consiguiente la siguiente letra, la ultima letra en lugar de incrementar en 1, iguala a cero la variable letra, entonces comenzara de nuevo.
El tiempo esta dado por set_timer1(1000), es totalmente configurable a gusto del desarrollador.
Como el circuito utilizado es el más sencillo posible para que se encienda un Led debe existir un 1 y un 0 de cada lado de la matriz, se podría haber usado el selector de columnas como 0b11111110, 0b11111101, etc... Pero para comprenderlo fácil se utilizo un 1 donde se quiere encender, para que no salga la letra negada en la matriz se utilizo el operando "~" delante del vector de las filas, de esta forma complementa el valor de la variable para que se vea correctamente.
Para utilizar más columnas debería utilizarse mas salidas, como podemos imaginarnos, podríamos hacer una matriz de 8x8 con dos puertos del PIC, pero se puede hacer más grande implementando registros de desplazamiento serie/paralelo, como el 74164, 74595, 4094, etc... Estos integrados reciben los datos de las columnas de forma serial y lo despliegan en paralelo en sus salidas, los mismos se pueden concatenar para hacer matrices más grandes, estos integrados se controlan mediante un Clock de sincronismo, un Dato donde se enviaran los valores seriales, y un Reset que pondrá el puerto paralelo de los registros a ceros.




#include <16f883.h>
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP,NOMCLR,INTRC
#use delay (int=4000000)
int fila[5],letra=0;
#INT_TIMER1
void isr()
{
   switch(letra){
      case 0: fila[0]=0b01000001;
              fila[1]=0b01000001;
              fila[2]=0b01001001;
              fila[3]=0b01001001;
              fila[4]=0b01111111;
              letra++;
              break;
      case 1: fila[0]=0b00000001;
              fila[1]=0b00000001;
              fila[2]=0b00000001;
              fila[3]=0b00000001;
              fila[4]=0b01111111;
              letra++;
              break;
      case 2: fila[0]=0b01000001;
              fila[1]=0b01000001;
              fila[2]=0b01001001;
              fila[3]=0b01001001;
              fila[4]=0b01111111;
              letra++;
              break;
      case 3: fila[0]=0b01000001;
              fila[1]=0b01000001;
              fila[2]=0b01000001;
              fila[3]=0b01000001;
              fila[4]=0b00111110;
              letra++;
              break;
      case 4: fila[0]=0b01000000;
              fila[1]=0b01000000;
              fila[2]=0b01111111;
              fila[3]=0b01000000;
              fila[4]=0b01000000;
              letra++;
              break;
      case 5: fila[0]=0b00000110;
              fila[1]=0b01001001;
              fila[2]=0b01001001;
              fila[3]=0b01000001;
              fila[4]=0b00111110;
              letra++;
              break;
      case 6: fila[0]=0b00110000;
              fila[1]=0b01001000;
              fila[2]=0b01001000;
              fila[3]=0b01001000;
              fila[4]=0b01111111;
              letra++;
              break;
      case 7: fila[0]=0b00000001;
              fila[1]=0b00000001;
              fila[2]=0b00000001;
              fila[3]=0b00000001;
              fila[4]=0b01111111;
              letra++;
              break;
      case 8: fila[0]=0b00000000;
              fila[1]=0b00000000;
              fila[2]=0b00000000;
              fila[3]=0b00000000;
              fila[4]=0b00000000;
              letra = 0;
              break;
     }
     set_timer1(1000);

}
void main(void)
{
   enable_interrupts(INT_TIMER1);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
   set_timer1(65535);
   enable_interrupts(GLOBAL);
   set_tris_c(0x00);
   set_tris_a(0x00);
   while(TRUE){
      output_a(0b00000001);
      output_c(~fila[0]);
      delay_ms(10);
      output_a(0b00000010);
      output_c(~fila[1]);
      delay_ms(10);
      output_a(0b00000100);
      output_c(~fila[2]);
      delay_ms(10);
      output_a(0b00001000);
      output_c(~fila[3]);
      delay_ms(10);
      output_a(0b00010000);
      output_c(~fila[4]);
      delay_ms(10);
   }
}


32 comentarios:

  1. capo! sos un groso yaa ando jugando a full, escribiendo frases y todo! exelente tuto :D

    ResponderBorrar
  2. chee capo consulta podes hacer q en vez q encienda y apaguen los led's formando las letras,podes hacer q se desplacen??

    ResponderBorrar
    Respuestas
    1. Hola!, estoy con un poco de carga laboral ultimamente, pero voy a ver si me puedo hacer un rato para crear un nuevo post sobre el Scrolling/Frames.
      Saludos!

      Borrar
  3. Hola que tal!!... sebastian y para juntar las 8 letras del la palabra ELECTGPL(por ejemplo) y en vez de cambiarlas en la misma matriz hacer un letrero juntando las demas matrices... es posible hacerlo? De antemano Gracias.

    ResponderBorrar
    Respuestas
    1. Hola como estas?, para ampliar el tamaño de la matriz es necesario utilizar registros de desplazamiento, por ejemplo el 74164, de esa forma se puede expandir (esto es para expandir el puerto, ya que el microcontrolador posee pocos pines como para manejar varias matrices). http://electgpl.blogspot.com.ar/2013/10/registro-de-desplazamiento-74164-con-ccs.html
      Saludos.

      Borrar
    2. Muchas Gracias por tu pronta respuesta, aun no he realizado mi proyecto por falta de tiempo, pretendo realizarlo con arduino y lo que quiero hacer es un letrero estático de n dimensión con matrices 5x7 concadenadas entre si, ya tengo claro lo de los registros de desplazamiento pero tengo duda en como mandar la cadena completa para que se despliegue. de antemano Muchas Gracias.

      Borrar
    3. Hola, tenes que realizar un array con las matrices, por ejemplo si tenes 3 matrices de 5x7 tendrías que conectarlas tal que formes una única matriz de 15x7, después el modo de funcionamiento es el mismo que en este circuito. El inconveniente es que te quedarías sin pines en el puerto para manejar las 15 columnas, para ello te recomendaría un registro de desplazamiento serial, por ejemplo el 74164, aquí podes ver un pequeño programa para manejarlo: http://electgpl.blogspot.com.ar/2013/10/registro-de-desplazamiento-74164-con-ccs.html

      Borrar
    4. Entonces utilizando el programa de este post más el que te mencione recién en el link, podría expandir a una matriz de mayor longitud estática. Decime que te parece y si queres lo vemos.
      Saludos.

      Borrar
  4. podrias compilarlo para un 16f877a en hex

    ResponderBorrar
    Respuestas
    1. :1000000000308A00B6280000FF00030E8301A10023
      :100010000A08A0008A010408A2007708A300780853
      :10002000A4007908A5007A08A600831383128C30F7
      :100030008400001C1D280C182E2822088400230888
      :10004000F7002408F8002508F9002608FA0020081F
      :100050008A00210E8300FF0E7F0E09008A110A120A
      :1000600031282C08F73E03188C28093E942841308B
      :10007000A700A8004930A900AA007F30AB00AC0A55
      :100080008C280130A700A800A900AA007F30AB008F
      :10009000AC0A8C284130A700A8004930A900AA006A
      :1000A0007F30AB00AC0A8C284130A700A800A90023
      :1000B000AA003E30AB00AC0A8C284030A700A80054
      :1000C0007F30A9004030AA00AB00AC0A8C28063073
      :1000D000A7004930A800A9004130AA003E30AB007B
      :1000E000AC0A8C283030A7004830A800A900AA002C
      :1000F0007F30AB00AC0A8C280130A700A800A90013
      :10010000AA007F30AB00AC0A8C28A701A801A90186
      :10011000AA01AB01AC018C2803308F00E8308E00BF
      :100120000C108A110A121D280A108A100A1182075F
      :10013000372841284A2854285D28672872287C28B7
      :1001400085282E308400831300080319B528013058
      :10015000F800F701F70BAA28F80BA9284A30F70096
      :10016000F70BB028B328800BA7280800840183135D
      :100170001F308305AC0183161F149F141F159F1198
      :1001800007309C00FF308312AD0083160C14B5308D
      :1001900083129000FF308F008E00C0308B0400303F
      :1001A000831687008312AD00831685008501013018
      :1001B000831285002708AE00AE090030AD0083161B
      :1001C000870183122E0887000A30AE00A120831613
      :1001D00085010230831285002808AE00AE09003088
      :1001E000AD008316870183122E0887000A30AE0007
      :1001F000A120831685010430831285002908AE00F2
      :10020000AE090030AD008316870183122E088700E7
      :100210000A30AE00A12083168501083083128500C4
      :100220002A08AE00AE090030AD00831687018312A4
      :100230002E0887000A30AE00A120831685011030F9
      :10024000831285002B08AE00AE090030AD00831686
      :10025000870183122E0887000A30AE00A120831682
      :04026000D628630039
      :02400E00713F00
      :00000001FF
      ;PIC16F877A
      ;CRC=C123 CREATED="25-ago-14 09:10"

      Borrar
    2. Ese es tu archivo Hex, para el 16F877A, tenes que pegar eso en un block de notas y guardarlo con el nombre que quiera .hex
      Saludos.

      Borrar
  5. Hola de nuevo, ya me encuentro realizando este proyecto en la simulación todo esta perfecto ya en físico tengo problemas con la matriz es 5x7 TC07-11EWA pero a diferencia a la que sale en la simulación esta tiene configuración cátodo común en las columnas y ánodo común en los renglones, entonces las letras me salen invertidas y no funciona igual, ya intente invertir el funcionamiento de muchas formas y nada que podra ser?? de antemano Muchas gracias.

    ResponderBorrar
    Respuestas
    1. Hola, podes invertir la matriz como mencionas que hiciste, pero tambien quita el simbolo "~" de cada linea de salida en el puerto C, "output_c(~fila[0]);", ese simbolo hace swap en la variable fila, ejemplo: si fila = 00011000, anteponiendo el simbolo ~fila sera igual a 11100111, eso podria ayudar a tu matriz invertida.
      Saludos.

      Borrar
  6. Muchas gracias ya quedo listo. jamas había utilizado matriz de led por eso andaba un poco enredado.

    ResponderBorrar
    Respuestas
    1. Por nada, espero que te sirva el post!, Son un poco engorrosas las matrices pero una vez que le agarras la mano ya sale mas sencillo.

      Saludos.

      Borrar
  7. ¿brother el codigo que utilizas es c++?

    ResponderBorrar
  8. ¿Brother el codigo que has utilizado es en c++?

    ResponderBorrar
  9. Buen dian alguien me podria decir como se genera el codigo de cada letra

    ResponderBorrar
    Respuestas
    1. Buen dia, como estas?,
      Tal vez te sirva este enlace, http://blog.riyas.org/2013/12/online-led-matrix-font-generator-with.html
      Es para generar el valor codificado correspondiente a cada columna o fila de la matriz.
      Saludos!

      Borrar
  10. Thank you this was very helpful tutorial compare to other webs my problem is what can i do if i want to put more character or reduce character which modification can i do?thank you

    ResponderBorrar
    Respuestas

    1. Hello, characters are created directly in each vector in the case of the switch function, none is the best way to do this, if you want you can analyze any of the other programs that are available on the blog where the LED array is. Anyway if you want you can change each of the bits of each vector and thus change the font and phrase. Regards!

      Borrar
  11. disculpa en que programa estas trabajando la matris
    yo lo nesecito para pic16887 pero estoy usando (PIC similador IDE)

    ResponderBorrar
    Respuestas
    1. Hola, están compilados con CCS http://www.ccsinfo.com/ccsfreedemo.php
      Saludos.

      Borrar
  12. una pregunta ,bueno yo estoy haciendo un proyecto que se basa en generar un letra en la matriz de leds por medio de la multiplexacion pero el envio de señales ala matriz lo debo hacer por puerto paralelo y la programacion lo estoy haciendo en turbo c ,y bueno me gustaria que me ayudaras respondiendo unas preguntas porfavor
    1)cuando intente encender un led solo uno no se enciende el codigo que use es este
    #include
    #include
    #include
    void main()
    {
    clrscr();
    outport(0x378,0);//todo apagado
    outport(0x378,128);//salida por el pin 9
    delay(5000);//tiempo de encendido 5 seg
    outport(0x378,0)//todo apagado
    getch();
    }
    bueno el programa compila sin ningun error pero veo atras y no enciende talvez sea un problema de falso contacto...
    2)con respecto ala multiplexacion que haria la negacion que tengo que hacer al outport seria !outport(o no porque creo que solo se usa eso en variables de tipo bool).
    3)tal vez sea un problema del puerto pero verifique en windows y me dice todo ok que funciona correctamente.entonces yo me preguntaba si estaba bien o de que otra manera confirmo que esta bien el puerto.
    4)estoy que veo tambien en el dev-c++(5.11) y descarge un imput.dll para poder creo yo usar los comandos para el envio de señales.pero cuando use outport y delay o sleep para el tiempo de encendido no reconoce dichos comandos porque sera problema de librerias cual tendria que usar ?.
    5)o talvez seria un problema de voltaje talvez el voltaje que vota el puerto no es lo suficiente para el led porque no creo que sea demasiado mis leds no sean quemado para nada
    bueno eso era lo que queria decir talvez esta fuera del tema del post con respecto al puerto paralelo pero gracias de antemano me gusto tus post esta bacan ...
    Muchas gracias¡¡

    ResponderBorrar
    Respuestas
    1. una consulta mas creo que si funciona porq que cuando puse el led ahora con una resistencia encendio poquisimo pero fue cuando aun no compile mi programa(lol) que es lo que estaria pasando gracias de ante mano

      Borrar
    2. Hola, la verdad que no sabria decirte sobre la programacion en PC, para puerto paralelo, esto esta realizado sobre microcontrolador, es un sistema embebido.
      El tema del multiplexado habria que verlo porque nose que velocidad de instruccion tiene el programa que estas haciendo en la PC, tal vez sea lento por el manejo del puerto y no funcione bien el multiplexado.
      Saludos.

      Borrar
  13. Hola Seba , en lenguaje asembler tenes idea como seria,gracias

    ResponderBorrar
    Respuestas
    1. Hola, si pero no lo tengo realizado en ASM ahora. Pero básicamente es leer una tabla de datos, por ejemplo con la instrucción "Tabla addwf PCL,F" donde vas incrementando el contador de programa y vas buscando luego cada literal con la instrucción "retlw + el valor de tabla" Pero no lo tengo echo.
      Saludos.

      Borrar