Autor Tema: timer 0 para 1 seg.  (Leído 6562 veces)

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

Desconectado black_flowers

  • PIC18
  • ****
  • Mensajes: 450
timer 0 para 1 seg.
« en: 20 de Enero de 2007, 17:23:04 »
he estado hechando un vistazo por los post acerca del timer0 para temporizar un segundo. Yo he hecho unos cálculos pero por lo visto no deben ser correctos por lo que por ahí he visto. Lo pongo para ver en donde me equivoco:

con cristal de 4mhz tenemos 0.00025us de ciclos de reloj. Cada ciclo máquina son 4 ciclos de reloj es decir tendríamos 0.00025*4=0.001 us. Es decir que con el prescaler a 1 tendríamos una temporización de 0.001 us que es un multiplo de 1 segundo.

¿qué está mal?

sl2

Desconectado Fer_TACA

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4069
Re: timer 0 para 1 seg.
« Respuesta #1 en: 20 de Enero de 2007, 17:54:11 »
Creo que los multiplos no estan correctos para 4MHz se obtiene un retardo de 1µSg no 0,001µsg.
Me equivoco?
Fermin
Todos los días se aprende algo nuevo.

Desconectado Modulay

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2651
Re: timer 0 para 1 seg.
« Respuesta #2 en: 20 de Enero de 2007, 18:22:11 »
Esas mates...
Con un cristal de 4 MHz tienes un periodo de reloj de 1/4 MHz = 0.25 us
Como cada ciclo máquina son 4 ciclos de reloj,tienes un ciclo máquina de 0.25 us * 4 = 1 us.
Es decir,el timer se incrementa en una unidad cada microsegundo.
La idea es buscar que el timer interrumpa cada cierto tiempo x,y que ese tiempo x sea divisor exacto de 1 segundo,por ejemplo 25 us,100 us,2 ms,10 ms,etc...
Además de esto,habrá que usar una variable contador que se irá incrementando cada vez que el timer se desborde,comprobando su valor cada vez que esto sucede y así llevar el control del tiempo transcurrido.
La fórmula,medida en segundos,que determina el periodo de desbordamiento de un timer de 8 bits (timer 0) es:

T = (256 - precarga) * prescaler * 4 / Fosc

Si fijamos el prescaler a 16...

T = (256 - precarga) * 16 * 4 / 4 MHz
=> precarga = 256 - T * 62500

T es la base de tiempos que andamos buscando y precarga es el valor que se le carga al timer tras cada interrupción para que vuelva a empezar a contar a partir de él.
Se trata de buscar un valor para T que sea divisor de 1 segundo y que al multiplicarlo por 62500 el resultado sea un número entero.
Por ejemplo 4 ms:

precarga = 256 - 4 ms * 62500 = 256 - 250 = 6

O sea,para conseguir la base de tiempos de 4 ms tendrás que cargar al timer con el valor 6 (con prescaler establecido a 16).
Hecho esto,para temporizar un segundo tendrás que contar:
 1 s / 4 ms = 250 interrupciones

Desconectado Fer_TACA

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4069
Re: timer 0 para 1 seg.
« Respuesta #3 en: 20 de Enero de 2007, 18:36:10 »
Jo, que esplicacion y que rapidez ¡te me has adentado!.
Todos los días se aprende algo nuevo.

Desconectado Modulay

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2651
Re: timer 0 para 1 seg.
« Respuesta #4 en: 20 de Enero de 2007, 18:43:48 »
 8) :mrgreen:

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
Re: timer 0 para 1 seg.
« Respuesta #5 en: 20 de Enero de 2007, 19:56:52 »
Jóse, con tu permiso, o sin él, esta explicación va de cabeza a Picmanía.  :D :D :D

Se puede explicar mas alto, pero no mas claro.  :mrgreen:
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado black_flowers

  • PIC18
  • ****
  • Mensajes: 450
Re: timer 0 para 1 seg.
« Respuesta #6 en: 20 de Enero de 2007, 21:37:11 »
Esas mates...
Con un cristal de 4 MHz tienes un periodo de reloj de 1/4 MHz = 0.25 us
Como cada ciclo máquina son 4 ciclos de reloj,tienes un ciclo máquina de 0.25 us * 4 = 1 us.



bueno ya se que voy a quedar como el culo despues de esta explicación tan detallada, pero es que a mi las formulas no son lo mío.

Entonces con respecto a lo de arriba, se podría  considerar que 1us es múltiplo de 1s y por lo tanto con el prescaler a 1 y un contador de 1000 pues ya tendría 1 segundo (¿me equivoco?)

sl2.

Desconectado manwenwe

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2211
Re: timer 0 para 1 seg.
« Respuesta #7 en: 20 de Enero de 2007, 23:08:17 »
Hola,
Citar
Entonces con respecto a lo de arriba, se podría  considerar que 1us es múltiplo de 1s y por lo tanto con el prescaler a 1 y un contador de 1000 pues ya tendría 1 segundo (¿me equivoco?)

Vamos a ver... 1us sí es divisor(no multiplo) entero de 1seg pero:  1seg = 1 millon useg, con lo que si pones el preescaler a 1(o lo que es lo mismo asignarlo al WDT) necesitarías hacer un contador de 1 millon de vueltas.

Aún con estas no obtendrías 1seg sino 3,4 o 5 segs porque debes hacer un bucle que que decremente el contador, testear el flag de desbordamiento del timer y ponerlo de nuevo a 0...

Si lo que quieres es no complicarte demasiado, haz lo que te sugiere Modulay:

TMRO = 6
PREESCALER = 16
CONTADOR = 250

como tu ciclo de intrucción es de 1 useg, tienes:

 1useg * (256 - 6) * 16 * 250 = 1useg * 1000000 = 1seg (milisegundo arriba, milisegundo abajo por los testeos... jeejjeej)

Saludos!
Ojo por ojo y todo el mundo acabará ciego - Mahatma Gandhi -

Desconectado Modulay

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2651
Re: timer 0 para 1 seg.
« Respuesta #8 en: 21 de Enero de 2007, 03:53:40 »
Jóse, con tu permiso, o sin él, esta explicación va de cabeza a Picmanía.  :D :D :D

Se puede explicar mas alto, pero no mas claro.  :mrgreen:


Un honor estar al servicio de la picmanía :)

Desconectado black_flowers

  • PIC18
  • ****
  • Mensajes: 450
Re: timer 0 para 1 seg.
« Respuesta #9 en: 21 de Enero de 2007, 07:56:19 »
Hola,
Citar
Entonces con respecto a lo de arriba, se podría  considerar que 1us es múltiplo de 1s y por lo tanto con el prescaler a 1 y un contador de 1000 pues ya tendría 1 segundo (¿me equivoco?)

Vamos a ver... 1us sí es divisor(no multiplo) entero de 1seg pero:  1seg = 1 millon useg, con lo que si pones el preescaler a 1(o lo que es lo mismo asignarlo al WDT) necesitarías hacer un contador de 1 millon de vueltas.

Aún con estas no obtendrías 1seg sino 3,4 o 5 segs porque debes hacer un bucle que que decremente el contador, testear el flag de desbordamiento del timer y ponerlo de nuevo a 0...

Si lo que quieres es no complicarte demasiado, haz lo que te sugiere Modulay:

TMRO = 6
PREESCALER = 16
CONTADOR = 250

como tu ciclo de intrucción es de 1 useg, tienes:

 1useg * (256 - 6) * 16 * 250 = 1useg * 1000000 = 1seg (milisegundo arriba, milisegundo abajo por los testeos... jeejjeej)

Saludos!

ok, tomo nota de los valores

aunque siento una ligera curiosidad.  Entonces una pregunta, en la interrupción del timer, en cuanto salta,comprueba flags, recarga y vuelve a lanzar timer, se están perciendo ciclos, de manera que la siguiente temporización empezaría con un ligero retraso. ¿es así no?

Desconectado Modulay

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2651
Re: timer 0 para 1 seg.
« Respuesta #10 en: 21 de Enero de 2007, 08:23:05 »
Es obvio que algo de imprecisión se comete por esas cuestiones.
Si tu sistema requiere una temporización estricta tendrías que llevar la cuenta exacta de cuantos ciclos consumes durante el tratamiento de la interrupción y ajustar la configuración del timer para cuadrar los tiempos.
En todo esto influye también el lenguaje que estés usando.Siempre será más óptimo usar ensamblador.En el caso de que tu programa no use más interrupciones que la del temporizador,te puedes ahorrar el testeo de flags.
Para paliar ese retraso por el tiempo de proceso en la rutina de interrupción se puede poner la recarga del timer en primer lugar,así,nada más producirse la interrupción y el salto a su correspondiente rutina,lo primero que harás será volver a poner a correr al temporizador,habiendo perdido un ciclo máquina si no me equivoco (el del salto).Eso,en tu caso supondría un error de 1 us cada 4 ms,es decir,1 segundo -> 250 interrupciones -> 250 us de error (retraso) en cada segundo,que se irían acumulando y sumándose tras cada segundo (en una hora ya sería casi 1 segundo de error acumulado).
Con esto de cargar el timer como primera acción hay que tener cuidado,ya que hay que hacerlo sólo si estas seguro de que no va a provocar que te inhiba una proxima interrupción por seguir dentro de la rutina de tratamiento de la misma.
Rizando más el rizo...
De todo esto tiene la culpa el que tengamos que recargar el timer.Si no tuvieramos que hacerlo (dejar al timer dar vueltas él solito),el timer interrumpiría de forma continua cada 256 cuentas,invirtiendo para ello de forma exacta el mismo intervalo de tiempo (siempre y cuando no esté inhibido).Esto nos vale pa echar un par de números:

T = (256 - 0) * 16 * 4 / Fosc
=> T * Fosc = 256 * 64
=> T * Fosc = 16384

Seguimos necesitando que T sea divisor exacto de 1 segundo.Estableciéndolo a un valor concreto,obtendríamos un valor concreto para la frecuencia del cristal.Si le damos a T el valor 1 (una interrupción cada segundo),obtenemos un valor para el cristal de 16384 Hz.Si no me equivoco,ese es un valor comercial muy querido por los amantes de los relojes en tiempo real :D
« Última modificación: 21 de Enero de 2007, 08:31:11 por Modulay »

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: timer 0 para 1 seg.
« Respuesta #11 en: 21 de Enero de 2007, 09:40:25 »
Para conseguir una temporización exacta, como te indica Modulay, hay que tener en cuenta los ciclos que consume tu interrupción.
Para ello, lo mejor que se ha inventado es la ventana Stopwatch de MPLAB, dentro del menú Debugger.
Es muy fácil de usar; pones un breakpoint al comienzo de tu interrupción y ejecutas la simulación. Cuando se pare le pulsas el botón Zero a la ventana Stopwatch lo que reseteará los contadores de ciclos y tiempo. A continuación ejecutas paso a paso y vas viendo cómo se incrementa hasta llegar a la línea que te interesa, que es la nueva precarga del timer.

Desconectado manwenwe

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2211
Re: timer 0 para 1 seg.
« Respuesta #12 en: 21 de Enero de 2007, 10:36:19 »
Una única puntualización a la buena explicación de Modulay:
Citar
habiendo perdido un ciclo máquina si no me equivoco (el del salto).

Las instrucciones de salto utilizan 2 ciclos de instrucción pues no se conoce la siguiente instrucción hasta que se produce el salto...

Saludos!
Ojo por ojo y todo el mundo acabará ciego - Mahatma Gandhi -

Desconectado black_flowers

  • PIC18
  • ****
  • Mensajes: 450
Re: timer 0 para 1 seg.
« Respuesta #13 en: 21 de Enero de 2007, 17:40:02 »
muchas gracias, por aclararlo, yo siempre pensé que el timer era algo en tiempo real 100%, lo tendré en cuenta

un saludo.   :-)