# TIMER0 in PIC18F4550

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

if(i==4)
{
//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)

=0.25MHz

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.

Thank You.

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

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.

• 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? – Mohit Apr 19 '15 at 0:28
• 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. – Majenko Apr 19 '15 at 0:43
• 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 – Mohit Apr 19 '15 at 7:33
• 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. – Majenko Apr 19 '15 at 8:07