Autor Tema: Problema al Calcular TMR0. Se atrasa  (Leído 6417 veces)

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

Desconectado kaki

  • PIC18
  • ****
  • Mensajes: 260
Re: Problema al Calcular TMR0. Se atrasa
« Respuesta #15 en: 25 de Septiembre de 2013, 23:40:13 »
Hice lo que me dijiste, recalcule el tiempo para 48Mhz y en ves de 1 segundo tengo 4,37 aproximadamente.. con ++nRTCC==100 como tiene q ser para 10ms


Claramente esta mas rapido, pero sigue sin ser el esperado...

Saludosss

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Problema al Calcular TMR0. Se atrasa
« Respuesta #16 en: 26 de Septiembre de 2013, 00:11:41 »
Es muy extraño...

Podrías probar haciendo parpadear un LED cada 1 segundo (usando delay_ms()) y contando por ejemplo 30 parpadeos a ver si se obtiene el tiempo esperado?

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 BBMNet

  • PIC12
  • **
  • Mensajes: 91
Re: Problema al Calcular TMR0. Se atrasa
« Respuesta #17 en: 27 de Septiembre de 2013, 11:31:17 »
Si me permiten una opinión.

Recordándo la variación por las tolerancias de los componentes incluyendo el propio PIC y el cristal, es un tanto dificil lograr un ajuste exacto.

En mi caso hacemos diseños que se hacen para más de un dispositivo y al principio siempre tuvimos esos problemas de ajuste. Dejábamos bien el dispositivo de ingeniería pero al pasar a producción cada dispositivo era diferente.

La solución fué, dependiéndo de la aplicación, utilizar una señal a partir de un cruce de cero de la línea de alimentación o de un oscilador externo al PIC. Estas señales disparan la interrupción para el servicio.

Espero que esta experiencia les ayude.

Un saludo.

Desconectado aldoMO

  • PIC10
  • *
  • Mensajes: 18
Re: Problema al Calcular TMR0. Se atrasa
« Respuesta #18 en: 28 de Abril de 2015, 10:09:31 »
hola a todos, tengo un problema muy similar..
estoy usando un pic 18f2550, lo que intento hacer es:
contar la cantidad de pulsos que ingresan por la interrupción externa en 1 minuto... mi problema es que la cuenta se retrasa muchisimo.
la verdad no encuentro el error, espero que puedan ayudarme.
uso un cristal de 20mhz, y coloque un led q enciende por 500ms aproximadamente para saber cuando "en teoría se cumple 1 minuto".
configure el timer de manera que el mismo deborde cada 1 segundo, y con un contador cuento hasta 60 para contar 1 minuto.
gracias de antemano!

#include <18f2550.h>
#use delay(clock=20000000)
#fuses HS,NOWDT,NOPROTECT,NOLVP,PUT,NODEBUG,BROWNOUT,NOCPD,NOWRT,NOFCMEN,CPUDIV1
#define LCD_DB4   PIN_B4
#define LCD_DB5   PIN_B5
#define LCD_DB6   PIN_B3
#define LCD_DB7   PIN_B7
#define LCD_RS     PIN_B1
#define LCD_RW    PIN_B2
#define LCD_E      PIN_B6
#define LED       PIN_A3
#priority EXT, RTCC



#include "flex_lcd_c.c"

//variables
int segundo=0;
int bandera1=0;
int contador=0;
float lluvia=0;

#int_RTCC
void  RTCC_isr(void)
{
segundo++;                                                                     
if(segundo==60)                                                                 
   {
   bandera1=1;
   segundo=0;
   }                                                         
set_timer0(26473);
}


#int_EXT
void  EXT_isr(void)
{
contador++;
}



void main()

   lcd_init();
   output_float(pin_b0);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_128);
   enable_interrupts(INT_RTCC);
   enable_interrupts(INT_EXT);
   ext_int_edge(l_to_h);
   enable_interrupts(GLOBAL);
   setup_timer_3(T3_DISABLED | T3_DIV_BY_1);
   setup_comparator(NC_NC_NC_NC); 

   set_timer0(26473);
   printf(lcd_putc,"\f");              //borrar lcd
   lcd_gotoxy(4,1);
   printf(lcd_putc, "pluviometro");
   delay_ms(500);
   while(TRUE)
   {
      if(bandera1==1)
    {
      output_high(LED);
      lluvia=contador*0.2;
      printf(lcd_putc,"\f");
      lcd_gotoxy(1,1);
      printf(lcd_putc, "contador=%d",contador);
      lcd_gotoxy(1,2);
      printf(lcd_putc, "lluvia %f mm",lluvia);
      contador=0;
      bandera1=0;
      delay_ms(500);
      output_low(LED);
    }
  }

}

Desconectado juaperser1

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 2976
Re: Problema al Calcular TMR0. Se atrasa
« Respuesta #19 en: 28 de Abril de 2015, 10:34:17 »
El problema que tienes es los delay no puedes usar delay en una aplicación que tenga que llegar una base de tiempo o seguir un tiempo real. Cuando pones un del ay tu micro se esta parando sin hacer absolutamente nada, en tu caso tu micro esta parado 500ms sin hacer nada por cada vez que realiza el bucle.

Si quieres llevar una base de tiempos nunca uses del ay, usa timers

Un saludo
Visita mi canal para aprender sobre electrónica y programación:

https://www.youtube.com/channel/UCxOYHcAMLCVEtZEvGgPQ6Vw

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Problema al Calcular TMR0. Se atrasa
« Respuesta #20 en: 28 de Abril de 2015, 10:52:12 »
No entiendo a que te referis con:

Citar
mi problema es que la cuenta se retrasa muchisimo.

El tiempo no es exactamente 60s ? es 50s o 70s ?
O que los pulsos no son los exactos ?

Yo creo que los delays no son problemas. Siempre y cuando no los pongas dentro de las interrupciones o utilizes variables que no queres que cambien en ese momento.

Por ejemplo en tu programa utilizas la variable contador, donde hay delays o instrucciones largas como las del LCD, esto hace que si viene un pulso mientras esta haciendo esa "animacion" no las cuente.
Una solucion es crear una nueva variable y al ocurrir la condicion de 60 segundos copiarla a esa variable, la otra es desactivar las interrupciones por ese momento. Me explico:

Código: C
  1. void  RTCC_isr(void)
  2. {
  3. segundo++;                                                                      
  4. if(segundo==60)                                                                
  5.    {
  6.    bandera1=1;
  7.    segundo=0;
  8.    variableparaLCD = contador;
  9.    contador = 0;
  10.    }                                                        
  11. set_timer0(26473);
  12. }

Código: C
  1. if(bandera1==1)
  2.     {
  3.       output_high(LED);
  4.       lluvia=variableLCD*0.2;
  5.       printf(lcd_putc,"\f");

Otra cosa es que nunca vas a tener 1 segundo exacto usando eso. Por todas las instrucciones de mas en ASM que hay y por que con 20Mhz no llegas a que sea 1 segundo exacto.

Otra ademas es que siempre vas a tener que esperar que llegue a los 60 segundos para que comienze la cuenta de vuelta. por que podes agarrarlo a los 40 segundos y solo te quedaria o mediria 20 segundos de pulsos entrantes.
La solucion seria que en primera interrupcion externa, habilite el timer o la interupcion del timer y cargue el valor. Cuando llega a 60 segundos el timer solo se desabilita y modifica una flag para esperar otro pulso que lo habilite por 60 segundos mas.
Todo depende de como queres que funcione tu programa

Desconectado aldoMO

  • PIC10
  • *
  • Mensajes: 18
Re: Problema al Calcular TMR0. Se atrasa
« Respuesta #21 en: 28 de Abril de 2015, 11:18:26 »
El problema que tienes es los delay no puedes usar delay en una aplicación que tenga que llegar una base de tiempo o seguir un tiempo real. Cuando pones un del ay tu micro se esta parando sin hacer absolutamente nada, en tu caso tu micro esta parado 500ms sin hacer nada por cada vez que realiza el bucle.

Si quieres llevar una base de tiempos nunca uses del ay, usa timers

Un saludo


Muchas gracias por responder juaperser1, efectivamente, tenias razon, era eso mi problema, no supuse que eso provocaría ese error...
En la simulación me andaba bien, pero en la realidad tenia unos problemas...
No quiero abusar, pero ahora mi problema es otro..
Al iniciar la ejecución, siempre siempre hace 1 cuenta, sin que ingrese ningún pulso.
A que puede deberse que cuente una interrupción sin que la misma exista realmente?

Desconectado juaperser1

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 2976
Re: Problema al Calcular TMR0. Se atrasa
« Respuesta #22 en: 28 de Abril de 2015, 11:19:42 »
Hola killer es cierto que hay muchos programas donde puedes usar los delay sin problemas, pero es una instrucción que yo la veo contraproducente en todos los sentidos, que el micro se pare sin hacer nada no es lo mejor ( lo mismo que en un while) yo hace tiempo que las desterre al igual que los while ( que no sea el del bucle principal) y tan contento, la programación se complica bastante es cierto pero yo prefiero no usarlos.

No digo que un programa hecho con delay con cuidado, sea mejor ni peor. Pero yo ni los uso ni los recomiendo. :D :D
Visita mi canal para aprender sobre electrónica y programación:

https://www.youtube.com/channel/UCxOYHcAMLCVEtZEvGgPQ6Vw

Desconectado aldoMO

  • PIC10
  • *
  • Mensajes: 18
Re: Problema al Calcular TMR0. Se atrasa
« Respuesta #23 en: 28 de Abril de 2015, 11:20:35 »
El problema que tienes es los delay no puedes usar delay en una aplicación que tenga que llegar una base de tiempo o seguir un tiempo real. Cuando pones un del ay tu micro se esta parando sin hacer absolutamente nada, en tu caso tu micro esta parado 500ms sin hacer nada por cada vez que realiza el bucle.

Si quieres llevar una base de tiempos nunca uses del ay, usa timers

Un saludo


Muchas gracias por responder juaperser1, efectivamente, tenias razon, era eso mi problema, no supuse que eso provocaría ese error...
En la simulación me andaba bien, pero en la realidad tenia unos problemas...
No quiero abusar, pero ahora mi problema es otro..
Al iniciar la ejecución, siempre siempre hace 1 cuenta, sin que ingrese ningún pulso.
A que puede deberse que cuente una interrupción sin que la misma exista realmente?

Desconectado juaperser1

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 2976
Re: Problema al Calcular TMR0. Se atrasa
« Respuesta #24 en: 28 de Abril de 2015, 11:31:33 »
Citar
  A que puede deberse que cuente una interrupción sin que la misma exista realmente?

Están referenciadas las masas de lo que produce la interrupción y el micro? Cuando Enciendes la maquina también se enciende lo que produce las interrupciones? Al encenderse quizás lo que produce la interrupción cambio el pin de estado lógico, mira a ver si es eso, si es eso ponle un retraso al micro hasta que todo este ya inicializado y pasa a funcionamiento normal.

También debes tener en cuenta lo que te ha dicho killer nunca vas a tener un tiempo exacto con los 20mhz, las cuentas se te atrasaran, para contar tiempo en segundo horas días... de manera estable necesitas un rtcc y un cristal de 32,768khz
Visita mi canal para aprender sobre electrónica y programación:

https://www.youtube.com/channel/UCxOYHcAMLCVEtZEvGgPQ6Vw

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Problema al Calcular TMR0. Se atrasa
« Respuesta #25 en: 28 de Abril de 2015, 11:36:36 »
Citar
Pero yo ni los uso ni los recomiendo

Yo soy tambien asi, a veces son necesarios y no hay con que darle, como esperar 2us que seria insensato hacer una interrupcion por timer y lleva mas tiempo de procesamiento.
Aca en el foro me encontre con personas que por ahi no tienen claro el tema de los timers o interrupciones, y tratar de hacerle entender a esa persona lo que es un timer es complejo.
Ademas de intentar cambiarle la forma de pensar en su programacion, lo que le trae mas dolores de cabeza a el y a vos. Por eso muchas veces voy por los delays. O intento seguir su forma de programacion.

Citar
Al iniciar la ejecución, siempre siempre hace 1 cuenta, sin que ingrese ningún pulso

Proba antes de habilitar las interrupciones globales de limpiar las banderas de interrupcion de ambos.

Desconectado juaperser1

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 2976
Re: Problema al Calcular TMR0. Se atrasa
« Respuesta #26 en: 28 de Abril de 2015, 11:43:11 »
Citar
Yo soy tambien asi, a veces son necesarios y no hay con que darle, como esperar 2us que seria insensato hacer una interrupcion por timer y lleva mas tiempo de procesamiento.
Aca en el foro me encontre con personas que por ahi no tienen claro el tema de los timers o interrupciones, y tratar de hacerle entender a esa persona lo que es un timer es complejo.
Ademas de intentar cambiarle la forma de pensar en su programacion, lo que le trae mas dolores de cabeza a el y a vos. Por eso muchas veces voy por los delays. O intento seguir su forma de programacion.

Si, tienes razón, cambiar el concepto de delay por timer no es fácil, sobre todo si la persona no tiene claro lo que es el primer. Pero bueno todos pasamos por hay tarde o temprano jeje
Visita mi canal para aprender sobre electrónica y programación:

https://www.youtube.com/channel/UCxOYHcAMLCVEtZEvGgPQ6Vw

Desconectado aldoMO

  • PIC10
  • *
  • Mensajes: 18
Re: Problema al Calcular TMR0. Se atrasa
« Respuesta #27 en: 28 de Abril de 2015, 11:48:17 »

hola KILLERJC , gracias por responder...


Citar
Por ejemplo en tu programa utilizas la variable contador, donde hay delays o instrucciones largas como las del LCD, esto hace que si viene un pulso mientras esta haciendo esa "animacion" no las cuente.
Una solucion es crear una nueva variable y al ocurrir la condicion de 60 segundos copiarla a esa variable, la otra es desactivar las interrupciones por ese momento.

muy bueno lo que me propones, lo voy a poner en practica...

Citar
Otra cosa es que nunca vas a tener 1 segundo exacto usando eso. Por todas las instrucciones de mas en ASM que hay y por que con 20Mhz no llegas a que sea 1 segundo exacto.


esto si lo tuve en cuenta, y creo q para lo que necesito me es suficiente con contar las interrupciones externas en un cierto tiempo, aproximadamente 1 segundo..

Citar
Otra ademas es que siempre vas a tener que esperar que llegue a los 60 segundos para que comienze la cuenta de vuelta. por que podes agarrarlo a los 40 segundos y solo te quedaria o mediria 20 segundos de pulsos entrantes.
La solucion seria que en primera interrupcion externa, habilite el timer o la interupcion del timer y cargue el valor. Cuando llega a 60 segundos el timer solo se desabilita y modifica una flag para esperar otro pulso que lo habilite por 60 segundos mas.
Todo depende de como queres que funcione tu programa

Esta propuesta me interesa, xq asi cuando no se produzca una interrupción externa no estaría haciendo correr al timer en vano, y es mas, hasta podría poner el pic en sleep y despertarlo con la interrupción externa, verdad? podría hacer esto para disminuir el consumo al máximo... si no es mucho pedir, explicarme como poner el pic en sleep y como despertarlo? o sea, como funciona?

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Problema al Calcular TMR0. Se atrasa
« Respuesta #28 en: 28 de Abril de 2015, 12:05:05 »
El tema es si realmente necesitas ahorrarte esos miliamperes por ponerlo a Sleep, cuando tu LCD consume tal ves unas 10 veces mas.
Por ejemplo a 5V y 40Mhz el PIC consume de 21 a 40mA, suponete unos 15 a 20mA con esa frecuencia.

Por otra parte el Timer0 NO puede sacarte del sleep. Suponete que recibas 1 solo pulso, pase a sleep y nada mas en 60 segundos. No despertaria hasta que volvieras a dar otro pulso.
A pesar que el diagrama dice que si, en el datasheet dice que el Timer0 no corre, cuenta en modo SLEEP.

Otra cosa, al despertar del SLEEP espera varios ciclos antes de volver a ejecutar instrucciones ya que apaga todos los osciladores. Esto repercutiria en tu "tiempo". son unas 1024 ciclos de reloj + unos 2ms de POR ( creo que era ese )
Vale la pena hacer todo esto ? xD

Eso SLEEP, Luego hay otros modos como es el PRI_IDLE que solo desabilita el clock al nucleo, pero sigue alimentando a los perifericos con el clock. Reasumiendo la operacion en 10us como maximo
Igual no se cuanto sera el ahorro en este modo, parece ser casi la mitad de corriente que cuando esta normalmente corriendo ( PRI_RUN )
« Última modificación: 28 de Abril de 2015, 13:00:44 por KILLERJC »

Desconectado aldoMO

  • PIC10
  • *
  • Mensajes: 18
Re: Problema al Calcular TMR0. Se atrasa
« Respuesta #29 en: 06 de Mayo de 2015, 10:55:06 »
Citar
Proba antes de habilitar las interrupciones globales de limpiar las banderas de interrupcion de ambos.

hola KILLERJC, estuve leyendo para hacer lo que me decis de limpiar la bandera, e hice lo siguiente:
primero definí el byte intcon, y luego vi en el datasheet que el flag que se pone en 1 cuando hay una interrupcion es el INT0IF, y lo puse a cero antes de habilitar las interrupciones globales, y si funciono...  pero no estoy seguro si lo que hice esta bien...

#byte INTCON=0xff2
#bit INT0IF=0xff2.1
...........
........
.........
void main()

   lcd_init();
   output_float(pin_b0);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_128);
   enable_interrupts(INT_RTCC);
   enable_interrupts(INT_EXT);
   ext_int_edge(l_to_h);
   INT0IF=0;
   enable_interrupts(GLOBAL);
.........
.....
..
}



esta bien esto?..
creo q si, porque asi ya no me cuenta siempre 1 cada vez que arranca...




 

anything