Temporizador 0 Interrupción xc8

3

RESUELTO: Pongo aquí mi código, ¡espero que ayude a alguien! ^^ CONSEJO: Mi problema fue porque estaba comparando si PORTBbits.RB3 == 0 o == 1; la solución ha estado comparando una variable en lugar de un estado.

#include <xc.h>
#include<plib/timers.h>

#define _XTAL_FREQ 40000000

unsigned char config1;
unsigned int timer_value;
unsigned int tpr;
int counter=0;

void main(void) {


TRISBbits.RB3 = 0;
PORTBbits.RB3 = 0;


   // 1/1 prescalar
   T1CONbits.T1CKPS1 = 1;
   T1CONbits.T1CKPS0 = 1;

   // Use Internal Clock
   T1CONbits.TMR1CS = 0;

   // Timer1 overflow interrupt
   PIE1bits.TMR1IE = 1;

   // Enable Timer 1
   T1CONbits.TMR1ON = 1;

   INTCONbits.PEIE = 1; // Enable Perpherial Interrupt
   INTCONbits.GIE = 1; // Enable Global Interrupt

   while(1)
   {

   }
}

void interrupt high_priority lowISR(void) {
if (PIR1bits.TMR1IF == 1) {

    if(counter == 0)
    {
        PORTBbits.RB3 = 1;
        counter = 1;

    }
    else if(counter == 1)
    {
        PORTBbits.RB3 = 0;
        counter = 0;
    }
    TMR1 = 0X00;

    PIR1bits.TMR1IF = 0;
}
}

En primer lugar, me presento! Soy Manuel y como puedes ver soy nuevo en esta web. ¡Ayudaré tanto como pueda!

En segundo lugar, estoy trabajando con PIC18F2520 con el compilador XC8 y quiero recibir un código infrarrojo. Para eso, necesito trabajar con Timers para la lectura de la señal, pero no lo hago funcionar. He estado buscando este tema y no lo he encontrado.

Consejo: la configuración de Pragma está escrita en otro archivo.

Cuando ejecuto este código en proteus, parece hacer cualquier cosa. ¿Cual podría ser el problema? Por cierto, en realidad estoy usando mi PIC18 con un oscilador externo.

Muchas gracias!

¿Cuál podría ser el problema? ¿Podrían ser las definiciones pragma?

EDITAR: código actualizado en la publicación principal, perdón por todos los inconvenientes!

    
pregunta Manuel Joaquín

1 respuesta

1

Personalmente, prefiero nunca usar las macros "simplificadas" proporcionadas por Microchip. Ocultan lo que te está pasando y nunca aprendes lo que realmente estás haciendo con el hardware.

Observo que en realidad no estás activando las interrupciones en tu código. Tienes que hacerlo manualmente tú mismo.

Este es un fragmento de código que uso, manipulando directamente los registros en lugar de usar las macros, que habilitan el temporizador 0 para tics de 1 ms en un PIC18:

// Set up TIMER0 to tick at 1ms intervals.
// The oscillator ticks at Fosc/4, so 4MHz. That is 1/16000000 s per tick.
// or 0.000000063s, or 0.000063ms, so 1 ms is 16000 ticks.
T0CONbits.T08BIT = 0; // 16-bit
T0CONbits.T0CS = 0; // Internal clock
T0CONbits.PSA = 1; // No prescaler
uint16_t tpr = (F_CPU/4)/1000;
tpr = 0xFFFF - tpr;
TMR0H = tpr >> 8;
TMR0L = tpr & 0xFF;
INTCONbits.T0IF = 0; // Clear the flag
INTCONbits.T0IE = 1; // Enable the interrupt
INTCONbits.PEIE = 1; // Turn on peripheral interrupts  <-- This is needed by you
INTCONbits.GIE = 1; // ... and global interrupts  <-- As is this
T0CONbits.TMR0ON = 1; // and finally set the period.

Y luego mi ISR se ve como:

void interrupt low_priority __isr_handler(void) {
    if (INTCONbits.TMR0IE && INTCONbits.T0IF) {
        INTCONbits.T0IF = 0;
        uint16_t tpr = (F_CPU/4)/1000;
        tpr = 0xFFFF - tpr;
        TMR0H = tpr >> 8;
        TMR0L = tpr & 0xFF;
        __millis++;
    }
}

Una razón por la que prefiero hacer la manipulación manual de registros es que puedes decidir exactamente en qué orden se hacen las cosas. Observas que primero hago todas las configuraciones: configurar el temporizador, las interrupciones, todo, y solo una vez todo eso. está hecho, realmente enciendo el temporizador.

    
respondido por el Majenko

Lea otras preguntas en las etiquetas