I am using PIC18F4550

I am trying to generate an interrupt every 1 sec, and by trial and error(i.e. just writing and simulating on hardware ) I am getting interrupt approx to 1 sec. Code for this is:-

 #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)
RCONbits.IPEN =1; //Priority Interrupt is enabled
INTCON = 0b11100000; //all high and low priority interrupt is enabled, timer 0 overflow interrupt enable
INTCON2bits.TMR0IP = 0; //set timer 0 interrupt  low priority

void inittimer(void)
T0CON = 0b00000111; //prescaler of 256, 16 bit, internal clock
TMR0H = 0xFFFF;  // Set TMRH and L Value
TMR0L = 0x0000;

void interrupt low_priority timerinterrupt (void)
 if(TMR0IF == 1)
        TMR0ON =0;//Timer 0 off
        TMR0IF = 0; //Timer 0 IF disable
        TMR0H = 0xFFFF;
        TMR0L = 0x0000;

//if i==4 I am getting approx 1 sec interrupt.

Now after reading the datasheet and about the procedure to calculate the value of the TMR0H and TMR0L register, I am unable to make sense of my code.

As I have set internal clock with default value by just using this,

#pragma config FOSC = INTOSCIO_EC

I think the clock is Fosc = 1Mhz, so the calculation is, Our FCPU=1MHz/4 (We are running from 1Mhz Internal Clock)


Time Period = 4uS

Prescaler Period = 4 x 256 = 1.024x10^-3 (Prescaler is set to divide frequency by 256)

Overflow Period = 1.024x10^-3 x 65535 = 67.10 s (Each over flow takes 65535 counts)

So it seems each overflow takes 67 seconds but it is taking 4 overflow for 1 sec timer, how is it possible? Is my calculation procedure wrong? Or I am taking wrong clock.

Please help me understand my error as I am new to PIC programming.

Thank You.

  • \$\begingroup\$ Did you forget to initialize i properly ? \$\endgroup\$
    – Triak
    Apr 18, 2015 at 19:40
  • \$\begingroup\$ no 'i' is global value with value=0 \$\endgroup\$
    – Mohit
    Apr 18, 2015 at 20:00
  • \$\begingroup\$ It is initialized as ? \$\endgroup\$
    – Triak
    Apr 18, 2015 at 21:27
  • \$\begingroup\$ static int i=0; \$\endgroup\$
    – Mohit
    Apr 18, 2015 at 21:28
  • \$\begingroup\$ Initialize like this unsigned int i=0; \$\endgroup\$
    – Triak
    Apr 19, 2015 at 10:28

1 Answer 1


Unless you have made any changes to the oscillator settings with the OSCCON register it will default to a prescaler of /8 to give 1MHz. If that is true, then the \$F_{CY}\$ will be 256000Hz.

Your prescaler is set to 256, so the clock tick will be at \$\frac{256000}{256}=1000Hz\$

You think you're setting the overflow value to 65535, but you're not. You're actually setting the current timer's high byte to 0xFFFF (which, since it's an 8 bit register is actually 0xFF), and the timer's low byte to 0x00, so the current timer count is 0xFF00 in total. It ticks up, and when it loops from 0xFFFF to 0x0000 it triggers an interrupt. That's 256 ticks away.

So at 1000Hz divided by 256 ticks, that's \$\frac{1000}{256}=3.90625Hz.\$

Which is almost 4 times per second.

So to get exactly one second, with a 1000Hz tick, you need 1000 ticks. So you would set your timer values to 65536 minus 1000, or 64536, which is 0xFC18, so your TIMERH would be 0xFC and your TIMERL would be 0x18.

  • \$\begingroup\$ PLease explain this to me....All the config instructions that I have used in the code is given above, and the default internal oscillator value is 1Mhz for PIC18f4550 then how can you say it is operating @ 8 Mhz? \$\endgroup\$
    – Mohit
    Apr 19, 2015 at 0:28
  • \$\begingroup\$ Hold on, I misread the DS a bit. The INTOSC can go UP to 8MHz, but "On device Resets, the default output frequency of the internal oscillator block is set at 1 MHz" so unless you have changed it it'll be 1MHz. \$\endgroup\$
    – Majenko
    Apr 19, 2015 at 0:43
  • \$\begingroup\$ The only explanation I think is that the TMR0H and TMR0L registers are taking value in 8 bit so the timer is acting as a 8bit even if I have selected it to be 16bit \$\endgroup\$
    – Mohit
    Apr 19, 2015 at 7:33
  • \$\begingroup\$ TMROH and TMROL are 8 bit registers. They can hold 8 bits each. They combine to make a single 16 bit register. When you try and write 16 bits to an 8 bit register only the lowest 8 bits have any effect. Re-read my third paragraph. \$\endgroup\$
    – Majenko
    Apr 19, 2015 at 8:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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