|
|
View previous topic :: View next topic |
Author |
Message |
Dale Stewart
Joined: 21 Apr 2005 Posts: 8 Location: Wollongong, AUSTRALIA
|
Newbie: Timer 0 Timing Correct? |
Posted: Thu Jul 14, 2005 4:50 am |
|
|
Hi
Just want to know if I am on the right track understanding the basics of how timing works.
Code: |
#include <16F876A.h>
#fuses NOWDT, NOLVP, HS, PUT, NOPROTECT
#use delay( clock = 8000000 )
#use rs232( baud = 9600, xmit = PIN_C6, rcv = PIN_C7 )
void main()
{
float time ;
int timer0_ticks, i;
setup_timer_0( RTCC_INTERNAL | RTCC_DIV_256 ) ;
//increments 8000000/(4*256) times per second
//or once every 128 us
while ( 1 == 1 )
{
//clear the timer
set_timer0( 0 ) ;
for ( i = 1; i <= 10 ; i++ )
{
printf( "\n\r%u Hello World!.", i ) ;
}
//read the ticks elapsed
timer0_ticks = get_timer0( ) ;
time = ( 128E-9 ) * timer0_ticks ;
// show the message
printf("\n\rIt took %e seconds to print 10 lines.", time ) ;
delay_ms( 5000 ) ;
}
}
|
Output ( from terminal program ):
1 Hello World!.
2 Hello World!.
3 Hello World!.
4 Hello World!.
5 Hello World!.
6 Hello World!.
7 Hello World!.
8 Hello World!.
9 Hello World!.
10 Hello World!.
It took 1.177599E-05 seconds to print 10 lines.
======================
Any comments much appreciated.
By the way, how can this output be formated to n dec places? _________________ :-]
Cheers
Dale |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Jul 14, 2005 6:15 am |
|
|
Transmitting the data will take most of the time, so the expected execution time should be around:
(17 characters * 10 bits per character * 10 lines) / 9600 baud = 0,177sec.
Your timer ticks every 128us. Total execution time is expected to be around 0,177sec.
0,177sec/128us = 1383 timer ticks
Your 8-bit timer 0 will overflow several times and calling get_timer(0) will give you a bogus execution time.
Easiest solution is to use one of the 16-bit timers instead. |
|
|
valemike Guest
|
|
Posted: Thu Jul 14, 2005 8:19 am |
|
|
Like ckielstra said, you should use a 16-bit timer instead. TMR0 on a 16F is only 8 bits, w/o the 16-bit option. On an 18F, I do have a 16-bit option.
Notice how I formatted my printf statement. I put a ".4" before the f to show only 4 decimal places. (I'm not sure what the '2' is for though).
Code: |
#include <18F448.h>
#device ADC=8
#fuses HS,NOWDT,NOPROTECT,NOLVP,PUT
#use delay(clock=8000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#ignore_warnings 202
#case
void main()
{
unsigned long this_tmr0;
unsigned int x;
float float_seconds;
BYTE start;
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_64);
set_timer0(0);
while (1)
{
printf("Press any key to begin.\n\r");
getc();
set_timer0(0);
for (x=0; x<10; x++)
{
printf ("Hello world!.\r\n");
}
this_tmr0 = get_timer0();
printf("this_tmr0 = %ld\r\n", this_tmr0);
// Calculation: 8000000 / (4 * 64) = 31250
// 1/31250 = 32 microseconds/tick
float_seconds = (float) this_tmr0 * 0.000032;
printf ("seconds elapsed is: %2.4f\r\n", float_seconds);
printf("Press any key to stop.\n\r");
getc();
}
}
|
The output is:
Code: |
Press any key to begin.
Hello world!.
Hello world!.
Hello world!.
Hello world!.
Hello world!.
Hello world!.
Hello world!.
Hello world!.
Hello world!.
Hello world!.
this_tmr0 = 4808
seconds elapsed is: .1538
Press any key to stop.
|
|
|
|
Dale Stewart
Joined: 21 Apr 2005 Posts: 8 Location: Wollongong, AUSTRALIA
|
|
Posted: Thu Jul 14, 2005 9:42 pm |
|
|
ckielstra wrote: | Transmitting the data will take most of the time, so the expected execution time should be around:
(17 characters * 10 bits per character * 10 lines) / 9600 baud = 0,177sec.
Your timer ticks every 128us. Total execution time is expected to be around 0,177sec.
0,177sec/128us = 1383 timer ticks
Your 8-bit timer 0 will overflow several times and calling get_timer(0) will give you a bogus execution time.
Easiest solution is to use one of the 16-bit timers instead. |
Thanks ck for your help and effort.
So I guess the \n\r take up two characters in the 17 characters?
OK so what u r saying is that the timer0 is reset every 128us to 0, "losing" the ticks & time that has actually passed?
So I guess that means you would have to keep track of each overflow and use a variable to keep track of all the overflows & ticks? _________________ :-]
Cheers
Dale |
|
|
Dale Stewart
Joined: 21 Apr 2005 Posts: 8 Location: Wollongong, AUSTRALIA
|
|
Posted: Thu Jul 14, 2005 10:04 pm |
|
|
valemike wrote: |
Notice how I formatted my printf statement. I put a ".4" before the f to show only 4 decimal places. (I'm not sure what the '2' is for though).
|
Hi valemike.
Thanks for your help and effort
OK thanks for the formatting tip.
I looked up Kernighan & Ritchie ( 2nd Edition, page 13 ), and the '2' is the number of characters the output is shifted to the right - hope that helps YOU.
Thanks for the code too!
Your's is a more elegant approach to my code. I just remembered that I could have used a kbhit() also instead of getc(). ( I am doing an introductory C course at TAFE college ).
I understand most of your code, but if I am not pushing my luck, could I ask about some points of your code?
#device ADC=8 - does that set ADC port bits to all digital IO?
BYTE start; - I have no clue...
Thanks for your suggestions to try 16-bits timer, will try that now. _________________ :-]
Cheers
Dale |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Jul 15, 2005 1:18 am |
|
|
Dale Stewart wrote: | So I guess the \n\r take up two characters in the 17 characters? | That's correct. The '\' character is an escape character used to indicate to the compiler that the next character has a special meaning. This is used for ASCII codes that are not representable as a visible character.
\n = carriage return (go to start of line)
\r = line feed
\t = tab
Quote: | OK so what u r saying is that the timer0 is reset every 128us to 0, "losing" the ticks & time that has actually passed? | The timer is not actually reset but is overflowing, result is the same but it's good to understand the difference. Timer0 has ony 8 bits to store the number of elapsed ticks. After counting up to 255 the maximum value it can hold is reached, adding one more tick it overflows and you will read a zero value. Compare it to normal counting with the restriction that you may only write down a single digit:
Code: | 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,...
^--- overflow |
Quote: | So I guess that means you would have to keep track of each overflow and use a variable to keep track of all the overflows & ticks? | Correct! This is one way of solving the limitation but not the easiest as it involves writing an interrupt handler. The solution I suggested was to use timer1 as it has a 16-bit counter compared to the 8-bits for timer0 and hence will overflow much later (128us * 65536 = 8,4 sec.). |
|
|
Dale Stewart
Joined: 21 Apr 2005 Posts: 8 Location: Wollongong, AUSTRALIA
|
|
Posted: Fri Jul 15, 2005 3:58 am |
|
|
Hi ck
Yep - I understand now ... you explained it very well - thanks heaps!!!
I am trying to understand a code example to use an SRF04 sonar sensor, so I need to work through timers, interrupts, and other issues.
Talk about jumping in at the deep end _________________ :-]
Cheers
Dale |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|