Autor Tema: reloj codificado  (Leído 2922 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Garbanzo

  • PIC10
  • *
  • Mensajes: 13
reloj codificado
« en: 28 de Octubre de 2016, 03:06:23 »
hola :)
quería pedir consejos con un pequeño proyecto que estoy haciendo se trata de una matriz de led casera de 5x8
que básicamente es un reloj pero en lugar de mostrar la hora con números la muestra en codigo con diferentes
combinaciones de leds encendidos  este es mi programa:

#include <16f886.h>
#fuses hs,nowdt,noprotect,noput
#use delay (clock=4M)
#byte portc=0x07
#byte trisc=0x87
#byte portb=0x06
#byte trisb=0x86
int horas=0, minutos=0, segundos=0,cuenta,suma;
int const n12[5]={0b01111110,0b01111011,0b11111111,0b11111111,0b11111111};
#int_timer1
void timer_1()
{
cuenta++;
if(cuenta==2){segundos=segundos+1;cuenta=0;}
if (segundos==59){minutos=minutos+1;segundos=0;}
if (minutos==59){horas=horas+1;minutos=0;}
if(horas==12){horas=0;}
suma=horas+minutos;
set_timer1(3036);
}

void main()
{

set_tris_b(0b00000000);
set_tris_c(0b00000111);
setup_timer_1(t1_internal|t1_div_by_8);
set_timer1(3036);
enable_interrupts(int_timer1);
enable_interrupts(global);

while(true)
{
switch(suma)
{
case 0: output_c(0b10000000);
      output_b(n12[0]);
      delay_ms(1);
      output_c(0b01000000);
      output_b(n12[1]);
      delay_ms(1);
      output_c(0b00100000);
      output_b(n12[2]);
      delay_ms(1);
      output_c(0b00010000);
      output_b(n12[3]);
      delay_ms(1);
      output_c(0b00001000);
      output_b(n12[4]);
      delay_ms(1);
      break;
}
}


lo que hice fue usar un timer configurado con un tiempo de .5 segundos y lo desbordo 2 veces con la variable cuenta
para tener un tiempo de 1 segundo después en la interrupción los if son los que llevan la cuenta de las horas minutos
y segundos como un reloj normal.
La variable int const n12[5]={0b01111110,0b01111011,0b11111111,0b11111111,0b11111111}; son los datos
para sacar en la matriz el código (inventado por mi)para saber que son las 12:00 y en la variable "suma",
sumo las horas + los minutos  y según el resultado despliego con un switch la hora que equivale a ese resultado
espero haberme explicado por ejemplo el programa empieza con las 12:00 am que para la cuenta del timer son las
0:00 entonces el programa suma 0+0=0 y el case 0 de la función switch muestra los datos para las 12:00 si tuviera que mostrar
las 4:25 sumaria 4+25=29 y el case 29 serian los datos para las 4:25
Bueno el programa funciona bien pero la forma en que lo hice implica un código colosal ya que serian 1440 datos(int const)
para todas las 24 horas mas otros 1440 "case" de la función switch para despegarlos en la matriz osea un código con mas de 2880 lineas

Quería pedir consejo para hacerlo mas corto se me ocurrió poner los datos de todas las horas así:
int const 12[5]={0b01111110,0b01111011,0b11111111,0b11111111,0b11111111};}
etc
etc
etc
etc
y ligar el resultado de la variable suma con el nombre de la variable int const (nombre) que en ese caso es 12 esto me ahorrria la mitad
del programa
porque ya no utilizaría la función switch con todos sus case solamente esto:

      output_c(0b10000000);
      output_b(suma[0]);
      delay_ms(1);
      output_c(0b01000000);
      output_b(suma[1]);
      delay_ms(1);
      output_c(0b00100000);
      output_b(suma[2]);
      delay_ms(1);
      output_c(0b00010000);
      output_b(suma[3]);
      delay_ms(1);
      output_c(0b00001000);
      output_b(suma[4]);
      delay_ms(1);
      break;

esto utiliza "suma" ligada al nombre de los datos de la hora para mostrar todas las horas el problema es que no se
como hacer esto (que este ligada la variable suma con el nombre del int const) y aparte no me permite ponerle de nombre
un numero al int const por eso mi programa dice int const n12 en vez de int const 12
espero haberme explicado bien
Gracias por su tiempo y sus respuestas  :P


Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:reloj codificado
« Respuesta #1 en: 28 de Octubre de 2016, 08:52:50 »
Primero tenes un error aca:

Código: C
  1. if(cuenta==2){segundos=segundos+1;cuenta=0;}
  2. if (segundos==59){minutos=minutos+1;segundos=0;}
  3. if (minutos==59){horas=horas+1;minutos=0;}
  4. if(horas==12){horas=0;}

Reemplaza los if de los segundos, minutos por esto:

Código: C
  1. if(cuenta==2){segundos=segundos+1;cuenta=0;}
  2. if (segundos > 59){minutos++;segundos=0;}
  3. if (minutos > 59){horas++;minutos=0;}
  4. if(horas==12){horas=0;}

Sino tendrias 00:58 todo OK, cuando sume uno mas y que deberia mostrar 00:59 no lo hace, por que se cumple la condicion y se pasaba a 01:00

-----------

Lo que vos queres hacer es justamente lo que se hace...
Al final de calcular y arreglar la hora, lo que haces es pasar los numeros a BCD, es decir si tenes el numero 48, como salida deberias tener 4 y 8.

Y aca vienen las posibilidades.
Los numeros como los minutos/segundos son siempre 59 o menos, las horas son de 0 a 11 o 0 a 23.

Lo podes hacer de 2 formas, es si es una division por 10, usando la operacion modulo % y la otra es restando sucesivamente 10 hasta que queden solo las unidades.

Código: C
  1. // Con el operador modulo
  2. decena_hora = horas % 10;
  3. unidad_hora = horas - (decena_horas * 10 );
  4. decena_minutos = minutos % 10;
  5. unidad_minutos = minutos - (decena_minutos * 10 );
  6.  
  7. // Con restas sucesivas
  8. for( decena_horas = 0; horas >= 10; decena_horas++, horas-=10)
  9. unidad_horas = horas;
  10. for( decena_minutos = 0; minutos >= 10; decena_minutos++, minutos-=10)
  11. unidad_minutos = minutos;


La diferencia esta en la velocidad, es mucho mas facil restar para el micro que multiplicar. A no ser que tengas un multiplicador de hardware. Ahora si no te interesa lo que tarde podes usar el modulo. Por si no se entiende el for es: Primero pongo el valor decenas_horas en 0, Mientras horas es mayor o igual que 10 (es decir que puedo restar) aumento en 1 a decenas_horas y resto 10 a horas. Cuando llegue al punto que sea menor que 10, es decir de 0 a 9, solo me queda las unidades en horas.
Obviamente esto es un codigo para 0 a 99, para horas que era de 0 a 12, podria habre preguntado si era mayor igual a 10, y ahi restarle con un if, pero si por algun motivo cambias el formato a 0 a 23, tendrias que arreglar el if, con esto sigue siendo valido.

Esto lo haces ANTES de mostrar. FUERA de la interrupcion. Luego si, si tenes la hora 05:34 vas a tener que enviar uno por uno, es decir primero el 0, luego el 5, luego el : , etc
« Última modificación: 28 de Octubre de 2016, 08:57:20 por KILLERJC »

Desconectado Garbanzo

  • PIC10
  • *
  • Mensajes: 13
Re:reloj codificado
« Respuesta #2 en: 01 de Noviembre de 2016, 04:35:58 »
Hola KILLERJC gracias por responder y por la corrección de los if ,pero no lo entendí bien lo que planteaste después
que logro al convertir la hora a bcd y pasar todo a unidades? y como ligo esto a mis datos de las horas para mostrarlos
en la matriz y creo que esto ocasiona otro problema ya que al final dices que tendría que mostrar todos los números por
separado pero los (int const) que utilizo encienden la matriz de led con el código de la hora completa no por separado
si entendí todo mal te agradecería me lo explicaras un poco mas detallado ya que no llevo mucho tiempo en la programación
gracias.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:reloj codificado
« Respuesta #3 en: 01 de Noviembre de 2016, 08:53:34 »
Y depende como hagas el barrido de tu matriz... Ademas yo me equivoque en no mostrarte de forma mas sencilla que podes ponerlo en una matriz

Vos deberias tener un par de constantes que formen cada numero. Voy a hacer un emjemplo con el 0, siendo que cada numero ocupa 5x5, En este ejemplo el 0 seria:

Código: [Seleccionar]
0b11111
0b10001
0b10001
0b10001
0b11111

Tambien voy a suponer que si tengo una matriz en la cual el espacio horizontal es mayor que el vertical, los datos que deben cargarse van a ser por filas. Es decir si tengo el valor: 01:00
Deberia enviar la primer fila del 0, la primer fila del 1, la primer fila del :, y luego 2 veces mas la primer fila del 0. Luego de que termine esta fila procedo a la siguiente.
Enviando la segunda fila del 0, la segunda del 1, la segunda del :, la segunda del 0, 2 veces por los 2 ceros.

Es decir, voy cargando los valores desde izquierda a derecha y de arriba hacia abajo.

Entonces Yo teniendo separado cada numero 0,1,0,0 puedo aplicar un loop.

Código: C
  1. //Constantes de los numeros
  2. const uint8_t BCD_A_Matriz[11][5] = {
  3.                                         {0b11111, 0b10001, 0b10001, 0b10001, 0b11111},          // El 0
  4.                                         {0b00001, 0b00001, 0b00001, 0b00001, 0b00001},          // El 1
  5.                                         // aca los demas, usar el 10 para el ':'
  6.                                 };
  7.  
  8. // Variable que tiene la hora a mostrar
  9. uint8_t Horario_Reloj[5] = {0,0,10,0,0};
  10.  
  11.  
  12.  
  13. // Primero convierto y guardo en un array, asi es mas facil hacer un loop
  14.  
  15. for( Horario_Reloj[0] = 0; horas >= 10; Horario_Reloj[0]++, horas-=10)
  16. Horario_Reloj[1] = horas;
  17. for( Horario_Reloj[3] = 0; minutos >= 10; Horario_Reloj[3]++, minutos-=10)
  18. Horario_Reloj[4] = minutos;
  19.  
  20.  
  21. // Comienzo el loop para mostrarlo
  22.  
  23. for(j=0;j<5;j++)        // 5 lineas cada dato
  24. {
  25.         for(i=0;i<5;i++)        // 5 datos, 0 , 1 , : , 0 , 0
  26.         {
  27.                 Enviar_A_Matriz(BCD_A_Matriz[Horario_Reloj[i]][j]);
  28.         }
  29. }

Suponete esto, el horario es 01:00 .. tenemos que:

Horario_Reloj[0] = 0
Horario_Reloj[1] = 1
Horario_Reloj[2] = 10
Horario_Reloj[3] = 0
Horario_Reloj[4] = 0

al llamar el primer Enviar_A_Matriz, i y j son 0.

Por lo tanto BCD_A_Matriz[0][0] me da la primer fila del 0. (Decenas de las horas)
En la proxima vuelta del for tenemos que BCD_A_Matriz[1][0] me da la primer fila del 1. (Unidades de las horas)
En la proxima vuelta del for tenemos que BCD_A_Matriz[10][0] me da la primer fila del ':'.  (Los 2 puntos, use el 10 asi poder ponerlo en la tabla junto a los numeros)
En la proxima vuelta del for tenemos que BCD_A_Matriz[0][0] me da la primer fila del 0. (Decenas de los minutos)
En la proxima vuelta del for tenemos que BCD_A_Matriz[0][0] me da la primer fila del 0. (unidades de los minutos)

Se termino mi primer fila  y pasaron las 5 primeras filas de cada numero como te habia comentado. Ahora si seguimos con el for.

En la proxima vuelta del for tenemos que BCD_A_Matriz[0][1] me da la segunda fila del 0. (Decenas de las horas)
etc...

Ves como puedo llevar todo simple a unos cuantos loops para mostrar en una matriz y no necesito muchos switch para cada numero. Simplemente necesito la representacion de cada elemento ( del 0 al 9 y el ':' ) y luego uso un array como es el Horario_Reloj para saber de que numero se trata y apuntar a la tabla de constantes o elementos

------------------------------------------------

Ahora si los datos que cargo son por columnas se aplica algo "parecido" pero deberiamos cambiar la tabla de constantes a un formato de columnas y no filas.
« Última modificación: 01 de Noviembre de 2016, 09:00:07 por KILLERJC »