|
|
View previous topic :: View next topic |
Author |
Message |
saroch
Joined: 06 Oct 2004 Posts: 8
|
so confused about timer0 with 16f877 |
Posted: Tue Oct 12, 2004 3:54 am |
|
|
hi,
i'm a newbie with PIC16f877 and now i'm so confused about using timer0
here is my code
Code: |
#include <16F877.h>
#define TxD PIN_C6
#define RxD PIN_C7
#define CLOCK_SP 20000000
#fuses HS
#fuses NOLVP, NOWDT
#fuses NOPROTECT
#use delay (clock=CLOCK_SP)
#use rs232 (baud=9600, xmit=TxD, rcv=RxD)
#define use_portb_lcd
#include <lcd.c>
void main ()
{
long time;
lcd_init();
while(1)
{
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_2);
printf(lcd_putc, "\f"); lcd_gotoxy(1,1);
printf(lcd_putc, "DIV_2");
delay_ms(1000);
set_timer0(0);
delay_cycles(18);
time = get_timer0();
printf(lcd_putc, "\n");
printf(lcd_putc, "Time : %lu us", time);
delay_ms(1000);
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_4);
printf(lcd_putc, "\f"); lcd_gotoxy(1,1);
printf(lcd_putc, "DIV_4");
delay_ms(1000);
set_timer0(0);
delay_cycles(18);
time = get_timer0();
printf(lcd_putc, "\n");
printf(lcd_putc, "Time : %lu us", time);
delay_ms(1000);
}
}
|
and the output is
DIV_2
Time : 8 us
DIV_4
Time : 4 us
please tell me what this output comes from??
thank you in advance
saroch |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
|
Posted: Tue Oct 12, 2004 5:23 am |
|
|
A slight problem with logic.
The timer is counting up from zero. Divide by 4 means that it takes twice as many input clocks as divide by two to get the same count. Your sample program line Code: | time = get_timer0(); |
could more accurately be represented as
Code: | timer_count = get_timer0(); |
therefore the count value for divide by 2 should be double the count value for divide by 4 giving you the result you observed
Last edited by asmallri on Tue Oct 12, 2004 5:54 am; edited 1 time in total |
|
|
Ttelmah Guest
|
|
Posted: Tue Oct 12, 2004 5:47 am |
|
|
You seem to be accessing te timer fine. All the timer is, is a 'counter'. It counts at a rate, dependant on the speed of the clock fed into it. The clock comes from the main incoming crystal (RTCC_INTERNAL), divided by four, then divided by the prescaler.
So in your first case, the clock is actually running at 20000000/(4*2) = 2500000Hz.
Now you pause for 18 'cycles'. Each instruction 'cycle' on the PIC, is four counts of the main clock. So the pause is for (18*4)/20000000 second = 36uSec. In 36uSec, the 2.5MHz clock will have counted 0.0000036/(1/2500000) times. This potentially gives 9 as the 'answer'. However you then have to consider the actual operation deeper in the chip. Because values are transferred from the internal 'W' reg, into other registers, at the end on the instruction cycle, but are read 'in', at the start of the cycle, you 'lose' one count edge, on the instruction after the transfer. The same happens in the other case. Hence you see a count of 8 and 4.
Best Wishes |
|
|
saroch
Joined: 06 Oct 2004 Posts: 8
|
|
Posted: Tue Oct 12, 2004 8:24 am |
|
|
just nearly CLEAR !!
but
what about
is this line for tell us what ??
thank you very much |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Tue Oct 12, 2004 9:28 am |
|
|
The command: set_timer0(0) simply sets timer0's counter to zero(0). If you had entered set_timer0(250) it would have set the counter to 250. In either case, the timer will count up to 255 and then roll over to zero again, at which time the interrupt will occur. This can be a bit tricky though because it takes a few clock cycles to complete this command so your 'count' could be slightly off from what you might think it to be.
Ronald |
|
|
saroch
Joined: 06 Oct 2004 Posts: 8
|
|
Posted: Tue Oct 12, 2004 10:06 am |
|
|
i understand set_timer0 like this
set_timer0(value)
where value = 256-(Tdelay/prescaler)*(fosc/4)
so i'm confused why using set_timer0(0) in that code
what does set_timer0(0) means in my understanding |
|
|
Ttelmah Guest
|
|
Posted: Tue Oct 12, 2004 10:51 am |
|
|
saroch wrote: | i understand set_timer0 like this
set_timer0(value)
where value = 256-(Tdelay/prescaler)*(fosc/4)
so i'm confused why using set_timer0(0) in that code
what does set_timer0(0) means in my understanding |
The counter, just counts. The value in Timer0, is incremented everytime the incoming 'clock' (including prescalers etc.), cycles.
If you set timer0 to 10, then the count will go 10,11,12.....255,0 etc..
The 'Tdelay' useage, comes from the fact that there is an extra circuit associated with the timer, which sets the timer0 interrupt flag (and generates an interrupt if this is enabled), when the timer increments from 255 to 0 (since it is an '8 bit' counter, it can only get to 255).
Hence if you want to delay for 50 'cycles' of the clock feeding the timer, you would want to set the timer to 216 (the 'wrap' is when you go from 255 to 0, which corresponds to a count of '256'). The formula you give, is how to calculate the value needed.
The code you posted, does not use the 'delay' ability of the counter, but just it's ability to count. To make the count start at '0', te counter is set to this value before starting.
I suggest you go to the Microchip website, and get document number 70059b, which is the manual for the timers on the chips. Remember that everything that applies to 16bit timers, also applies to the 8bit units, just with the 'wrap', taking place at 255->0, instead of at 65535->0.
Best Wishes |
|
|
saroch
Joined: 06 Oct 2004 Posts: 8
|
|
Posted: Tue Oct 12, 2004 10:59 am |
|
|
thanks for the help |
|
|
|
|
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
|