Autor Tema: PROBLEMAS CON EL TIEMER0 SE RETRASA  (Leído 2239 veces)

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

Desconectado mauroc146

  • PIC10
  • *
  • Mensajes: 3
PROBLEMAS CON EL TIEMER0 SE RETRASA
« en: 25 de Agosto de 2016, 00:49:31 »
saludos.

Tengo un problema con el timer0 como temporizador de 0ms a 8ms, se retrasa al hacer un delay_ms en el void main() del programa.

Anteriormente hice un programa para controlar un triac usando el timer1 y no tuve inconvenientes, pero ahora lo quise hacer con el timer0, porque el timer1 lo usare para otro propósito, y no puedo hacerlo funcionar

He simplificado el código para encontrar en que estaba fallando y encontré que cuando pongo algún delay de cualquier valor en void main(), el timer0 deja de trabajar como debería.
Si quito los delay y lo simulo en el proteus funciona bien.

He leído que el timer0 es independiente del programa principal y es por eso que, no sé que estoy haciendo mal :( 
Gracias por su atención


#include <16F876A.h>
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#use delay(crystal=4000000)
#use FIXED_IO( B_outputs=PIN_B4,PIN_B3,PIN_B2 )

#INT_EXT                                     
void  EXT_isr(void)
{                                                 //uso la interrupcion por pin_b0 para el cruce por cero de la red
set_timer0(120);                         // aqui cargo el valor del timer0 para el desbordamiento
enable_interrupts (INT_TIMER0);  // que sera de 0ms a 8ms para un control de 0º a 180º +-
}

#INT_TIMER0
void  TIMER0_isr(void)
{
   DISable_interrupts (INT_TIMER0);
      output_high(pin_b4);                 // cuando se desborde el timer0 activa al triac
          delay_ms(1);                         //   y espera a la interrupcion externa para activar y cargar
      output_low(pin_b4);                  //      nuebamente al timer0
       
}


void main()
{
       
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_32|RTCC_8_bit);      //8.1 ms overflow
   enable_interrupts(INT_TIMER0);
   enable_interrupts(INT_EXT);     
   enable_interrupts(GLOBAL);

   while(TRUE)
   {
         
         output_high(pin_b4);   //activo una salida para que aga algo el programa
           delay_ms(1);            //el problema es cuando pongo un delay de cualquier valor
         output_low(pin_b4);    //el timer0 deja de funcionar periodicamente (hace cualquier cosa)
           delay_ms(1);           
         
   }

}

adjunto dos imagenes de la simulacion en proteus

* 1.jpg
(102.38 kB, 1024x576 - visto 374 veces)

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:PROBLEMAS CON EL TIEMER0 SE RETRASA
« Respuesta #1 en: 25 de Agosto de 2016, 08:21:22 »
Te respondi antes:

- Quita delays de las interrupciones
- Limpia la bandera del TMR0 antes de activarlo
- Usa otra salida entre la interrupcion y el loop principal. Para ver si realmente esta fallando.

Desconectado mauroc146

  • PIC10
  • *
  • Mensajes: 3
Re:PROBLEMAS CON EL TIEMER0 SE RETRASA
« Respuesta #2 en: 25 de Agosto de 2016, 11:54:40 »
Gracias KILLERJC por la respuesta

Tienes razón el problema fue el delay dentro la interrupción. Lo quite y funciona bien

Pues mira  que no había leído que no se debían usar delay dentro de las interrupciones, pues poco a poco se aprende más

Gracias por la pronta respuesta

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:PROBLEMAS CON EL TIEMER0 SE RETRASA
« Respuesta #3 en: 25 de Agosto de 2016, 13:43:11 »
No solo delays, sino que todo aquello que ocupe demasiado tiempo deberia ser sacado de las interrupciones.

El obejtivo de la interrupcion es que atienda la misma y salga rapidamente. Asi seguir ejecutando el loop principal. Si es necesario hacer algo que ocupe mas tiempo, entonces usas una variable de 1 bit, la pones en 1 en la interrupcion, y luego en tu programa principal lees la variable y ejecutas el codigo que sea.

Con un buen entendimiento del programa es posible poner delays en las interrupciones, suponiendo que no tengas mas interrupciones ni sea demasiado importante lo del main. Pero mejor evitarlas.


 

anything