PIC18F452 timer0 no es exacto

0

Estoy simulando un proyecto en el software de simulación Proteus usando este microcontrolador. Mi problema es que he hecho una interrupción de 2 segundos en el timer0. Pero la simulación lo muestra como demasiado rápido (w.r.t reloj de simulación).

Usé la calculadora del temporizador Mikroelectronica usando estos ajustes:

Elesquemadesimulacióneselsiguiente:

Estoy usando MikroC pro para compilador PIC. Y sí, he verificado dos veces la frecuencia del reloj en el compilador, del cristal de cuarzo y la MCU en proteus, todos son de 4 MHz. También he establecido el cristal como XT en el compilador.

¿Cuál podría ser la razón detrás de este temporizador inexacto?

El código que estoy usando es el que se muestra a continuación:

int toggle1 = 0;
int toggle2 = 0;
int toggle3 = 0;
int toggle4 = 0;

void InitTimer0(){
  T0CON  = 0x84;
  TMR0H  = 0x0B;
  TMR0L  = 0xDC;
  TMR0IF_bit = 0;
  TMR0IE_bit     = 1;
}

void Interrupt() {
  if (INT0IF_bit && INT0IE_bit) {
     INT0IF_bit = 0;
     if(toggle1 == 0){
          LATC0_bit = 1;
          LATC2_bit = 0;
          toggle1 = 1;
          INTEDG0_bit = 1;         // Interrupt on rising edge on RB0
     }
     else{
          LATC0_bit = 0;
          toggle1 = 0;
          INTEDG0_bit = 0;         // Interrupt on falling edge on RB0
     }
   }
   if (INT2IF_bit && INT2IE_bit) {
     INT2IF_bit = 0;
     if(toggle2 == 0){
          LATC3_bit = 1;
          LATC2_bit = 0;
          toggle2 = 1;
          INTEDG2_bit = 1;         // Interrupt on rising edge on RB0
     }
     else{
          LATC3_bit = 0;
          toggle2 = 0;
          INTEDG2_bit = 0;         // Interrupt on falling edge on RB0
     }
   }
   if (INT1IF_bit && INT1IE_bit) {
     INT1IF_bit = 0;
     if(toggle3 == 0){
          LATC0_bit = 1;
          LATC2_bit = 0;
          toggle3 = 1;
          INTEDG1_bit = 1;         // Interrupt on rising edge on RB0
     }
     else{
          TMR0IE_bit     = 1;
          toggle3 = 0;
          INTEDG1_bit = 0;         // Interrupt on falling edge on RB0
          delay_ms(500);
          LATC0_bit = 0;
     }
   }
   if (TMR0IF_bit){
    TMR0H    = 0x0B;
    TMR0L    = 0xDC;
    if(toggle1 == 0 && toggle3 == 0)
          LATC2_bit = 0;
    if(toggle4 == 0){
         LATC4_bit = 1;
         toggle4 = 1;
    }
    else{
         LATC4_bit = 0;
         toggle4 = 0;
    }
   }

}

void main() {

  ADCON1 = 0x07;           // All digital I/O
  RBPU_bit = 0;

  TRISB = 0xFF;            // Set PB0 as input
  TRISC = 0x00;            // Set PortD as output
  PORTC = 0x00;            // Starting value for PortD

  INTEDG0_bit = 0;         // Interrupt on falling edge on RB0
  INTEDG1_bit = 0;         // Interrupt on falling edge on RB1
  INTEDG2_bit = 0;         // Interrupt on falling edge on RB2

  INT0IF_bit = 0;          // Clear INT0IF
  INT0IE_bit = 1;          // turn OFF interrupt on INT0

  INT1IF_bit = 0;          // Clear INT1IF
  INT1IE_bit = 1;          // turn OFF interrupt on INT1

  INT2IF_bit = 0;          // Clear INT2IF
  INT2IE_bit = 1;          // turn OFF interrupt on INT2

  InitTimer0();

  GIE_bit = 1;             // enable GIE

  while(1){}
}
    
pregunta Mohsin Anees

1 respuesta

2

Probablemente porque no está borrando el indicador de interrupción Timer0 en su controlador de interrupciones.

Necesitas tener un TMR0IF_bit = 0; ; de lo contrario, tu código se quedará atascado en la interrupción, repitiéndolo una y otra vez.

    
respondido por el brhans

Lea otras preguntas en las etiquetas