Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Difficulty with Timer0

Status
Not open for further replies.

MrNobody

New Member
Hi, I'm trying to use Timer0 to interrupt every 1ms.
I'm using PIC18F4550 running on 8MHz. The code is written in C18.
Below is the code.

Code:
#pragma code low_vector=0x18    //setup the ISR vector
	void low_interrupt (){
		 _asm GOTO LowISR _endasm    //jump to interrupt handler
	}
#pragma code

#pragma interruptlow LowISR
void LowISR()
{
    if (INTCONbits.TMR0IF == 1)
    {
	    INTCONbits.TMR0IF=0;    // Put breakpoint here and monitor the time interval using stopwatch (in MPLAB SIM).
    }
}

void main()
{
    // Counting from 6 to 255 should give 250 counts
    // Prescaler = 1:8
    // 250 * 8 * 500ns = 1ms
    TMR0L = 6;
    T0CON = 0b11000010;
    INTCONbits.GIE = 1;
    INTCONbits.PEIE = 1;
    INTCONbits.TMR0IE = 1;

    while(1);
}

What i was excepting to get is an interval of 1ms between interrupts. However, what I get is 1.024ms. 1.024 is equivalent to TMR0L = 0. Even if I set TMR0L = 255, it still give me 1.024ms. Something might have gone wrong somewhere but I'm not sure what it is.

Another things i observed is that the timer interval is not consistent. For a time of 1.024ms, the number of instructions is 2048 for FOSC = 8MHz. However, sometimes i get the interval of 2049 or 2047 instructions.

I'm not really sure whats going on there.

Can somebody please advise on these 2 difficulties.. Thanks.
 
You initialise Timer 0 with 6, then sit in a while(1) endless loop.

The timer will count from 6->255 on the first pass, but it won't be reloaded with 6 when it rolls over, from then on it will just count 0->255->0 forever.

The other difference you see in execution time will be down to the interrupt latency. Without looking it up in the datasheet I can't be specific on that.

I'd suggest you check out the Timer0 section of the datasheet, also the Midrange reference manual has more detail on Timer0 operation (you're using an 18F series device so the midrange reference is probably not applicable here)
 
Last edited:
Oh.. yeah.. I remember to load it the first time but didn't load it there after.. Thanks for pointing that out.
 
@MrNobody,

You have used a 1:8 prescaler for timer0. So when you load the timer0 with value 6 inside your ISR, you don't know what is the current count value inside the prescaler. The prescaler could clock the timer0 if its internal value is 7 and your first timer count is "short".

Therefore a more accurate method is to read the value of timer0 and waits until it has incremented from 0->1 or from 1->2 (depends on the time of the ISR rountine) and then load the timer with "7" or "8".
 
Last edited:
You might also try using timer2 instead of timer0, it's easier to use and more powerful.
Yeah, I used to use Timer2 and yeah, its powerful. However, i'm trying to expose myself to other features of PIC.. Thats why I use Timer0 just for the sake of learning how to use it.

eblc1388:
Thanks, That will surely give a more accurate interrupt.
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top