Interruptor de tiempo que se llama cada vez - Pic16F877A y CCS PIC C

4

Actualmente estoy probando el siguiente ejemplo

#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)


#INT_TIMER1
void TimerOverflow() 
{
    printf("Timer Overflowed\r\n");
}

void main() 
{
   long time;
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_TIMER1);

   set_timer1(8000); //count till 8000 then overflow
   time = get_timer1();
     while(1)
     {
     }

}

Sin embargo, se supone que la función de interrupción debe llamarse cada vez que (casi) 8 segundos, pero se llama como si el retraso fuera de 0 segundos. ¿Qué estoy haciendo mal aquí?

    
pregunta MistyD

1 respuesta

5

Creo que entendiste mal las funciones del temporizador. Según tu comentario, estás asumiendo que set_timer1 establecerá el valor que el temporizador cuenta. Pero lo que realmente sucede es que establece el temporizador 1 en el valor 8000. La interrupción del temporizador se activa cada vez que el temporizador se desborda. Debido a que timer1 es un temporizador de 16 bits, esto sucede cuando el contador llega a 65535. Por lo tanto, la primera vez que el temporizador cuenta de 8000 a 65535, activa la interrupción, restablece el contador a 0 y cuenta de nuevo a 65535, activa la interrupción, y así sucesivamente.

Deje que \ $ f \ $ sea la frecuencia de reloj, entonces es el intervalo de tiempo \ $ T \ $ su interrupción se activa: $$ T = \ frac {4 \ cdot2 ^ {16}} {f} $$ Entonces, para una frecuencia de reloj de 1Mhz, su interrupción se dispara cada 262 ms, para un 20Mhz se dispara cada 13 ms.

Lo que debe hacer para obtener un retraso mayor es aumentar el número de contadores de software en su rutina de interrupción. Pero con tu reloj de 20Mhz obtienes estos 13 ms impares. Lo que necesita para obtener un buen número como 10 ms es contar hasta 50000 (reorganizar la fórmula desde arriba). Entonces, lo que puede hacer es inicializar el temporizador no a 0 sino a \ $ 2 ^ {16} - 50000 = 15536 \ $ (esta vez con la función set_timer1 ). Lo último es aumentar el contador de software mencionado cada vez que se desencadena la interrupción. Cuando tu variable tiene un valor de 8000, ya sabes, que han transcurrido 8 segundos.

Debería leer la hoja de datos para la foto, especialmente el capítulo 6 'Módulo Timer1', para comprender mejor lo que está sucediendo y cómo utilizar su microcontrolador pic

    
respondido por el PetPaulsen

Lea otras preguntas en las etiquetas