# PIC16F877 Timer/Timing

#### CVMichael

Joined Aug 3, 2007
419
I am using a PIC16F877, using a 20MHz clock, I write code for it in mikroC

I need to find out how long some code took, for example if I have code that takes an unknown time to execute, how can I tell when the code is done, how much time it took to execute ?

Pseudocode:

Rich (BB code):
start_time = current_time;

// some code here that could take any amount of time

end_time = current_time;
time_taken = end_time - start_time;
So what I need is the "time_taken", but how ?

I would prefer to get the time in clocks, or the smallest interval possible, because I need to do things accurately.

#### beenthere

Joined Apr 20, 2004
15,819
I would imagine that the PIC's data sheet would give the execution speed of each instruction in terms of clock ticks.

Your easiest way to determine that run time of any code segment is by analysis of the hex code that executes - parse the hex file for the instructions and assign clocks to each as determined from the data sheet. Assuming there are no conditional branches, the total number of clocks over the frequency will give you execution time.

Writing the code in C or even one of the Basics wouldn't be too much of a challenge.

#### CVMichael

Joined Aug 3, 2007
419
Well, parsing HEX is beyond me... that's why I write code in C

Also, that is assuming that the code will take the same amount of time... but depending on analog input and/or other inputs, the time it takes changes...

I looked in the mikroC help, and the only reference to time I found some code that looks like this:
// Timer 0
T0CON = 0x07;
TMR0H = (65536-156) >> 8;
TMR0L = (65536-156) & 0xFF;
INTCON.T0IE = 1; // Enable T0IE
T0CON.TMR0ON = 1;

But in the whole help file, it does not say what T0CON is or what TMR0H is, etc...

I can't believe that in the help file there is no mention about timers

#### CVMichael

Joined Aug 3, 2007
419
OK, I found a good example for PIC16F877 written in MikroC, that I tested on my chip and works fine:
Rich (BB code):
unsigned int cnt;

void interrupt() {
cnt++;                   // Increment value of cnt on every interrupt
TMR0   = 96;
INTCON = 0x20;           // Set T0IE, clear T0IF
}

void main() {
OPTION_REG = 0x84;       // Assign prescaler to TMR0
TRISD = 0;               // PORTD is output
PORTD = 0xFF;            // Initialize PORTD
TMR0  = 96;              // Timer0 initial value
INTCON = 0xA0;           // Enable TMRO interrupt
cnt = 0;                 // Initialize cnt

do {
if (cnt == 400) {
PORTD = ~PORTD;      // Toggle PORTD LEDs
cnt = 0;             // Reset cnt
}
} while(1);
}
The only thing I understand there is that it executes an interrupt, that interrupt counts how many times it executes, then in the main function, it flips the bits on port D every time the counter reaches 400.

What I DON'T understand is how to set the interrupt ?
How do I set the interval ?

To be more precise, what does each line in the following do:
OPTION_REG = 0x84; // Assign prescaler to TMR0

Why 0x84 ? what is that magic number ? what is a prescaler ?

TMR0 = 96; // Timer0 initial value

Why 96 ?

INTCON = 0xA0; // Enable TMRO interrupt

Why 0xA0 ??

Also in the interrupt:
INTCON = 0x20; // Set T0IE, clear T0IF

Why 0x20 ?

Where do I find a table/description with what each value means ?

#### n9352527

Joined Oct 14, 2005
1,198
... Where do I find a table/description with what each value means ?
Datasheet.

#### CVMichael

Joined Aug 3, 2007
419
Datasheet does not explain how everything works...

But I searched the web, and I found help:
http://www61.homepage.villanova.edu/robert.popovitch/docs/servo_controller.pdf

On page 6 & 7 it explains how to calculate the values, so, in my case for a 20Mhz clock, if I want a timer to fire every millisecond, I have to set the following values:

OPTION_REG = 0x84; // Prescaler Delay = 16 cycles
TMR0 = 100; // Timer0 initial value

And the math: 20000000 / 8 / 16 / (256-100) = 1001.6

That's pretty close to what I need....

#### n9352527

Joined Oct 14, 2005
1,198
Datasheet does not explain how everything works...
Really?

#### nanovate

Joined May 7, 2007
666
Just a comment about TMR0 and the prescaler:

If you assign the prescaler to the watchdog then the timer updates every instruction (4 clocks) NOT two instructions.

#### CVMichael

Joined Aug 3, 2007
419
Really?

Yea, I tried to read the datasheet, but I could not understand almost anything...

Now that I already know it works, looking through the datasheet I understand it better (the timers section that is...), but before it was just gibberish to me...

Everything else is still gibberish to me when I look at the datasheet so it's gonna be a while until I understand everything in there...

For me this is first time doing this, so I need really basic explanations

#### CVMichael

Joined Aug 3, 2007
419
Just a comment about TMR0 and the prescaler:

If you assign the prescaler to the watchdog then the timer updates every instruction (4 clocks) NOT two instructions.
Thanks for the info, but there is something there that does not make sence to me...

First of all, before I made this thread, I thought that there is an integrated timer that keeps track of the clocks, and I thought that I could tap into that to find the time takes for parts of code to run, but it's not like that, as I know now...

If I do it the way you said, how can it run all the code ?
I mean it does one instruction per 4 clocks, right ? in my interrupt code, I have more than one instruction, so how can it run the interrupt for every 4 clocks, when the code in the interrupt is more than 4 clocks ??

Can you give me a short example on how to do it ?

Anyways, I found an even better combination of OPTION_REG / TMR0 values:

OPTION_REG = 0x81; // Prescaler Delay = 2 cycles
TMR0 = 131; // Timer0 initial value

That gives me: 20000000 / 8 / 2 / (256-131) = 10,000

I like that much better because it does exactly 10,000 interrupts per one second, so there are no rounding errors in there, and it's perfect for my needs.

PS. I made a small VB6 function that finds the values that I have to put for OPTION_REG & TMR0

#### n9352527

Joined Oct 14, 2005
1,198
Right, I understand. Datasheets are not always easy to understand or follow logical flow of writing. But they present complete information on the devices.

You will get used reading them, it is just a matter of experience and a bit of practice.