3
\$\begingroup\$
#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; } } 

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.

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


\$\endgroup\$
1
  • \$\begingroup\$ One thing I don't see in your code is anything to do with turning on interrupts, or setting the timer's interrupt to trigger a low priority interrupt signal. \$\endgroup\$ Commented Nov 16, 2014 at 11:04

1 Answer 1

2
\$\begingroup\$

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.

\$\endgroup\$
0