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 CCS Technical Support

Critical timer

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



Joined: 02 Feb 2005
Posts: 9
Location: Finland

View user's profile Send private message

Critical timer
PostPosted: Fri Mar 10, 2006 5:56 am     Reply with quote

Hello

Now I have a problem with timer1, how can I speed up this timer1 interrupt service routine. This is the only thing that processor do, so there should be plenty of time to execute it. I want to get 10us pulse in every 10ms. How can I speed up this ISR? Now it takes about 13us to execute whole timer1 isr. Can someone give me an example.

Code:

#include <18F6722.h>
#DEVICE ICD=TRUE
#fuses H4,NOWDT,NOLVP,MCLR
#use delay(clock=32000000)

main()
{
setup_adc(adc_off);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);                                  //timer for generating signal
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);                                     //timer for generating pulse

enable_interrupts(int_timer0);
enable_interrupts(global);

   while(1)
   {

   }

}


#INT_TIMER0
int_timer0_isr()
{
   set_timer0(65224);                            //16bit   (1/(32000000/(4*256))*311=10ms
   enable_interrupts(int_timer1);
}

#INT_TIMER1
int_timer1_isr()
{
   set_timer1(65520);
   if(edge==0)
   {
      output_high(pin_a5);
      edge=1;
   }
   
   else if(edge==1)
   {
      output_low(pin_a5);
      disable_interrupts(int_timer1);
      edge=0;
   }
}
sjbaxter



Joined: 26 Jan 2006
Posts: 141
Location: Cheshire, UK

View user's profile Send private message Visit poster's website

PostPosted: Fri Mar 10, 2006 6:58 am     Reply with quote

Can you not just set timer0 to fire every 10ms and make the isr create the whole of the 10us pulse, ie.

Code:
#include <18F6722.h>
#DEVICE ICD=TRUE
#fuses H4,NOWDT,NOLVP,MCLR
#use delay(clock=32000000)

// 16bit   (1/(32000000/(4*256))*311 = 10ms
#define PRE_LOAD_10ms     65224

main()
{
   output_low(pin_a5);

   setup_adc(adc_off);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);  //timer for generating 10ms interval
   set_timer0(PRE_LOAD_10ms);

   enable_interrupts(int_timer0);
   enable_interrupts(global);

   while(1)
   {
   }

}

#INT_TIMER0
int_timer0_isr()
{
   set_timer0(PRE_LOAD_10ms);

   output_high(pin_a5);
   delay_us(10);
   output_low(pin_a5);
}

_________________
Regards,
Simon.


Last edited by sjbaxter on Fri Mar 10, 2006 10:26 am; edited 2 times in total
dorinm



Joined: 07 Jan 2006
Posts: 38

View user's profile Send private message

PostPosted: Fri Mar 10, 2006 7:20 am     Reply with quote

1: #use fast_io(A) , it eliminates a 2 BCFs (2x1 cycle) on TRISA
2: use

else
{ ...
}

instead of

else if(edge==1)
{ ...
}
...it eliminates a BTFSS (1,2 or 3 cycles) and a BRA (2 cycles)
try it and let us know ;)
Ttelmah
Guest







PostPosted: Sat Mar 11, 2006 10:17 am     Reply with quote

The key to understand, is that interrupts involve work. This is why on systems like the PC, it is common to find serial communication at high rates, loosing characters, except on modern units, where large hardware buffers are present. This despite having a processor, that can potentially execute hundreds of instructions in the interval between interrupts. Unfortunately, when an interrupt occurs, there is a lot of 'housekeeping', which has to happen, both before entering the interrupt routine, and then after leaving this.
As it stands, setting the timer 'on' to generate a time, works, but will cause problems if other tasks start to occur, where the time may become innaccurate, if there are a lot of other things to do. Personally, I'd always use a timer that can do the timing in 'hardware' if possible. If (for instance), you program timer2, to use 249 counts, with the /16 prescaler, and interrupt on every ten counts, you will get an interrupt every five mSec. Simply toggle a bit, and if it is set, execute the code to generate the pulse.
Now on the pulse, the 'best' solution, is to use the hardware to do this for you. The CTC channels, have the ability to clear a pin, after a programmed time, and will do this without needing a call to an interrupt handler. So:
Code:

#int_timer2
void fivems_tick(void) {
   static int1 toggle=false;
   if (toggle) toggle=false;
   else {
      toggle=true;
      CCPx=20;
      set_timer1(0);
      output_high(CCP_PIN);
   }
}

If Timer1, is set to increment on 0.5uSec counts, then this will raise the pin (you will have to select which CCP you want, and which pin it uses), and drop it automatically 10uSec latter.

Best Wishes
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