CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

help with timer1

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Forest
Guest







help with timer1
PostPosted: Wed May 14, 2003 3:35 pm     Reply with quote

Howdy Picsters

I know this is a well worn subject, I'm probably missing the point but I can't get my 16F877 to count in seconds.
Ive checked out the forum, everyone says you can do it but my timer 1 with a 32kHz watch crystal across RC0 & RC1 doesn't work.

My crystal is not resonating, this could be the problem but I thought this may be something to do with the output of the PIC not being set right.

Am confused on whether to use T1_EXTERNAL, T1_EXTERNAL_SYNC and what exactly does T1_CLK_OUT do??
I calculate that the number of interupts per second should be 0.5 (32768/65536) - is this correct? how would u put this in code as it is not an integer.

My code is attached - any advice would be fantastic.

Forest



#include <16f877.h>
#fuses hs,nowdt,noprotect,put,nowrt,nolvp
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#define INTS_PER_SECOND 1 // (32768/65536) not sure about this line

byte seconds=0;
byte int_count;


#int_timer1 // This function is called every time
clock_isr() { // (timer1) overflows (255->0).
// For this program this is apx 0.5 times
if(--int_count==0) { // per second???.
++seconds;
printf("\n\rSeconds: \%d", seconds);

int_count=INTS_PER_SECOND;
}

}


main() {

int_count=INTS_PER_SECOND;
set_timer1(0
___________________________
This message was ported from CCS's old forum
Original Post ID: 144514466
Tomi
Guest







Re: help with timer1
PostPosted: Thu May 15, 2003 1:06 am     Reply with quote

A setup example:
setup_timer_1(T1_DIV_BY_1 | T1_EXTERNAL | 0x08);
// the last 0x08 enables the internal oscillator; unfortunately CCS C has a constant T1_DISABLED but doesn't have T1_ENABLED and the default state is to disable the oscillator :)

The 0.5 rate means that you will get Timer1 IT in every 2 seconds. If it is affordable for you then you can simply use:
seconds += 2;
instead of
++seconds;
If you want to get ITs in every 1 second then you can use:
Set_Timer1(32768);
as the first instruction of the IT handler (and additionally you have to check that the IT latency is less than 1/32768 = 30usec)
___________________________
This message was ported from CCS's old forum
Original Post ID: 144514476
Kenny



Joined: 07 Sep 2003
Posts: 173
Location: Australia

View user's profile Send private message

Re: help with timer1
PostPosted: Thu May 15, 2003 1:23 am     Reply with quote

:=Howdy Picsters
:=
:=I know this is a well worn subject, I'm probably missing the point but I can't get my 16F877 to count in seconds.
:=Ive checked out the forum, everyone says you can do it but my timer 1 with a 32kHz watch crystal across RC0 & RC1 doesn't work.
:=
:=My crystal is not resonating, this could be the problem but I thought this may be something to do with the output of the PIC not being set right.
:=
:=Am confused on whether to use T1_EXTERNAL, T1_EXTERNAL_SYNC and what exactly does T1_CLK_OUT do??
:=I calculate that the number of interupts per second should be 0.5 (32768/65536) - is this correct? how would u put this in code as it is not an integer.
:=
:=My code is attached - any advice would be fantastic.
:=
:=Forest

First, you didn't say why you are using an external oscillator instead of counting the internal fosc/4, ie 4000000/4 = 1MHz together with the prescaler.
There are several points if you really want to use the external oscillator. Interrupts will only occur every two seconds at best unless you preload the counter with half the maximum count every time an interrupt occurs ie 0x7fff.
Read the timer1 module section of the pdf for the PIC16F87X.

1. Two capacitors of 33pF are needed with the 32.768kHz crystal.
2. The oscillator needs to be enabled with bit T1OSCEN (T1CON.3)
3. The counter needs to be enabled with bit TMR1ON (T1CON.0)

Define these bits as necessary,
#bit timer1_osc_en = 0x10.3
#bit timer1_on = 0x10.0

4. External needs to be selected as the clock source and the prescaler set.
eg.
setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1);

Setup timer 1 overflow interrupts:
enable_interrupts(INT_TIMER1);
enable_interrupts(global);

5. Don't use printf within the interrupt service routine, far too much code to process. Instead, set a flag for main().

short one_sec_fl;

#int_timer1
timer1_isr() {
++seconds;
one_sec_fl = 1;
set_timer1(0x7fff); // Preload half

}

timer1_osc_en = 1;
timer1_on = 1;

main() {
while(1) {
if (one_sec_fl) {
one_sec_fl = 0;
printf("\n\rSeconds: \%d", seconds);
}
}
}

Don't need to worry about T1_EXTERNAL_SYNC unless you need to synchronise the external oscillator with the internal phase clocks. Not sure what T1_CLK_OUT does.

Regards
Kenny





:=#include <16f877.h>
:=#fuses hs,nowdt,noprotect,put,nowrt,nolvp
:=#use delay(clock=4000000)
:=#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
:=
:=#define INTS_PER_SECOND 1 // (32768/65536) not sure about this line
:=
:=byte seconds=0;
:=byte int_count;
:=
:=
:=#int_timer1 // This function is called every time
:=clock_isr() { // (timer1) overflows (255->0).
:= // For this program this is apx 0.5 times
:= if(--int_count==0) { // per second???.
:= ++seconds;
:= printf("\n\rSeconds: \%d", seconds);
:=
:= int_count=INTS_PER_SECOND;
:= }
:=
:=}
:=
:=
:=main() {
:=
:= int_count=INTS_PER_SECOND;
:= set_timer1(0
___________________________
This message was ported from CCS's old forum
Original Post ID: 144514478
Forest
Guest







Re: help with timer1
PostPosted: Thu May 15, 2003 3:16 am     Reply with quote

Hi Kenny/Tomy
Thanks for your replies.
I wanted to use an external oscillator in order to achieve a reasonably accurate real time clock relying on the 32kHz crystal - it is supposed to give an exact (supposed!!) non-prescaled interupt interval. I can't see any reason why I can't - I suppose i could implement the internal osc/4 with prescaler - I just thought this would be easier.

The 16F877 data sheet does suggest 33pF but other text has suggested other values (as per manufacturer) - I'm using 12.5pF
I didn't realise you would have to set the register direct - I assumed that the set commands would cover this.
Pre-loading the counter makes sense - TA
The mystery of T1_CLK_OUT continues - I've seen it used in the EX_STWT.C but it relates to RTCC???

Sorry about the multiple posts before - I kept getting errors and thought I was doing something wrong - apparently the server was full up or something.


:=:=Howdy Picsters
:=:=
:=:=I know this is a well worn subject, I'm probably missing the point but I can't get my 16F877 to count in seconds.
:=:=Ive checked out the forum, everyone says you can do it but my timer 1 with a 32kHz watch crystal across RC0 & RC1 doesn't work.
:=:=
:=:=My crystal is not resonating, this could be the problem but I thought this may be something to do with the output of the PIC not being set right.
:=:=
:=:=Am confused on whether to use T1_EXTERNAL, T1_EXTERNAL_SYNC and what exactly does T1_CLK_OUT do??
:=:=I calculate that the number of interupts per second should be 0.5 (32768/65536) - is this correct? how would u put this in code as it is not an integer.
:=:=
:=:=My code is attached - any advice would be fantastic.
:=:=
:=:=Forest
:=
:=First, you didn't say why you are using an external oscillator instead of counting the internal fosc/4, ie 4000000/4 = 1MHz together with the prescaler.
:=There are several points if you really want to use the external oscillator. Interrupts will only occur every two seconds at best unless you preload the counter with half the maximum count every time an interrupt occurs ie 0x7fff.
:=Read the timer1 module section of the pdf for the PIC16F87X.
:=
:=1. Two capacitors of 33pF are needed with the 32.768kHz crystal.
:=2. The oscillator needs to be enabled with bit T1OSCEN (T1CON.3)
:=3. The counter needs to be enabled with bit TMR1ON (T1CON.0)
:=
:=Define these bits as necessary,
:=#bit timer1_osc_en = 0x10.3
:=#bit timer1_on = 0x10.0
:=
:=4. External needs to be selected as the clock source and the prescaler set.
:=eg.
:=setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1);
:=
:=Setup timer 1 overflow interrupts:
:=enable_interrupts(INT_TIMER1);
:=enable_interrupts(global);
:=
:=5. Don't use printf within the interrupt service routine, far too much code to process. Instead, set a flag for main().
:=
:=short one_sec_fl;
:=
:=#int_timer1
:=timer1_isr() {
:=++seconds;
:=one_sec_fl = 1;
:=set_timer1(0x7fff); // Preload half
:=
:=}
:=
:=timer1_osc_en = 1;
:=timer1_on = 1;
:=
:=main() {
:=while(1) {
:=if (one_sec_fl) {
:=one_sec_fl = 0;
:=printf("\n\rSeconds: \%d", seconds);
:=}
:=}
:=}
:=
:=Don't need to worry about T1_EXTERNAL_SYNC unless you need to synchronise the external oscillator with the internal phase clocks. Not sure what T1_CLK_OUT does.
:=
:=Regards
:=Kenny
:=
:=
:=
:=
:=
:=:=#include <16f877.h>
:=:=#fuses hs,nowdt,noprotect,put,nowrt,nolvp
:=:=#use delay(clock=4000000)
:=:=#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
:=:=
:=:=#define INTS_PER_SECOND 1 // (32768/65536) not sure about this line
:=:=
:=:=byte seconds=0;
:=:=byte int_count;
:=:=
:=:=
:=:=#int_timer1 // This function is called every time
:=:=clock_isr() { // (timer1) overflows (255->0).
:=:= // For this program this is apx 0.5 times
:=:= if(--int_count==0) { // per second???.
:=:= ++seconds;
:=:= printf("\n\rSeconds: \%d", seconds);
:=:=
:=:= int_count=INTS_PER_SECOND;
:=:= }
:=:=
:=:=}
:=:=
:=:=
:=:=main() {
:=:=
:=:= int_count=INTS_PER_SECOND;
:=:= set_timer1(0
___________________________
This message was ported from CCS's old forum
Original Post ID: 144514484
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

Help with RTC
PostPosted: Thu May 15, 2003 8:30 am     Reply with quote

You should look at this. You don't need a second crystle to get an accurate RTC.
<a href="http://www.pic-c.com/forum/general/posts/6403.html" TARGET="_blank">http://www.pic-c.com/forum/general/posts/6403.html</a>
___________________________
This message was ported from CCS's old forum
Original Post ID: 144514493
Forest
Guest







Re: help with timer1 - it works & figured out T1_CLKOUT
PostPosted: Fri May 16, 2003 6:14 pm     Reply with quote

Thanks for all your help guys.
I also wanted to use an external clock for the wakeup facility. Got my circuit going after your tips and tricks got me thinking. I used the flags idea and also realised what T1_CLKOUT does: If you look at the 16F877 file and see the define for T1_CLKOUT is "8". Checked out the data sheet and realised this sets the T1CON bit3 or T1OSCENanble!!. No need to set the register with 0x08, or the set the 10.3 bit (same thing) - just OR (|) T1_CLKOUT.
I've posted my updated code FYI - thanks again fella's

#include <16f877.h>
#fuses hs,nowdt,noprotect,put,nowrt,nolvp
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#define INTS_PER_SECOND 32768 // Load half the TMR1 with for 1sec int

byte count=0;
byte seconds=0;
byte minutes=0;
byte int_count;
short one_sec_fl;

#int_timer1 // This function is called every time
clock_isr()
{ // (timer1) overflows (255->0).
++count;
one_sec_fl = 1;
set_timer1(0x7fff);
}

main() {

setup_timer_1( T1_DIV_BY_1 | T1_EXTERNAL | T1_CLK_OUT ); //setup timer1
enable_interrupts(INT_TIMER1); //setup interupts
enable_interrupts(GLOBAL);
delay_ms(5);

while(1)
{
if (one_sec_fl)
{
++seconds;
if (seconds==60)
{
++minutes;
seconds=0;
}
one_sec_fl = 0;
printf("\n\r\%d:\%d",minutes,seconds);
}
}
}
___________________________
This message was ported from CCS's old forum
Original Post ID: 144514517
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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