Autor Tema: Problema Precisión Timer0 - SOLUCIONADO (INTERESANTE)  (Leído 9862 veces)

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

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18310
    • MicroPIC
Re: Problema Precisión Timer0 - SOLUCIONADO (INTERESANTE)
« Respuesta #15 en: 15 de Octubre de 2008, 05:54:48 »
¿Porqué Pocher?, si siempre tarda lo mismo y podemos descontar su efecto no veo la razón por la que no debería ser preciso.

Desconectado DarkVect

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 302
Re: Problema Precisión Timer0 - SOLUCIONADO (INTERESANTE)
« Respuesta #16 en: 15 de Octubre de 2008, 08:05:56 »
En los data de los PIC e incluso en el data general donde se recogen los aspectos comunes de éstos NO dice nada en contra de escribir sobre el registro del timer. De hecho lo único que remarcan es esa inhabilitación del conteo durante dos ciclos de reloj. Eso es exacto y preciso.

Lo que ya no tengo claro es lo de escribir sobre el Timer1. Si miráis el data genérico pone que no es recomendable hacer escrituras sobre el registro bajo del timer, por lo que según entiendo sólo se podrían cargar valores múltiplos de 256 que son los que van en el registro alto. Alguna idea sobre esto?

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5490
    • Electrónica Didacta
Re: Problema Precisión Timer0 - SOLUCIONADO (INTERESANTE)
« Respuesta #17 en: 15 de Octubre de 2008, 13:07:51 »
No tengo muy claro que la reducción de 2 ciclos en la precarga del TMR0 consiga hacer ir bien a un reloj. Habría que probarlo, personalmente creo que lo mejor para conseguir una base de tiempos exacta es no hacer precargas con el set_timer0.

conseguir la presición de un timer, es poco probable, porque caeriamos en el tema de factores externos, sobreencabezamientos (overhead) en lenguajes de alto nivel, etc. Lo mejor en estos casos:

Citar
la mejor prueba es simular el código (mplab ó proteus) y ajustar los tiempos si se da el caso.

La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado Marttyn

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1836
    • IDEAA
Siguen sin darme los calculos :?
« Respuesta #18 en: 03 de Noviembre de 2008, 00:35:40 »
No me dan los calculos  :?
Estuve leyendo el post, y por lo visto el Timer0 pierde 2 ciclos con la pregarga... por lo visto esto no afecta al timer1 segun lei en algun lado...
Pero aun asi no me dan los calculos... quiero contar 20mS (20.000uS) y para ello uso el timer1 con precarga de 45535 (65535 - 45535 = 20000)
Los resultados son estos:



Como se ve en el stop watch, me paso por 39 (TREINTAYNUEVE  :shock:) instrucciones. Seria comprensible que me pasara por 7 instrucciones (4 para la precarga y 3 pasa retomar el programa), ya que es lo que se demora dentro de la interrupcion.... pero donde esta todo el tiempo que me sobra?

el codigo lo reduje a lo mas simple... osea, solo la interrupcion:

Código: C
  1. #include <12F683.h>
  2. #device adc=8
  3.  
  4. #FUSES NOWDT,NOMCLR,PUT,INTRC_IO
  5. #use delay(clock=4000000)
  6.  
  7. #int_TIMER1
  8. void TIMER1_isr(void) {
  9.         set_timer1(45535);
  10. }
  11. void main() {
  12.        
  13.         setup_adc_ports(NO_ANALOGS|VSS_VDD);
  14.         setup_adc(ADC_CLOCK_INTERNAL);
  15.         setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
  16.         setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
  17.         setup_timer_2(T2_DISABLED,0,1);
  18.         setup_comparator(NC_NC);
  19.         setup_vref(FALSE);
  20.         disable_interrupts(INT_TIMER0);
  21.         enable_interrupts(INT_TIMER1);
  22.         enable_interrupts(GLOBAL);
  23.         setup_oscillator(OSC_4MHZ);
  24.        
  25.         set_timer1(45535);
  26.  
  27.         do{                    
  28.  
  29.         }while(TRUE);  
  30. }

haciendo un par de pruebas veo que desde el momento que se produce INT_TIMER1 tarda 35 instrucciones en llegar a la primer instruccion dentro de la interrupcion (ahi estan los 39 ciclos perdidos, 35 + 4 ciclos de precarga). Pero no solo eso! una vez acabada la ISR del timer, le lleva 26 instrucciones mas retomar el programa donde estaba  :shock: :shock:
Como es eso posible? Es por la traduccion de C a ASM? o en ASM pasa lo mismo?
Ahora entiendo porque nunca pude hacer andar un servo a la perfeccion! es imposible generar los 20mS exactos sin estar al tanto de todas estas cosas  :mrgreen:
« Última modificación: 04 de Noviembre de 2008, 00:44:06 por Marttyn »
La gente ve las cosas que existen y se pregunta por qué.
Yo prefiero imaginar lo que no existe y preguntarme por qué no.

Desconectado Marttyn

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1836
    • IDEAA
Re: Problema Precisión Timer0 - SOLUCIONADO (INTERESANTE)
« Respuesta #19 en: 03 de Noviembre de 2008, 02:01:26 »
Haciendo mas pruebas veo que para entrar en las ISR lleva unas cuantas instrucciones desde que se produce la interrupcion:
TMR0: 39 instrucciones
TMR1: 36 instrucciones
TMR2: 41 instrucciones
CCP1: 41 instrucciones

Salir de estas interrupciones y retomar el programa consume 26 instrucciones para cualquiera de ellas.
Estas pruebas las hice con un 12F683, en modo debug con el stop watch de mplab, y usando lenguaje C.
Alguna conclusion?  :z)

Si alguien quiere comprobar o continuar con estas pruebas dejo el codigo fuente que use. Solo hay que comentar y descomentar las lineas necesarias para probar cada interrupcion
La gente ve las cosas que existen y se pregunta por qué.
Yo prefiero imaginar lo que no existe y preguntarme por qué no.

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18310
    • MicroPIC
Re: Problema Precisión Timer0 - SOLUCIONADO (INTERESANTE)
« Respuesta #20 en: 03 de Noviembre de 2008, 03:41:52 »
Sí, Marttyn, eso pasa siempre con las interrupciones: hay que salvar el contexto y determinar qué tipo de interrupción es antes de devolver el control al programa.
Cuando sales de la interrupción hay que dejar el contexto como estaba.
Todo eso consume los ciclos que tú dices.

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Problema Precisión Timer0 - SOLUCIONADO (INTERESANTE)
« Respuesta #21 en: 03 de Noviembre de 2008, 04:25:47 »
Buenas.

Lo que comentás es completamente cierto y existe, tanto en C como en ASM.
Esas 35 instrucciones que comentas son seguramente las que guardan los registros clave(como el W,STATUS,FSR...) y hacen la selección de cuál interrupción se produjo. Voy a destacar que en ASM bajo ciertas condiciones y truquillos es posible achicar bastante ese número de instrucciones. En el caso de un compilador ya no es tan sencillo ya que deberías modificar el ASM de salida a mano para lograrlo.

Las importantes son las instrucciones antes de ser atendida una interr. y no las que tarda en salir de la ISR(al menos para los Timers con tiempos medianos o grandes). A esto lo digo porque no interesa si tarda 10 o 100 instrucciones antes de salir de la ISR, ya que el Timer estará contando igualmente aunque se encuentre dentro de la ISR. Obviamente supongo que estará más que sobreentendido que no es necesario que el uC se encuentre fuera de la ISR para que un timer cuente ;).

Ahora, si nos vamos a poner en exquisitos hay muchísimos factores a considerar. Ya han mencionado varios: los 2 ciclos de ejecución durante los cuales el timer no se incrementa cuando se carga un valor en su registro, las instrucciones antes de llegar a realmente precargar el timer y otras que no se han comentado como, por ejemplo,  cuando se produce una interrupción, el uC automáticamente carga el vector 0x004(en el pic que exponés, 12F683) y eso lleva 2 ciclos de instrucción(es una especie de "call 0x004"). Además, puede que la interrupción tarde en producirse un poco más entre que el Timer se desborda y el uC realmente se percata de esto(CREO que son 2 ciclos más en el caso del TMR0). Dependiendo del tipo de interrupción, el uC puede tardar más en detectarla. Por ejemplo, una interrupción por cambio de estado del puerto b(RB4-RB7) lleva entre 3 y 4 ciclos de ejecución antes de que el uC se percate de que realmente se produjo y efectivice la interrupción.

En definitiva: lo que necesitás sencillamente es agregar a la formulita un numerito más que represente todos esos ciclos adicionales que hay que contemplar según la interrupción(y según lo que al compilador le de la gana (que es un verdadero trastorno, ya que también depende de su versión)).

Tiempo de desbordamiento =  [(256-TMR0) * PREESCALER + A+ 4 + B] * (4/FOSC)

A= 2 si  es que hay precarga del TMR0
B= número de instrucciones antes de que se se precargue el TMR0

Los cuatro ciclos adicionales correspondes 2 al tiempo de sincronísmo entre los relojes del uC, y dos más del call 0x004. Tal vez eso demuestre la incongruencia entre tus cálculos teóricos iniciales y los del programita que usabas para calcularlos.

Si no se precarga el registro TMR0, A no exíste y B no tiene importancia(se ignora).

Saludos.



"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado DarkVect

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 302
Re: Problema Precisión Timer0 - SOLUCIONADO (INTERESANTE)
« Respuesta #22 en: 03 de Noviembre de 2008, 08:53:27 »
Marttyn el problema que creo que tienes con el timer1, al cual NO aplica lo de la deshabilitación durante 2 ciclos después de escribirlo, es que según entiendo yo del Datahseet NO se debe escribir en su registro bajo. Es decir, en los set_timer1 diría que hay que cargar valores múltiplos de 256 para no modificar ese registro bajo.

Alguien puede confirmar esto?

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Problema Precisión Timer0 - SOLUCIONADO (INTERESANTE)
« Respuesta #23 en: 03 de Noviembre de 2008, 15:43:22 »
Hola DarkVect.

No puedo confirmarlo, tampoco refutarlo completamente pero desde mis humildes conocimientos diría que lo que comentás no es posible. El Timer1 consta de dos registros: TMRH y TMRL y ambos son leibles/escribibles. Si querés podés no escribir el registro bajo, pero no vas a lograrlo con la instrucción set_timer1 ya que seguramente siempre te escriba ambos indiferentemente del valor que le cargues.

Saludos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado Marttyn

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1836
    • IDEAA
Re: Problema Precisión Timer0 - SOLUCIONADO (INTERESANTE)
« Respuesta #24 en: 03 de Noviembre de 2008, 18:34:32 »
Gracias Bruno!
Muy buena tu explicacion! Seguire con las pruebas y estudiare algo de ASM para poder optimizar el codigo  lo mas posible cuando sea necesario :mrgreen:

Por cierto, DarkVect lo de la precarga solo con multiplos de 255, no lo se, pero como dice bruno, cuando haces un set_timer1() se generan las respectivas instrucciones en ASM para escribir tanto en la parte alta como en la parte baja del registro del timer, por lo que si el compilador lo hace asi, no deberia haber problemas por ello...
La gente ve las cosas que existen y se pregunta por qué.
Yo prefiero imaginar lo que no existe y preguntarme por qué no.

Desconectado DarkVect

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 302
Re: Problema Precisión Timer0 - SOLUCIONADO (INTERESANTE)
« Respuesta #25 en: 03 de Noviembre de 2008, 21:53:05 »
Bueno, que el compilador lo haga así no asegura que sea lo correcto ya que en los ejemplos que da en el manual no tienen enuenta los dos ciclos de deshabilitación del Timer0, por ejemplo.

Aquí un datasheet como ejemplo. En la pág. 59 columna derecha lo explica, pero ahora que lo miro bien es para cuando se usa como Contador Asíncrono. También podría ser que CCS parase el timer, escribiese y lo volviese a poner en marcha, cosa que también significaría algunos ciclos de retraso.

http://ww1.microchip.com/downloads/en/DeviceDoc/39598e.pdf

Desconectado Marttyn

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1836
    • IDEAA
Re: Problema Precisión Timer0 - SOLUCIONADO (INTERESANTE)
« Respuesta #26 en: 04 de Noviembre de 2008, 01:12:27 »
Gracias a todos por salpicarme con su sabiduria!  :-/
Mientas mas me explicais, mas aprendo y mas ganas de saber tengo! Pero mis preguntas se estan desviando del tema principal de este POST, asi que retomare mis dudas aqui:
http://www.todopic.com.ar/foros/index.php?topic=23662.0
Si alguien quiere pasarse por ahi se lo agradezco!
Salu2
La gente ve las cosas que existen y se pregunta por qué.
Yo prefiero imaginar lo que no existe y preguntarme por qué no.