TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: PabloFiscella en 27 de Noviembre de 2003, 14:59:00

Título: Precisión del reloj
Publicado por: PabloFiscella en 27 de Noviembre de 2003, 14:59:00
Hola a todos.

Estoy intentando hacer un temporizador.
Uso un cristal de 4Mhz y haciendo la cuenta 4000000/(4*256*256)
da 15.2 y pierdo precision.
Cada un minuto se adelanta aproximadamente 1 seg.
Que es lo que deberia hacer para hacer un reloj tatalmente preciso.
Cambiar el cristal?

Saludos. Gracias nuevamente.
Pablo.
Título: RE: Precisión del reloj
Publicado por: solid84 en 27 de Noviembre de 2003, 18:58:00
que tal yo te comento que si puedes cambiar el cristal por 1 de 4.096mhz

con el preescaler a 4 y usando la interrupcion del tmr0

tendras interrupciones cada 1milisegundo exactos esta es una buena base de tiempos saludos
Título: RE: Precisión del reloj
Publicado por: PabloFiscella en 28 de Noviembre de 2003, 08:19:00
Hola
Si uso el cristal de 4.096MHz que capacitores uso. (cambia en algo?)
Que es el prescaler 4?
Y por ultimo si podes decime que cuenta deberia hacer para sacar las repeticiones.
Esta era la cuenta que me daba con el cristal de 4MHz

#fuses XT,NOWDT
#use delay (clock=4000000)
#define INTS_PER_SECOND 15.2 // (4000000/(4*256*256))


Muchas gracias.
Saludos.
Pablo
Título: RE: Precisión del reloj
Publicado por: MGLSOFT en 28 de Noviembre de 2003, 08:44:00
El prescaler es un divisor que se puede asignar al Tmr0 o al WatchDog, uno por vez.
El Tmr0 desborda a la cuenta de 255, produciendo una interrupcion.
Si el prescaler esta en 4 entonces cada 4 instrucciones el timer avanza en uno, por lo cual el desborde es a 255 x 4 = 1020 microsegundos, equivalente a 1,02 milisegundos.
para que la interrupcion sea exacta debes poner el Tmr0 en 5 luego de cada interrupcion.
de todos modos influyen otras cosas, como por ejemplo si utilizas instrucciones de mas de un microsegundo el tiempo deriva, pero seria muy raro que te meta mucha diferencia en el tiempo deseado.
Título: RE: Precisión del reloj
Publicado por: cucaracha en 28 de Noviembre de 2003, 10:36:00
A ver si no me equivoco, que lo hago de memorieta.

La fórmula general puede ser:

t=(256-Recarga) * Preescalar * (4/Fcristal)

Osea, por ejemplo si tenemos un cristal de 4,096Mhz, el máximo que podremos temporizar  por cada interrupción será:

t=(256-0)*256*(4/4096000)=0.064segundos

Si por ejemplo quieres temporizar 1 segundo, pues tendrás que ir incremetado un registro cada, por ejemplo 50ms, que está dentro de máximo que puede contar el timer (64ms).
Por tanto tendrás que hacer una recarga de:

Recarga=256-(0.05*4096000)/(256*4)=56

Por tanto, con un cristal de 4.096MHz, escogiendo predivisor de 256 para el timer0 y haciendo una recarga de 56 tendrás una interrupción cada 50ms.
Ahora 1seg=50ms*20. Osea 20 interrupciones. Ahora pues coges un registro, lo cargas con el número 20 y lo vas decrementando cada interrupción y comprobando si llegó a cero. Cuando llegue a cero pues tienes tu preciado segundo. Vuelves a poner a 20 el registro y vuelta a empezar.
Ten en cuenta que las instrucciones también necesitan un tiempo en ejecutarse. Por lo que es error que se suma. Lo ideal es que cuando salte la interrupción, lo primero a hacer es realizar la recarga.

uff... ya está.

Saludos!
Título: RE: Precisión del reloj
Publicado por: pocher en 28 de Noviembre de 2003, 10:59:00
Yo utilizo para calcular el Valor a cargar en el TMR0 para una determinada temporización, la siguiente fórmula (cosecha propia):

Valor a cargar en TMR0=256 - (Temp · fosc) / (4 · Preescaler)

Yo creo que hay que poner 256, no 255 ya que el TMR0 produce la interrupción (se activa el flag) al  "pasar de 255", no al llegar a 255.

Con esta fórmula si usas una fosc=4MHz, Preescaler=4, Temp=1ms ---> Valor a cargar en TMR0 = 6

Con esta fórmula si usas una fosc=4,096MHz, Preescaler=4, Temp=1ms ---> Valor a cargar en TMR0 = 0

Un saludo

 
Título: RE: Precisión del reloj
Publicado por: cucaracha en 28 de Noviembre de 2003, 11:06:00
No me acuses de espionaje pocher
jejeje
Saludos!!
Título: RE: Precisión del reloj
Publicado por: pocher en 28 de Noviembre de 2003, 11:10:00
Caray Jimy el rápido a tu lado era una sombra. Me has ganado por un pelo.

Saludos Cuca.
Título: RE: Precisión del reloj
Publicado por: MGLSOFT en 28 de Noviembre de 2003, 12:13:00
Llevan razon ambos, el overflow es en 256, no en 255.
Pido mis disculpas a ambos, y con mas razon a Pablo si es que pude confundirlo...
Estaba y no me di cuenta de mi error, gracias por corregirme.

Se ve que al pasar de las cuatro decadas empezas a perder neuronas, je.. je..
Título: RE: Precisión del reloj
Publicado por: PabloFiscella en 28 de Noviembre de 2003, 13:30:00
Espero sepan disculpar pero no se realmente mucho del tema.
Estuve tratando de conseguir cristales de 4,096MHz pero solo consegui de 4MHz
Me podrian explicar cual de todos estos es el prescalar y que es lo que tendria que cambiar para que el segundo sea exacto con un cristal de 4MHz

respueta anterior
Con esta fórmula si usas una fosc=4MHz, Preescaler=4, Temp=1ms ---> Valor a cargar en TMR0 = 6
Valor a cargar en TMR0=256 - (Temp · fosc) / (4 · Preescaler)
no entendi muy bien la cuenta seria
TMR0=256-(1000*4000000)/(4*4) (no me dan las cuentas)
Perdon estoy un poco confundido.

#include <16F84A.h>

#use delay (clock=4000000)
#fuses XT,NOWDT
#define INTS_PER_SECOND 80     // (4000000/(4*256*256))

byte int_count;

#int_rtcc                          
clock_isr() {                      
    if(--int_count==0) {          
      segundos1++;
      int_count=INTS_PER_SECOND;
    }

}

void main(void) {
   int_count=INTS_PER_SECOND;
   set_timer0(6);
   setup_counters( RTCC_INTERNAL, RTCC_DIV_256);
   enable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);

   for(; {
        // codigo
   }
}

Gracias saludos.
Pablo
Título: RE: Precisión del reloj
Publicado por: PabloFiscella en 28 de Noviembre de 2003, 14:01:00
RE: Precisión del reloj[/b]

<
Título: RE: Precisión del reloj
Publicado por: pocher en 29 de Noviembre de 2003, 01:59:00
Hola Pablo.

Como tu proyecto debe ser muy exacto. Al usar la fórmula anterior, el Valor a cargar en TMR0 no te debe dar un número decimal, ya que si así fuera tendrías que redondear, produciéndose un pequeño error, que sería exponencial al aumentar el tiempo.

Para que te hagas una idea, mirando los números de Cucaracha:

Usando un cristal de 4MHz, un Preescaler de 256 y deseando una temporización de 50ms sale: Valor a cargar en TMR0=256-(0,050 · 4000000) / (4 · 256) = 256 - 195,3 = 60,7 Aproximaremos entonces a 61.

Si ahora de la fórmula te despejas la Temp y sustituyes el valor 61 en el TMR0 sale Temp = 49,92ms (no 50ms como hubiesemos deseado). Si este número lo multiplicas por 20 (50ms · 20=1000ms=1s) sale 998,4ms con lo que el error que se comete es de 1,6ms cada segundo. Retrasaría 1,6ms

Cada minuto el error sería de 96ms.

Cada hora el error sería de 5,7s.

Cada 24h el error sería de 2,28 minutos (retrasaría esos minutos).

Para una frecuencia de 4MHz los únicos Preescalers que dan números exactos son el Preescaler=4 y Preescaler=8 Por ejemplo con el Preescaler de 8 quedaría:

Valor a cargar en TMR0=256-(Temp·4000)/(4·8)=256-Temp·125 con lo que la Temporización máxima que se podría conseguir sería:

Temp(max)=(256-0)/125=2,048ms El problema es que para conseguir 1s, sale: 1000ms/2,048=488,28 ¡¡¡decimal!!! Se tendría que aproximar a 488 dando ya error en las temporizaciones.

Lo mejor es que te consigas un cristal con el que los números salgan exactos, sin decimales, con el de 4,096MHz salen exactos.

Copiando los números de Cucaracha:

Para fosc=4,096MHz, Preescaler=256, Temp=50ms ---> Valor a cargar en TMR0 = 56 ---> Nº de interrupciones para 1s=20 (50ms·20=1000ms=1s)

Pablo te has equivocado aquí: TMR0=256-(1000*4000000)/(4*4) (no me dan las cuentas) Para 1ms no tienes que poner 1000 sino 0,001, de esa forma sale Valor TMR0=6

Otra cosa que viene del error anterior: en el programa cargas el TMR0 con 6, esta carga es para un Preescaler=4 no de 256 .

Lo dicho creo que lo mejor es agenciarse un cristal con el cual los números sean exactos.

Espero Pablo no haberte liado y no haberme equivocado después de estar pensando, haciendo números y escribiendo durante más de 1 hora.

Un saludo




Título: RE: Precisión del reloj
Publicado por: PabloFiscella en 30 de Noviembre de 2003, 10:31:00
Agradesco a todos por la explicacion, creo que me quedo bastante claro.
El problema es que en Argentina no consigo ese cristal, si alguien sabe donde puedo conseguirlo, le estare muy agradecido.

Saludos.
Gracias nuevamente.
Pablo
Título: RE: Precisión del reloj
Publicado por: solid84 en 01 de Diciembre de 2003, 16:06:00
que tal disculpa el que tarde en contestar pero me encontraba ausente retomando el tema del cristal te comento si usas el cristal de 4.096Mhz utilizas unos capacitores de 22pf que el valor nominal

ahora con la formula es la siguiente

Fosc/1*4*(Tmr0)*(preescaler)
esto es la freecuencia del reloj es 4096,000 su inversa o la division sobre 1 resultando

000000244140625 o sea 244 nano segundos esto * 4 que es el  reloj del pic que quiere decir esto cada 4 ciclos de reloj se ejecuta una instruccion del micro;

ejemplo;

4096000/1=000000244140625*4=0000009765625 nano segundos
esto es el valor de una instruccion del pic

espero ser claro ahora ya tenemos el valor de la instruccion

siguiendo la formula 4096000/1=000000244140625*4=0000009765625nS*256=
.00025 (250microsegundos)*4=.001(1milisegundo)

esto por el valor de tmr0 que este caso sera el desborde de 00 a ff
son 256

por ultimo el preescaler configuras los bits PS0 a PS2 con el valor 2
esto es 010;

o sea el divisor esta en la escala de division entre 4  
esto lo puedes checar en el datasheet del pic en la seccion del registro opcion

asi tienes una base de tiempo exacta de 1 milisegundo si tu quieres un segundo entonces tendras que contar 1000 incrementos supongamos

void interrupt timer0()
{
     conta1++;
     if(conta1==1000)
     {
        conta1=0;
        segundos++;  
}
en lo personal es muy buena base de tiempo ya que si es exacta puedes probar con la ayuda de un osciloscopio y veras que no se le va nada saludos y espero haber sido claro
Título: RE: Precisión del reloj
Publicado por: pocher en 04 de Diciembre de 2003, 10:57:00
A ver si con este cristal tienes más suerte en encontrarlo: 32,768 KHz

Cálculos:

Para una temporización de 1s:

Valor a cargar en TMR0 = 256 - (1s · 32768Hz) / (4 · 256) = 256 - 32 = 224

Nº de interrupciones = 1

PD Se me olvidaba los condensadores: 2 de 27p
Título: RE: Precisión del reloj
Publicado por: pocher en 05 de Diciembre de 2003, 11:28:00
Aquí tienes el reloj totalmente acabado, cortesía de Diegonet: http://miarroba.com/foros/ver.php?temaid=665952&foroid=46840
Título: RE: Precisión del reloj
Publicado por: PabloFiscella en 05 de Diciembre de 2003, 12:09:00
Pareceria ser que en Argentina no se consigue nada.
El 3,2768 tampoco lo consigo. Encotre alguien que vende el 4,096 a  U$s7, un poco caro no?
Luego les cuento porque lo voy a comprar.
Para poder hacer el temporizador.

Saludos a todos.
Pablo
Título: RE: Precisión del reloj
Publicado por: achamber2k3 en 10 de Diciembre de 2003, 17:53:00
Bueno, en mi pais ahora tenemos control de cambio y es un poco dificil conseguir cualquier cosa, asi que aplico un metodo que llame "del año bisiesto" para resolver esto con un común cristal de 4MHz exactos, lo que hice fue lo siguiente:

1.- considere el preescaler en 256 y la fcristal obviamente en 4MHz

2.- Construi una tabla en excel para calcular con valores de recarga desde  0 hasta 255 la siguiente formula:

nciclos = 1seg/( (256-recarga)*256*(4/4000000) )

Esto me da el numero de ciclos necesarios del lazo externo (que en un ejemplo dado por ustedes era de 20) para contar aproximadamente un segundo. Por supuesto me dan todos con decimales, pero bueno ahi esta el truco de la cosa.

3.- Tomo el valor de nciclos que menos decimales tenga y por supuesto sea menor a 255 en este caso tengo que con un valor de recarga de 6 el cual tiene un valor de nciclos de 15,625 con una interrupcion por timer cada 64ms bien veamos que nuestra diferencia con un numero entero es de 0,625 para el valor de nciclos, pues tratamos de encontrar el primer numero que multiplicado por 0,625 nos de un entero, en este caso es 8 - > 8*0.625 = 5 esto significa que cada 8 ejecuciones del contador cargado con 15 debemos cargarlo con 15+5 = 20 para de esta forma corregir los decimales.

4.- Asi pues usariamos dos contadores uno que llevaria la cuenta de ajuste y otro que llevaria la cuenta de cuando se cumple un segundo. Este metodo pienso aplicarlo proximamente en un control de luces, ya lo simule y funciona perfectamente, una salida alternativa al problema de los cristales.

Saludos a todos y Exitos

AChamber
Título: RE: Precisión del reloj
Publicado por: pocher en 11 de Diciembre de 2003, 06:27:00
Hola Alfredo, no lo acabo de entender y creo que esto que tú planteas nos interesa a todos.

Siguiendo tu razonamiento:

Cargando el TMR0 con 6 y usando un Preescaler=256 (fosc=4MHz) sale que cada 64ms se producirá una interrupción.

¿Puedes poner como cargarías los 2 contadores externos para conseguir el deseado segundo?

Un saludo
Título: RE: Precisión del reloj
Publicado por: pocher en 11 de Diciembre de 2003, 10:31:00
Hola Cuca, estaba contestando antes y se ha ido la luz ... dita sea.

Vamos a hacer algunos números.

Cargando el TMR0 con 6 y usando un Preescaler=256 (fosc=4MHz) sale que cada 64ms se producirá una interrupción.

Si usamos un Contador cargado con 15 y realizamos 15 interrupciones saldría un tiempo de 15 · 64ms = 960ms.

Si esto se repite 8 veces saldría un tiempo de 8 · 960ms = 7680ms

Si ahora hacemos la corrección cargando el registro Contador con 5 (en lugar de 15) el tiempo empleado en estas 5 pasadas será: 5 · 64ms = 320ms.

Es decir los 8 primeros segundos los ha realizado en 7680ms más la corrección que es 320ms.

Si sumamos ambos tiempos salen un total de 7680 + 320ms = 8000ms = 8s

Creo que la precisión se obtiene cada 8s, no cada 9s.

¡¡¡Muy buena explicación Cucaracha!!!
Título: RE: Precisión del reloj
Publicado por: cucaracha en 11 de Diciembre de 2003, 10:57:00
...y esos 5 "añadidos" en que segundo entran pocher...

Saludos!
Título: RE: Precisión del reloj
Publicado por: pocher en 11 de Diciembre de 2003, 11:16:00
Ya estoy otra vez aquí.

Los 320ms son los que le faltan para completar los 8s, por lo tanto entran en el transcurso del 7º segundo.

Un saludo
Título: RE: Precisión del reloj
Publicado por: cucaracha en 11 de Diciembre de 2003, 11:35:00
Jeje... pues mirándolo de nuevo creo que ni tú ni yo...
En el 8º se deben de contar 20 en lugar de 15. Se ha de cambiar una vez concluido el 7º paso. Ya que si cargas luego de 8 el contador con 5, cuando se cumplan incrementará también los segundos, osea que serían ya 9.
No?

Saludos!!
Título: RE: Precisión del reloj
Publicado por: pocher en 11 de Diciembre de 2003, 12:17:00
Vamos a darle más caña:

- Según el primer desarrollo numérico (7680ms + 320ms), la corrección, que son los 320ms se empieza a hacer cuando han pasado 7680ms , es decir cuando han pasado 7,68s y cuando termina la corrección han pasado los 8s.

- Según tu segundo desarrollo numérico (el de 20), la corrección se empieza a hacer cuando han pasado 960ms · 7 = 6720ms, es decir cuando han pasado 6.72s y el resultado de la corrección es: 20 · 64ms = 1280ms. Si sumamos los 6720ms + 1280ms = 8s

CONCLUSIÓN: bien de una manera, bien de otra se llega al mismo resultado.

Un saludo
Título: RE: Precisión del reloj
Publicado por: cucaracha en 11 de Diciembre de 2003, 13:13:00
Más marcha!!

Si te fijas, el segundo desarrollo está basado en el primero. Cuando han pasado esos 7,68seg es al octavo paso. Ahora le sumas los 320mseg que faltan y listo. Sobre papel muy bien, pero como lo haces en el micro. Para llevar a cabo el primer desarrollo, tienes que hacer lo que viene en el segundo.
Porque como sumas esos 320ms (los cinco ciclos)?? Habría que hacerlo con otra rutina que los contara y no incrementara los segundo al final.
Microcontroladormente hablando esos 7,68 seg, en realidad es como si fueran los 8 seg con un error de 320ms (por el cristal), entonces se hace la treta de la correción. Pero eso, esos 7,68seg son 8seg con un error de 320ms. Entiendes mi razonamiento

No?

Saludos!!
Título: RE: Precisión del reloj
Publicado por: achamber2k3 en 11 de Diciembre de 2003, 13:53:00
Carambas he entrado por curiosidad desde el trabajo y Dios Mio! que interesante se ha puesto esto, jaja, pues si, ambos tienen razon, yo lo que hago originalmente es cargar con 15 durante siete veces y con 20 la octava vez, y obtengo el ajuste de error cada 8 segundos, le he llamado metodo del a~no bisiesto porque asi se hace en el calendario, el a~no solar tiene algo asi como 365.25 dias, ese error se suma y cada 4 a~nos tenemos un 29!

En la noche al llegar a la casa les cuelgo el programa para que lo vean y comentemos.

Saludos y Exitos

Achamber
Título: RE: Precisión del reloj
Publicado por: PabloFiscella en 12 de Diciembre de 2003, 07:30:00
Lo probe y funciona perfecto.

Son unos capos.
Muchas gracias. Saludos
Pablo
Título: RE: Precisión del reloj
Publicado por: achamber2k3 en 12 de Diciembre de 2003, 18:25:00
Perdonen la demora aqui esta lo prometido, un poco tarde pues ya medio foro sabe como es, gracias por sus comentarios muchachos:

////                     INICIALIZAR                                 ////

void inicializar() {

      set_tris_a(0x00);                //Todo puerto A Salidas
      set_tris_b(0xF0);                //RB0-3 Salidas RB4-7 Entradas

      port_b = 0x00;                   //Inicializa señales de control
      port_a = 0x0c;                   //Inicializa señales de control

      init_lcd();

      setup_counters(RTCC_INTERNAL,RTCC_DIV_256);
      set_rtcc(6);
      enable_interrupts(INT_RTCC);
      enable_interrupts(GLOBAL);

}

////                     RUTINAS DE INTERRUPCION                     ////

#INT_RTCC
void cada64ms()  {

   disable_interrupts(GLOBAL);

   set_rtcc(6);
   contemp1 = contemp1 - 1;

   if (contemp1==0) {

         contemp2 = contemp2 - 1;
         contemp1 = 15;

         if (contemp2==0){

            contemp1 = contemp1 + 5;
            contemp2 = 8;

         }

         // Rutina Aprox cada segundo - Exacta cada 8 seg.
         // contemp1 se carga con 15, 15, 15, 15, 15, 15, 15, 20, 15, 15...

         segundos = segundos + 1;
         if (segundos==60){
            minutos = minutos + 1;
            segundos = 0;
         }
         if (minutos==60){
            horas = horas + 1;
            minutos = 0;
         }
         if (horas==13){ horas = 1; }
         bampm = 0;

   }

   enable_interrupts(GLOBAL);

}

Título: RE: Precisión del reloj
Publicado por: pocher en 13 de Diciembre de 2003, 05:29:00
achanver2k3 faltan bastantes cosas (definición de variables, el include de la LCD, el main ... )

¿Que te parece si pones el programa completo, incluida la visualización sobre la LCD?

Un saludo
Título: RE: Precisión del reloj
Publicado por: achamber2k3 en 13 de Diciembre de 2003, 10:05:00
Bueno alli va el programa, solo maneja el LCD, porque al hacer el control para todo lo demas que queria pues me quede sin memoria y ahora estoy trabajando en el diseño con un 876. Cuando lo tenga listo, con control de teclado, dimmer para las luces que controla e interfaz para el PC pues subo todo el proyecto.

Espero les sea útil.

Saludos a todos.

Alfredo

/////////////////////////////////////////////////////////////////////////
////                     PROYECTO DE DOMOTICA                        ////
/////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////
////                     COMANDOS DEL PREPROCESADOR                  ////
/////////////////////////////////////////////////////////////////////////

#if defined(__PCM__)
#include <16F84A.h>
#fuses XT,NOWDT,NOPROTECT,PUT
#use delay(clock=4000000)

#bit lcd_rs = 5.0
#bit lcd_e = 5.1
#bit latch_ck = 5.2
#bit temp_cs = 5.3
#bit buzzer = 5.4

#byte port_a = 5
#byte port_b = 6
#byte lcd_data = 6

/////////////////////////////////////////////////////////////////////////
////                     DEFINICION DE VARIABLES                     ////
/////////////////////////////////////////////////////////////////////////

char string[16];
int estado_control;
int horas = 12;
int minutos = 00;
int segundos = 00;
short bampm = 0;
int contemp1 = 15;         // Contador Interno 15 o 20
int contemp2 = 8;         // Contador Ajuste hasta 8
float temp = 26.36;

/////////////////////////////////////////////////////////////////////////
////                     DEFINICION DE FUNCIONES                     ////
/////////////////////////////////////////////////////////////////////////

void inicializar();
void init_lcd();
void write_lcd_nibble(BYTE);
void write_lcd(SHORT, BYTE);
void lcd_gotoxy(BYTE,BYTE);
void lcd_putc(char);
void pantallaespera();
void lcd_putc(char);
void goto_lcd(BYTE,BYTE);

/////////////////////////////////////////////////////////////////////////
////                     RUTINA DE INICIALIZACION                    ////
/////////////////////////////////////////////////////////////////////////

void inicializar() {

      set_tris_a(0x00);                //Todo puerto A Salidas
      set_tris_b(0xF0);                //RB0-3 Salidas RB4-7 Entradas

      port_b = 0x00;                   //Inicializa señales de control
      port_a = 0x0c;                   //Inicializa señales de control

      init_lcd();

      setup_counters(RTCC_INTERNAL,RTCC_DIV_256);
      set_rtcc(6);
      enable_interrupts(INT_RTCC);
      enable_interrupts(GLOBAL);

}

/////////////////////////////////////////////////////////////////////////
////                     PROGRAMA PRINCIPAL                          ////
/////////////////////////////////////////////////////////////////////////

main()   {

   inicializar();

   while(TRUE){

      pantallaespera();

   }

}

/////////////////////////////////////////////////////////////////////////
////                     RUTINAS DE INTERRUPCION                     ////
/////////////////////////////////////////////////////////////////////////

#INT_RTCC
void cada64ms()  {

   disable_interrupts(GLOBAL);

   set_rtcc(6);
   contemp1 = contemp1 - 1;

   if (contemp1==0) {

         contemp2 = contemp2 - 1;
         contemp1 = 15;

         if (contemp2==0){

            contemp1 = contemp1 + 5;
            contemp2 = 8;

         }

         // Rutina Aprox cada segundo - Exacta cada 8 seg.
         // contemp1 se carga con 15, 15, 15, 15, 15, 15, 15, 20, 15, 15...

         segundos = segundos + 1;
         if (segundos==60){
            minutos = minutos + 1;
            segundos = 0;
         }
         if (minutos==60){
            horas = horas + 1;
            minutos = 0;
         }
         if (horas==13){ horas = 1; }
         bampm = 0;

   }

   enable_interrupts(GLOBAL);

}

/////////////////////////////////////////////////////////////////////////
////                     RUTINAS DE MENU                             ////
/////////////////////////////////////////////////////////////////////////

void pantallaespera(){

      write_lcd (0, 0x80);
      printf(lcd_putc, "%02u:%02u:%02u%c %02.2fC", horas, minutos, segundos, bampm, temp);
      write_lcd (0, 0xc0);
      printf(lcd_putc, " * * O O      * ";

}

/////////////////////////////////////////////////////////////////////////
////                     RUTINAS DE MANEJO DE LCD                    ////
/////////////////////////////////////////////////////////////////////////

void init_lcd() {

   write_lcd_nibble(0x02);
   write_lcd(0, 0x0c);
   write_lcd(0, 0x01);
   write_lcd(0, 0x06);

}

void write_lcd_nibble(BYTE n) {

      lcd_data = n;
      delay_ms(1);
      lcd_e = 1;
      delay_ms(1);
      lcd_e = 0;
      delay_ms(1);

}

void write_lcd(SHORT nocom, BYTE dato) {

      lcd_rs = nocom;
      delay_ms(1);
      write_lcd_nibble(dato >> 4);
      write_lcd_nibble(dato & 0xf);
      lcd_rs = 0;

}

void lcd_putc( char c) {

   write_lcd(1,c);     break;

}

/////////////////////////////////////////////////////////////////////////
// FIN

Título: RE: Precisión del reloj
Publicado por: PabloFiscella en 16 de Diciembre de 2003, 06:42:00
Hola:

Estoy tratando de hacer funcionar el programa del LCD pero lo unico que aparece es media pantalla en negro.

Supongo que se debe a una conexion erronea.

LCD   PIC
0v
5v
contraste
4       A0
5
6       A1
7       B0
14     B7

Saludos.
Pablo
Título: RE: Precisión del reloj
Publicado por: cucaracha en 16 de Diciembre de 2003, 07:22:00
Pusistes el potenciómetro para el control de contraste?? En los ejemplos que te pasaron en Proteus no viene, ya que el proteus es algo flexible en eso al igual que con el reloj del micro, que no hace falta ponerlo (sólo hace falta indicarlo en sus propiedades).

Mira en http://www.x-robotics.com/ en la sección "RUTINAS" tienes un ejemplo de LCD 16X2. Fíjate como conecta toda la parte de control.

Saludos!!
Título: RE: Precisión del reloj
Publicado por: PabloFiscella en 16 de Diciembre de 2003, 08:41:00
Hola:

El conexionado creo que esta bien probe las dos formas, la de 4 y 8 bits y sigue igual pone la mitad de la pantalla con los caracteres completamente negros. (¨€ ¨€ ¨€ ¨€ ¨€).

Otra cosa que pueda probar?
no pude copiar el ejemplo de asm porque no tengo compilador y la verdad es que tampoco se mucho de asm.

Saludos y gracias.
Pablo
Título: RE: Precisión del reloj
Publicado por: pocher en 16 de Diciembre de 2003, 10:13:00
achanver2k3 mira a ver si nos indicas cuales son las conexiones del PIC con la LCD. He intentado varios tipos de conexiones y aquello no carbura.

Un saludo
Título: RE: Precisión del reloj
Publicado por: Elena2000 en 16 de Diciembre de 2003, 10:25:00
Ufff.... chicos, caramba... me quito el sombrero ante esta birguería de subforo... que derroche de sabiduría con los razonamientos para ajustar los segundos....
Hale hale, a seguir!

Elena
Título: RE: Precisión del reloj
Publicado por: achamber2k3 en 16 de Diciembre de 2003, 17:36:00
Perdonarme por haberme desaparecido, pues aqui les mando el enlace donde bajar simulacion .c y .hex

http://www.fraktalnet.com/domotica.zip

Es la pagina de mi empresa pero no es relacionada con pics para que no se desilucionen

Probablemente el que no les funcione esta en el modo de conectar los bits d0 a d3 de la pantalla, fijense que los coloco a niveles fijos  de tal manera de asegurar el cambio a modo de 4 bits del lcd en una sola instruccion.

Ah, por cierto, mucho gusto Elena... es una agradable sorpresa ver mujeres lindas en este mundillo de los PICs...

Saludos y exitos...

Achamber