PIC como tener un reloj exacto aun teniendo retardos en el codigo?

Hola estoy trabajando en un circuito con un pic en el que tiene que contar un tiempo determinado para realizar una accion determinada, pero creo que el problema que puedo llegar a tener es que si tengo un retardo para crear un segundo y partir de esa base para generar un reloj entonces al momento de poner un retardo nuevo para ejecutar una accion programada el reloj del tiempo variaria?... me gustaria saber sus opiniones y saber de que forma ustedes lo resuelven, mi lenguaje es mikroPascal o mikroC cuando mucho pero si me representan un codigo en otro lenuaje es solo cuestion de estudiarlo o que me enseñen lo basico!

saludos y gracias por sus respuestas!
 
Busca RTC Real-Timer Clock, son chip que programas la hora y funcionan como autenticos relojes. Se programan mediando I2C normalmente con otro programador, los hay con muchas funciones como alarmas, calendarios, etc. Poseen circuitos internos de compensación por temperatura, etc. Puedes ir actualizando cada cierto tiempo tu reloj del microcontrolador con el reloj de RTC.

Un saludo

 
Última edición:
Amigo, evidentemente es como comenta chclau.
Debes habilitar el temporiz. interno del PIC, segun la arquitectura del mismo puede hallarse temporiz. de 8bit y/o 16bits los mismos ofrecen la posibilidad de generar un llamado a interrupcion cuando se desbordan, ademas puedes prescalarlos si el tiempo requerido es pequeño.
Busca el datasheet del PIC.
 
Última edición:
La contabilización de tiempos con los micros, se deja en manos de algún temporizador que estos traen, caso concreto de un PIC.
Timer0 ó timer1, son los que se emplean para esto, 8 y 16bits respectivamente, pueden contar desde unos pocos uSeg a varios Seg, según velocidad del cristal del pic, que puede ser interno o externo (posibilidad de conectar uno de baja frecuencia).
Se complementa con el uso de interrupciones que son capaces de disparar estos temporizadores, así que la cosa es en segundo plano(si lo querés así).

De todos modos te advierto que es muy difícil lograr cierta precisión, especialmente si se trata de una cuenta de varias horas, por la deriva propia de las condiciones de los cristales resonadores, sumado a esto que todo es binario, y con ello no te cierran las cuentas contra nuestro mundo decimal, cayendo en oscurantismo en la programación y técnicas solo conocidas por tecnomagos, para lograr una cuenta coherente entre estos dos mundos.

Si lo tuyo es contar muchas horas (o días o años), no queda otra solución fiable que dejar la cosa en manos de algún circuito especializado, si estás en Argentina, terminas cayendo en Electrocomponentes o algún lugar así, y pedis un DS1307, pero ahora tenés que aprender el manejo del I2C, porque este integrado se conecta al mundo atravéz de esta interfáz.

Flojos estos pic's Che, nunca vi uno que incorpore un RTC asistido con una fuente externa de respaldo al modo del DS1307, así nunca pierde la cuenta, por ausencia de la fuente principal.

Tu búsqueda debería ser:

"pic + timer0 + interrupt" (ó timer1)
"pic + DS1307 + RTC"
 
Amigo, evidentemente es como comenta chclau.
Debes habilitar el temporiz. interno del PIC, segun la arquitectura del mismo puede hallarse temporiz. de 8bit y/o 16bits los mismos ofrecen la posibilidad de generar un llamado a interrupcion cuando se desbordan, ademas puedes prescalarlos si el tiempo requerido es pequeño.
Busca el datasheet del PIC.

Se refiere a un reloj exacto, prueba utilizando un timer del micro a generar un reloj y ya me contaras la cantidad de minutos o horas de inexactitud que pierdes en un mes.
 
Usar bucles vacíos como método de temporizar es muy muy poco serio para cualquier aplicación. Lo normal es usar timers e interrupciones literalmente para todo.
Además para hacer un reloj lo lógico es usar uno para no volverse loco. Si se pone un primer en autorecarga se puede conseguir exactitud pero es complejo.
 
A ver no me entendeis, aunque utilice los timer del micro estos no son tan exactos como para elaborar un reloj. En 1 seg temporizado con el timer del micro que pierdas 1 ms de precisión no importa, pero a lo largo de 1 mes que son 2.592.000 seg, pierdes 2.592 seg o lo que es 43.2 minutos algo que no se puede permitir. Los timer del micro no sirve para esas aplicaciones. Necesitas RTC que tiene compensadores de temperatura y otras unidades de precisión.


DS39696A-page 29-2

• Time: Hours, Minutes and Seconds
• 24-Hour Format (Military Time)
• Calendar: Weekday, Date, Month and Year
• Alarm Configurable
• Year Range: 2000 to 2099
• Leap Year Correction
• BCD Format for Compact Firmware
• Optimized for Low-Power Operation
• User Calibration with Auto-Adjust
• Calibration Range: ± 2.64 Seconds Error per Month
• Requirements: External 32.768 kHz Clock Crystal
• Alarm Pulse or Seconds Clock Output on RTCC pin
 
Última edición:
Ni mas ni menos, Basalto tiene la razon, sin embargo tambien he visto microcontroladores que cuentan con la funcion de RTC, imagino que son especificos para alguna aplicacion que requiere de un reloj preciso.
 
Habría que ver el modelo de Pic con el que trabaja.

En los AVR, podés usar un cristal de 32,768kHz como oscilador auxiliar (distinto al oscilador principal del uC) para generar un RTC (vía soft) a partir del uso de un timer con todos sus pre-escaler. Yo lo llegué a implementar y funciona muy bien.
 
Hola veo que es un tema complejo y todavia no e probado ninguna teoria de las que me indican pero apenas tenga un tiempo lo voy a hacer! por otro lado el pic que voy a usar es un 18F2455 que estoy programando en MikroPascal como comente antes!
 
Encontre documentacion sobre rtc con pic y MikroPascal yo tengo un codigo ya extenso voy a tener que estudiar la posibilidad de implementar o no el uso de rtc :unsure:



Tengo que contar segundos horas y dias el tiempo maximo seria de un mes aproximado, lo bueno es que no requiero tanta presicion con el tiempo pero tampoco quiero llegar a contar 45 dias en un mes :D



una duda si tengo un ht1380 tengo que programar ese circuito o el programa va en el pic para hacer un rtc ? porque encontre este circuito y su codigo de rretamar http://www.clubdelphi.com/foros/showthread.php?t=65727

3588h1w.png
 
Última edición:
En la hoja de datos del PIC que dice que al Timer 1 podés engancharle un 2do cristal de 32kHz, seguramente los puertos de ese segundo oscilador ya poseen los capacitores internos necesarios para que el cristal funcione (es cuestión de ver bien la hoja).

Una vez que colocás ese 2do cristal, tenés que configurar el pre-escaler + el contador del timer, para que haga una cuenta c/1 seg, para eso usá un divisor de 2^15 (en el AVR es pre-escaler en 128 y contador de 256 => 2^7*2^8=2^15).

Para el código yo implementé algo así (está en C, pero seguro que lo podés adaptar a tu lenguaje):

- Archivo RTC.c

PHP:
#define SEGUNDO		         0
#define MINUTO		         1
#define HORA		                 2
#define DIA			         3
#define MES			         4
#define ANIO		                 5
#define BISIESTO	                 6
#define TAMANIO_VECTOR_RTC	 7

void RTC_MES_ANIO(u8 hora[])
{
	if(hora[MES]>=12)
		{
			hora[MES]=1;
			
			hora[ANIO]++;
			
			if((hora[ANIO]%4)==0)
				hora[BISIESTO]=1;
			else
				hora[BISIESTO]=0;
		}
	else
		hora[MES]++;
}

void RTC_DIA(u8 hora[])
{
	hora[DIA]++;
	
	if(hora[MES]==2)
		{
			if(hora[BISIESTO])
				{
					if(hora[DIA]>=30)
						{
							hora[DIA]=1;
							RTC_MES_ANIO(hora);	
						}
				}
			else
				{
					if(hora[DIA]>=29)
						{
							hora[DIA]=1;
							RTC_MES_ANIO(hora);	
						}
				}	
		}//febrero
	else
		{
			if((hora[MES]==4)||(hora[MES]==6)||(hora[MES]==9)||(hora[MES]==11))
				{
					if(hora[DIA]>=31)
						{
							hora[DIA]=1;
							RTC_MES_ANIO(hora);	
						}
							
				} //30 dias
			else
				{
					if(hora[DIA]>=32)
						{
							hora[DIA]=1;
							RTC_MES_ANIO(hora);	
						}
				} //31 dias
		}//El resto de los meses
}

void RTC_HORA(u8 hora[])
{
	
	if(hora[SEGUNDO]>=59)
		{
			hora[SEGUNDO]=0;
			
			if(hora[MINUTO]>=59)
				{
					hora[MINUTO]=0;
					
					if(hora[HORA]>=23)
						{
							hora[HORA]=0;
							RTC_DIA(hora);
						}
					else
						hora[HORA]++;
				}
			else
				hora[MINUTO]++;
		}
	else
		hora[SEGUNDO]++;
	
}

- Dentro del main.c:

PHP:
....
int main()
{
  //--------------- VECTOR HORA PARA EL RTC -----------//
  u8 vector_hora_rtc[TAMANIO_VECTOR_RTC]={55,59,23,27,2,13,0}; //Inicialización de la hora y fecha 23:59:55 del 27/2/13 (año no bisiesto)
  //--------------- VECTOR HORA PARA EL RTC -----------//
  ... //Resto de la inicialización --> incluso timer 1 y su interrupción

  while(1)
  {
   ....//Tu rutina
   
   if(flag_timer_1) //Hubo una interrupción en el timer 1 -> implica que pasó 1 seg
     RTC_HORA(vector_hora_rtc);	//Actualizo el vector RTC -> le suma 1 seg. al vector RTC
   
   ...  
   }
}

Fijate si te sirve.
 
Última edición:
cosmefulanito04 gracias por responder tengo algunas dudas , si no uso un RTC y uso tu codigo en el pic 18f2455 tengo que poner un cristal en las patas OSC1 y OSC2 eso está más que claro pero donde pongo el segundo cristal en T1OSO y T1OSI?? el datasheet que estoy viendo es http://ww1.microchip.com/downloads/en/devicedoc/39632c.pdf soy muy malo con el ingles! por otro lado que resultados te dio tu codigo es preciso el tiempo? y que opinas de implementar un ht1380? si lo uso con que software lo programo MikroPascal no incluye este circuito y ic-prog y winpic800 tampoco :( sigo en la busqueda de mi santo grial :D
 
...pero donde pongo el segundo cristal en T1OSO y T1OSI??...

Al parecer es como decís:





Además del cristal, vas a tener que agregar los capacitores necesarios que aconseja la hoja de datos.

..por otro lado que resultados te dio tu codigo es preciso el tiempo?

Funcionaba muy bien, no lo probé 1 mes, pero un par de días iba bien.

Tené en cuenta que la deriva de tiempo dependerá casi exclusivamente del cristal, ya que el uC lo único que hace es:

- Suma una cuenta en el Timer 1 c/3,9 mSeg, un tiempo enorme para un uC.
- Genera una interrupción c/1 Seg, tiempo más que suficiente para que llames la función RTC_HORA.

Esto último es en el AVR, en tu caso, el pre-escaler máximo que tenés es de 8, pero tu contador es de 16bits, con lo cual podrías directamente usar el contador sin pre-escaler configurandolo con 32768 cuentas.

...y que opinas de implementar un ht1380?...

No sabría decirte, no lo usé nunca. Pero si el uC ya tiene un hard suficiente para generar el RTC, no le veo mayor utilidad.

¿Que deberías tener en cuenta?

- Necesitás sicronizarlo al tiempo actual la 1era vez, te recomiendo hacerlo mediante la Uart o algún puerto de comunicación.

- La batería. Si se resetea el uC perdés la hora, este es el "lado oscuro" de la solución, ya que la batería debería alimentar a todo el uC para poder resguardar la hora... ahí vas a tener que implementar un código que ponga al uC en modo de bajo consumo.
 
Última edición:
me perdi mal acá! :unsure:

De alguna forma tenés que configurar la hora actual del reloj, para eso en mi código tenés que actualizar los valores del vector_hora_rtc y eso lo podés hacer:

- Vía código --> no es buena idea, solo lo podés hacer una vez.
- Mediante un teclado implementado en el uC + un display.
- Mediante el puerto serie/usb conectado a la PC y mediante un soft enviar la hora actual de la PC (esto es lo que hice yo para poner en hora el RTC).
 
entonces tengo en cuenta estos items:

1) entonces uso un cristal de 32,768kHz en las patas auxiliares y otro en las patas del oscilador normal
2) ago un codigo y uso rutinas procedimientos funciones y retardos normalmente pero siempre Timer1 va a ser el RTC
3) tengo en cuenta que tendria que sicronizar el tiempo la 1era vez con algun medio (un teclado por ejemplo)
4) implementar un código que ponga al uC en modo de bajo consumo, al configurar el micro hay una opcion que lo pone en sleep me parece?!

si me olvido de algo porfavor avicen :D
 
Atrás
Arriba