Electronic – Timer0 Interruption xc8

picxc8

SOLVED: I put here my code, I hope it helps someone! ^^
TIP: My problem was because I was comparing if PORTBbits.RB3 == 0 or == 1; the solution has been comparing a variable instead a state.

#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;
}
}

First of all, I introduce myself! I'm Manuel and as you can see I'm new on this web. I will help as much as I can!

Second of all, I'm working with PIC18F2520 with XC8 compiler and I want to receive an infrared code. For that, I need to work with Timers for the signal's reading, but I dont get it working. I've been looking for this topic and I haven't find it.

Tip: Pragma settings are written in other file.

When I run this code in proteus, seems to do anything. What could be the problem?
Btw, actually I'm using my PIC18 with an external oscillator.

Thank you very much!.

What could be the problem? could be the pragma definitions?


EDIT: code updated in main post, sorry for all the inconvenients!

Best Answer

Personally I prefer never to use the "simplified" macros provided by Microchip. They hide just what is going on from you and you never learn what you're really doing with the hardware.

I notice you aren't actually turning on interrupts in your code. You have to do that manually yourself.

This is a snippet of code I use, directly manipulating the registers instead of using the macros, which enables timer 0 for 1ms ticks on a 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.

And then my ISR looks like:

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++;
    }
}

One reason I prefer to do manual register manipulation is that you get to decide exactly what order things are done in. You notice I do all the setting up first - configuring the timer, the interrupts, everything - and only once all that is done do I actually turn on the timer.