Autor Tema: Sentencia printf  (Leído 4693 veces)

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

Desconectado neocommandos

  • PIC10
  • *
  • Mensajes: 25
Sentencia printf
« en: 26 de Octubre de 2004, 18:04:00 »
       Hola foro
tengo una duda...estoy realizando un reloj usando para ello el timer0, y a la hora de visualizar el tiempo, necesito que en el lcd aparezca un ancho de campo de 2. De forma que aun cuando la variable que almacena los segundos, sean 7, en el lcd aparezca 07, y no 7. Estoy usando para ello la sentencia printf de esta forma

printf(lcd_puts,"%2d",segundos);

 pero no funciona, ya que en caso de ser 7, lo que hace es añadirme un espacio en blanco.

Hay alguna forma directa de hacerlo, mediante algun modificador de printf?
sino supongo que habria construir algun codigo para diferencia cuando es menor mayor de 9, no?

Gracias de antemano.

Desconectado wqtrp

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 170
RE: Sentencia printf
« Respuesta #1 en: 26 de Octubre de 2004, 18:12:00 »
agregale un 0 despues del % y antes del 2 y todo lindo

suerte

Desconectado neocommandos

  • PIC10
  • *
  • Mensajes: 25
RE: Sentencia printf
« Respuesta #2 en: 26 de Octubre de 2004, 19:12:00 »
Que rapidez!

Probe eso antes, y me daba un fallo, por eso pense que lo hacia mal, pero ya he trasteado y si el modificador es como tu dices.

Pero cuando realizo el codigo que te indico abajo, me aparece por ejemplo

00:000:00:25

donde 25 son los segundos, los 00 situados a su izquierda los minutos, y todo lo anterior 00:000 no se porque sale.

Ademas, el reloj atrasa una barbaridad, en 2 minutos, ya se retrasa del orden de segundos y tampoco veo el porque.

Aqui adjunto el codigo....


/*//////////////////////////////////////////////////////////////////////////////
     Este programa es un reloj con formato 24 horas que se muestra en
     el LCD. Para el reloj se ha utilizado el temporizador TMR0.
//////////////////////////////////////////////////////////////////////////////*/


#include    <16F877A.H>                 /* tipo de PIC */
#include    <lcd.c>

#use        delay( clock = 4000000 ) /* reloj de 4 MHz */
#fuses      XT,NOWDT,NOPROTECT,PUT,NOBROWNOUT,NODEBUG,NOLVP,NOCPD
#use        fast_io(B)

//#include    <Rutinas.h>


char cuenta_interrupciones=0;
char segundo=0;
char minuto=0;
char hora=0;


#int_rtcc
void interrupt(void)
{
   cuenta_interrupciones++; // Incrementa la variable que cuenta las
                            // interrupciones

   if(cuenta_interrupciones==250)    // Si la cuenta ha llegado a 250 ha
                                      // pasado 1 segundo
   {
      cuenta_interrupciones=0;
      segundo++;

   }

   if(segundo>59)
   {
      segundo=0;
      minuto++;
   }

   if (minuto>59)
   {
      minuto=0;
      hora++;
   }

   if (hora>23)
      hora=0;

   set_rtcc(0x06);          // interrupciones y recarga el timer

}



void main( void )
{
   lcd_init();

   setup_counters (RTCC_INTERNAL, RTCC_DIV_16); // Programacion TMR0
   set_timer0(0x06);                            // Carga el valor del timer0

   enable_interrupts(INT_RTCC);                 // Habilita interrupcion TMR0
   enable_interrupts(GLOBAL);                   // Habilita las interrupciones


   while(1)
   {

      lcd_gotoxy(5,1);         // Posiciona el cursor del LCD en dicha posicion
      printf(lcd_puts,"%02d",hora);
      lcd_putc(":");
      printf(lcd_puts,"%02d",minuto);
      lcd_putc(":");
      printf(lcd_puts,"%02d",segundo);
   }

}




Desconectado oshow

  • PIC18
  • ****
  • Mensajes: 321
RE: Sentencia printf
« Respuesta #3 en: 27 de Octubre de 2004, 03:54:00 »
Hola neocommandos, he probado tu código y salvo algunos fallos a la hora de compilar funciona perfectamente, la forma de mostrar el reloj es tal y como tú preguntas, que ponga un cero delante del dígito si éste es menor de 10.

Te pasteo el código modificado. Lo único que no he comprobado es la precisión de la interrupción, pero lo que preguntas (la visualizacion del reloj) es como quieres que sea.

Codigo:

#include <16F877A.H> /* tipo de PIC */
#use delay( clock = 4000000 ) /* reloj de 4 MHz */
#include <lcd.c>
#fuses XT,NOWDT,NOPROTECT,PUT,NOBROWNOUT,NODEBUG,NOLVP,NOCPD
#use fast_io(B)

//#include <Rutinas.h>


char cuenta_interrupciones=0;
char segundo=0;
char minuto=0;
char hora=0;


#int_rtcc
void interrupt(void)
{
   cuenta_interrupciones++; // Incrementa la variable que cuenta las
   // interrupciones

   if(cuenta_interrupciones==250) // Si la cuenta ha llegado a 250 ha
   // pasado 1 segundo
      {
         cuenta_interrupciones=0;
         segundo++;

      }

   if(segundo>59)
      {
         segundo=0;
         minuto++;
      }

   if (minuto>59)
     {
         minuto=0;
         hora++;
     }

   if (hora>23)
      hora=0;

   set_rtcc(0x06); // interrupciones y recarga el timer

}



void main( void )
{
   lcd_init();

   setup_counters (RTCC_INTERNAL, RTCC_DIV_16); // Programacion TMR0
   set_timer0(0x06); // Carga el valor del timer0

   enable_interrupts(INT_RTCC); // Habilita interrupcion TMR0
   enable_interrupts(GLOBAL); // Habilita las interrupciones


   while(1)
   {

      lcd_gotoxy(5,1); // Posiciona el cursor del LCD en dicha posicion
      printf(lcd_putc,"%02u",hora);
      lcd_putc(":");
      printf(lcd_putc,"%02u",minuto);
      lcd_putc(":");
      printf(lcd_putc,"%02u",segundo);
   }

}



Saludos.

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2569
RE: Sentencia printf
« Respuesta #4 en: 27 de Octubre de 2004, 05:19:00 »
Como Oshow ha comprobado el código que pegaste tenía errores ¿no entiendo como pudiste comprobar el funcionamiento con estos errores?

Cuidado con los retrasos: la recarga del TMR0 hazla al entrar en la interrupción, no al salir.

Desconectado wqtrp

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 170
RE: Sentencia printf
« Respuesta #5 en: 27 de Octubre de 2004, 07:05:00 »
hola, si como dice pocher, debe mover la instruccion de recarga del timer a inicio de la int., ( y deberia ser lo primero)
asi y todo no podras solucionar el problema de la precicion y sera bastante, calculo q del orden del 1%
el primer problema es q estas usando un divisor de prescaler, con lo cual nunca podras ajustarla lo suficiente, la mejor condicion q llegaras sera de 16/4000 q es un 4 por mil


dependiendo del pic, deberias usar algo tipo el modulo de PWM para q el mismo micro haga la recarga del timer y entonces si, seras completamente feliz ..... ja

suerte....


Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2569
RE: Sentencia printf
« Respuesta #6 en: 27 de Octubre de 2004, 08:00:00 »
Completamente de acuerdo, se me había pasado.

Otras causas de retrasos:

Al entrar en la interrupción se gastan microsegundos (malo)

Al utilizar la función de recarga del timer se gastan microsegundos (malo)

Desconectado neocommandos

  • PIC10
  • *
  • Mensajes: 25
RE: Sentencia printf
« Respuesta #7 en: 27 de Octubre de 2004, 16:40:00 »
   Hola a todos,
ciertamente habia fallos, despiste mio alguno, aunque realmente funcionaba.
He vuelto a probar el codigo que me mandastes oshow, gracias. Ciertamente como habeis dicho pocher y wqtrp  aun poniendo la recarga del timer al principio, el retraso aun es bastante grande,asi que probare otra cosa. Y aun me sigue apareciendo en la pantalla ceros de mas, por ejemplo si han transcurrido 25 segundos, me apareceria esto en el lcd:


00:000:00:25



Lo del PWM para que haga la recarga del timer en que consistiria la idea, wqtrp? no acabo de entenderlo...

Gracias a todos por vuestra ayuda.

Desconectado cucaracha

  • PIC24H
  • ******
  • Mensajes: 1409
    • CUCAWEB
RE: Sentencia printf
« Respuesta #8 en: 27 de Octubre de 2004, 16:58:00 »
Noooooooooooo!!! mi@ otra vez me pilló!!!desquiciado
Bueno... repito.

Te es más fácil usar un cristal adecuado para esos menesteres... Cuales. Pues aquellos que dividiendo entre 256 resulte un número entero.
Recuerdas esos cristales usados en los RTC... 32,768KHz. Pues mira 32768/256=128, osea, numerito entero... Que casualidad!!Muchas risas
Pues eso... busca cristales que sigan esa regla...
3.276.800Hz (3,2768Mhz) por ejemplo. Esta no es una frecuencia que me haya sacado de la manga ni nada de eso... hay muchas, que precisamente son para este uso, para que generen bases de tiempo en segundo mediante timers. Hay muchos.
Mira por ejemplo en www.micropik.com en cristales y verás...
Por cierto... este tema de los cristales ya ha sido tratado varias veces en el foro por si te interesa...

Saludos!!

PD: a ver... copiar texto..... ahora no me pillas mi@!!!
Saludos desde Huelva (ESPAÑA)

Desconectado wqtrp

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 170
RE: Sentencia printf
« Respuesta #9 en: 27 de Octubre de 2004, 18:04:00 »
como ha derivado esto , de un printf a optimizar un reloj.....ja

bueno, vamos por partes, segun el ejemplo usas el f877, fijate en el data sheet en el timer 2 como se puede utilizar y veras q pones un valor en un registro y automaticamente cuando el timer llega a ese valor, genera una int. y ademas repone el valor nuevamente, tofo esto sin utilizar ciclos de pic.

pero sin duda la solucion de cucaracha es la mejor para un reloj, utilizas el timer 1 con un cristal externo, eso chiquitos q parecen un tubito y q estan por todos lados, (en lo relojes sobre todo) q son de muy baja frecuencia, generalmente 32768Hz y al pic lo haces oscilar con un RC nomas, para q mas, si la presicion te la da el otro cristal...

excelente lo de cuca.... y nosotros enterrados con los ciclos.....

suerte

Desconectado oshow

  • PIC18
  • ****
  • Mensajes: 321
RE: Sentencia printf
« Respuesta #10 en: 27 de Octubre de 2004, 22:17:00 »
Volviendo al tema de la visualización... ahora mismo no se porque te salen todos esos ceros, yo he usado ese especificador de formato con varios relojes y me ha funcionado a la perfección, no sé, prueba a borrar el lcd antes de que imprima nuevos datos cada segundo, a ver si consigues solucionar algo así.

De todas formas he simulado el código en proteus y funciona perfectamente, se visualiza bien.... no se me ocurre nada por lo que te puedan salir todos esos ceros... podría ser tu versión del compilador??? no sé que decir....a mí, el código que te he puesto en cuanto a visualización funciona perfectamente...

Saludos.

Desconectado neocommandos

  • PIC10
  • *
  • Mensajes: 25
RE: Sentencia printf
« Respuesta #11 en: 28 de Octubre de 2004, 19:30:00 »
Hola oshow, pues si estoy pensando que sea el compilador. Lo he simulado con el Proteus, y aparecen todos esos ceros de mas a excepcion de uno.

Lo de borrar la pantalla, tambien probe, pero no funciona, de hecho no se ve nada en la pantalla, aun poniendole retardos.

Voy a ver si consigo otra version de compilador.

Desconectado neocommandos

  • PIC10
  • *
  • Mensajes: 25
RE: Sentencia printf
« Respuesta #12 en: 03 de Noviembre de 2004, 18:51:00 »
           Hola a todos de nuevo,
ya probe el codigo con el compilador nuevo de duracion 30 dias de CCS, la version 3.212d y sigue haciendo lo mismo. Tambien probe a borrar el lcd, pero igualmente pasa lo mismo.

Tambien, lo he simulado de nuevo en Proteus, y siguen saliendo esos ceros de mas, solo que uno menos.

Oshow dices que has probado el mismo codigo en proteus, y no te aparecen los ceros, no?

La verdad es que ya no se que probar,...a alguien se le ocurre algo???



Desconectado kruskal

  • PIC16
  • ***
  • Mensajes: 108
RE: Sentencia printf
« Respuesta #13 en: 03 de Noviembre de 2004, 20:37:00 »
IdeaIdeaIdeaIdeaIdea

Te recomiendo que uses un reloj de tiempo real (RTC), puede ser un I2C DS1307 o uno con serial con clock DS1302. No se atrasan y ademas de darte la hora al segundo puedes tener la fecha dia:mes:año:dia de la semana.

hace tiempo intente hacer un reloj fue un completo fracaso por mas que intente, se atrasa o incluso se adelanta de muy mala calidad el resultado.
El PCW tiene librerias muy transparentes que hacen muy facil usar un RTC, sin dudas se te acabaran los problemas cuando uses uno.

Salud2 y Suerte.


Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2569
RE: Sentencia printf
« Respuesta #14 en: 04 de Noviembre de 2004, 03:09:00 »
Si quieres hacer un reloj con un PIC la mejor solución es la que apuntó Cuca, usando un cristal de 3,2768 MHz por ejemplo. Con un preescaler de 128 conseguirás que se desborde cada 1s (sin recargar el TMR0, que se pierden valiosos us).

Y para arañar más us, no lo hagas por interrupción, hazlo detectando en el while la activación del bit T0IF.

Por supuesto otra solución es con un RTC.

Un saludo


 

anything