1
\$\begingroup\$

I want to generate Interrupt(on PIC18f4550 using TIMER0) every 1 sec but by using the following code interrupt is generated after every 6 secs.

#include<pic18f4550.h>

#pragma config PLLDIV = 5 , CPUDIV = OSC1_PLL2 , USBDIV = 2    

#pragma config FOSC = INTOSCIO_EC
#pragma config FCMEN = OFF                                 
#pragma config BORV = 3
#pragma config WDT = OFF
#pragma config CPB = OFF
#pragma config CPD = OFF

void intinter(void);
void inittimer(void);
void interrupt low_priority timerinterrupt(void);
 void main()
{
TRISB =0x00; // Port B as output for LCD
PORTB =0xff;
intinter(); // Initialise Interrupt
inittimer(); // Initialise Timer
TMR0ON =1;   // Timer 0 on
while(1);
}
 void intinter(void)
{
RCONbits.IPEN =1; //Low priority enable
INTCON = 0b11100000; //timer 0 interrupt enable
INTCON2bits.TMR0IP = 0; //set timer 0 int. low priority
}
void inittimer(void)
{
T0CON = 0b00000111; //prescaler of 256, 16 bit, internal clock
TMR0H = 0xED;  // Set TMRH and L Value
TMR0L = 0xB0;
}
void interrupt low_priority timerinterrupt (void)
{
 if(TMR0IF == 1)
    {
        TMR0ON =0;//Timer 0 off
        TMR0IF = 0; //Timer 0 IF disable
        TMR0H = 0xED;
        TMR0L = 0xB0;
        PORTB = ~ PORTB; //complement  port B
        TMR0ON = 1; //Timer 0 on
        }
}

I am setting the internal clock at 20MHz and I think the problem is in the values of TMR0L and TMR0H. Can someone please guide me, how to set correct values for these and get 1sec interrupt if it is possible. Or there is another way to do it.

Thank you.

\$\endgroup\$
  • \$\begingroup\$ You say you're "setting the internal clock at 20MHz". How exactly are you achieving this? The internal oscillator only goes up to 8MHz and you can't run it through the PLL on this PIC. \$\endgroup\$ – brhans Mar 10 '15 at 19:31
  • \$\begingroup\$ I am new to microcontroller programming so I am sorry if I have some topics not well versed. But I thought #pragma config PLLDIV = 5 did that. Am I wrong? \$\endgroup\$ – Mohit Mar 10 '15 at 19:45
  • \$\begingroup\$ Look at the diagram on page 24 of the datsheet. The internal oscillator is not connected to the PLL module. To use the PLL you have to supply your PIC with en external crystal or clock. \$\endgroup\$ – brhans Mar 10 '15 at 21:00
1
\$\begingroup\$

Timer 0 is not well suited to long but precise periodic interrupts. You can do short interrupts by using timer 0 in 8 bit mode with a presscaler of 1, but those are limited to 256 cycles. You also have to understand the timer very well to not loose any cycles each period.

Timer 2 is a better answer since it has a built-in period register. Perhaps you can't get a time as long as 1 s, but that can be easily created by counting a number of faster but accurate timer 2 interrupts. At the least you can set up timer 2 to interrupt every few 1000 cycles, so the overhead of counting a few of those before you get to 1 second is noise.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.