Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

PIC18F instruction timing

Status
Not open for further replies.

rbfowler9

Newbie level 3
Joined
May 12, 2010
Messages
3
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Location
Brazil
Activity points
1,311
Hi,

I need to create a precision timer for my PIC18F13K50 application. I'm running it at 8MHz with the 4x PLL enabled, resulting in a 0.125us instruction clock.

Are all PIC instructions single-clock? I'm building my delay routines around a Timer 0 set to 1:1 (no prescaler), so the timer clock period is also 0.125us. I tried counting to 8 achieve a 1us delay, but it seems that the needed instructions plus some controller latency are longer than 8 clock cycles, and the microcontroller hangs because of repeated interrupt recursion (I guess).

Trying to achieve a 5us delay, I tried counting to 40, but it results in a delay quite longer than 5us...

Here's my current code, I'm using MPLAB:

Code:
#pragma code high_vector=0x08;
void int_high_vector(void)
{
_asm GOTO timer_isr _endasm
}
#pragma code

#pragma interrupt timer_isr(void)
{
// clear flag
INTCONbits.TMR0IF=0;

// count to 40
TMR0L=-40;

// my internal counter, declared globally elsewhere
T0TC++;

return
}


My delay routines are simple compares with the current T0TC timer counter:


Code:
timer_now=T0TC;
// if T0TC period were 5us, then 1ms would be 200 T0TC "ticks"
while (timer_now + 200 >= T0TC);

Am I missing something?
 

Apparently you want a precise counter but you don't really want to let the timer to do it. So instead of keeping the counter value in a variable how about letting the timer run and look for it's value only? Or better, generate an interrupt when you need to do something (something more than just incrementing a value). Of course, your interrupts must not be triggered faster than your microcontroller can deal with them.
 

benradu,

That's precisely what I'm doing. I set the Timer 0 up so that it generates an interrupt on overflow and the timer counter TMR0L is increased every cycle (1:1 prescaler).

Then I write (255 - x) to the TMR0L, being "x" the number of cycles that I want between interrupt triggers (in this case, x=40, since I have a instruction cycle of 0.125us, so the interrupt would be triggered at each (0.125 * 40 = 5 us).

However, it seems that there are additional cycles wasted in the ISR servicing, since the 40-cycle interrupt trigger period end up elapsing more than the expected 5 us.

The timer counter variable is just a trick so I can count anywhere from the lowest timer resolution (5us in this case) to a bunch of seconds without having to reprogram the timer's prescaler and counter at every delay function call. I could rely solely on the PIC's Timer 0 internal counter, but it's only 16-bit at best, and would count up to 8192us only with a 1:1 prescaler.
 

OK. Yes, the processor will spend some time to save and restore the context, that is registers that will be affected in interrupt. So you can't rely on instant interrupt servicing. That holds true for any processor in this world.
Now that I understand better what you try to do I suggest to use the 16 bit timer to count up to the max value and when it overflows you can trigger an interrupt in which you increment a timer extension variable. This way you basically extend your timer from 16 bits to whatever you want. Then you compare the timer value and the extension with the desired delay. You don't have to reprogram the timer every time you change the delay!
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top