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

timer1 too slow??

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



Joined: 28 Jul 2004
Posts: 32

View user's profile Send private message

timer1 too slow??
PostPosted: Fri Dec 03, 2004 10:30 am     Reply with quote

i want to produce a variable delay by using timer1 (i can't use delay_us)
i need to adjust the delay between about 20us and 500us

what i did is to preset timer1 with (0xFFFF-mydelay) and then let it overflow. to test i inverted a0 at every overflow.

test-code looks about like this:
Code:



#int_timer1
void timer1_isr(){
   static int1 toggle;
   set_timer1(0xFFE7);
   toggle^=1;
   output_a(toggle);
}

...
setup_timer_1(T1_internal|T1_div_by_4);
enable_interrupts(global);
enable_interrupts(int_timer1);
....
while(1);


the program works but the delay is not 20us as calculated it is about 30us.

i'm using a pic16f876@20mhz
compiler version 3.208

where is the problem??
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Fri Dec 03, 2004 11:00 am     Reply with quote

The extra time is from the int handler over head. Try adding a value to timer1 to cancel the effect.

timer1 += (0xFFE7);

Be aware of overflow, your timer would have to roll through a complete cycle before you get an int.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri Dec 03, 2004 11:29 am     Reply with quote

This is the classic problem that everyone starting to work with interrupt based timers stumbles across.

You are assuming that an interrupt is an 'instant' action, requiring no time at all to start. The thing is that before entering your interrupt handler function the compiler has added several instructions for saving all the possible registers that you might change in your function.
On exiting the interrupt the compiler has again added code for restoring the previously saved registers.
On a PIC16 it takes about 18 instructions to enter the interrupt routine the same to exit again. The PIC18 has more registers and so takes even longer with approximately two times 36 instructions.

The easiest solution is to change your interrupt routine by not setting timer1 with a fixed value, but reading timer1 first and then subtract your delay from this.
Code:
#define MY_DELAY  0xFFE7

#int_timer1
void timer1_isr(){
   static int1 toggle;
   set_timer1( get_timer1() + MY_DELAY);
   toggle^=1;
   output_a(toggle);
}
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