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

detect a timer overflow during ISR execution

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







detect a timer overflow during ISR execution
PostPosted: Fri Jul 23, 2004 1:43 pm     Reply with quote

Hi!

I have the following problem:

My InterruptServiceRoutine for timer0 overflows is not quite short...
So it happens, that the timer1-overflow-ISR cannot be executed.
But in this case, the timer0-ISR has to know, THAT THERE WAS a timer1 overflow!
How can I check this in the timer0-ISR???
Is there a flag I can simply read to see, if there was an overflow?

Thanx in advance!

[PIC16F628 @ 20Mhz]
Mark



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

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

PostPosted: Fri Jul 23, 2004 2:20 pm     Reply with quote

You should keep you ISR's short as possible. If possible, set a flag and handle in the main loop.

To answer your question, you can look at the PIR1 register and the TMR1IF flag bit.
Guest








PostPosted: Fri Jul 23, 2004 4:39 pm     Reply with quote

Thanks.

okay, I tried to keep the ISR short, but in this case it is not possible to put the code into main().
The execution of the code in the ISR is time-critical and has to be a direct reaction on the timer0 overflow.
In main() it would not be possible to react on the incoming event directly, since heavy floating point math is done there, so hundreds of instructions could pass, before the flag (which was set in the ISR before) can be read.


this is the routine:
(counter, c2, timerval are int32, numimps is byte)
Code:

#bit Timer1IF = 0xC.0
#int_RTCC
RTCC_isr()
{
timerval = get_timer1();
if(Timer1IF)timerval+=65536;  //NEW: check the overflow flag
counter*=65536;
counter+=timerval;

if(counter>15000)
{
   if(numimps!=0)
      c2+=counter;
   numimps++;
}

counter =0;
set_timer1(0);
set_timer0(255);  //cause an interrupt on next signal-change
}

#int_TIMER1
TIMER1_isr()
{
counter++;
}



as you can see, i added the TMR1IF flag test to compensate missed timer overflows.
Could that work this way?
ckielstra



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

View user's profile Send private message

PostPosted: Fri Jul 23, 2004 5:37 pm     Reply with quote

After checking the Timer1 overflow flag you need to reset it too.


Code:
if(Timer1IF)
{
  timerval+=65536;  //NEW: check the overflow flag
  clear_interrupt( INT_TIMER1 );
}


Also consider to change your code and getting rid of the 32-bit couters, they require a lot of code, for example:
Code:
counter*=65536;

This is a 32 bit x 32 bit multiplication and requires a lot of code space! Much more efficient is:
Code:
counter <<=16;


Or even better, split your counters in two 16 bit parts, counter_high and counter_low.
powerpurzel



Joined: 23 Jul 2004
Posts: 6
Location: Germany

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

PostPosted: Fri Jul 23, 2004 6:49 pm     Reply with quote

okay, I'll try the thing with clearing the flag after processing it tomorrow.

btw:
counter*=65536 and counter<<=16 produce exactly the same code, so I kept this for better readability ('cause I normally need some time to realize what happens when i do bitshifting Laughing )

and:
yes, the 32-bit-counters need much code space but the pic still has some space left, so there was no need for changing that. The 32-bit counter values are later conversed into floats and I was too lazy to code the extra math funcs myself...

thanks for your help so far...
Ttelmah
Guest







PostPosted: Sat Jul 24, 2004 8:42 am     Reply with quote

powerpurzel wrote:
okay, I'll try the thing with clearing the flag after processing it tomorrow.

btw:
counter*=65536 and counter<<=16 produce exactly the same code, so I kept this for better readability ('cause I normally need some time to realize what happens when i do bitshifting Laughing )

and:
yes, the 32-bit-counters need much code space but the pic still has some space left, so there was no need for changing that. The 32-bit counter values are later conversed into floats and I was too lazy to code the extra math funcs myself...

thanks for your help so far...

I'd suggest doing some of your operations with a union. If you have something like:
union time {
int16 word[2];
int32 full;
} counter;

You can then have the timer1 interrupt, just increment counter.word[1].
Accessing a variable in an array using a fixed subscript, is as fast as directly accessing a normal variable.
In the RTCC, you then code as you show, except the timer value is directly transferred into word[0], and no multiplications or additions are needed.
So:
Code:

counter.word[0]=get_timer1();
if (Timer1IF) {
    counter.word[1]++;
    Timer1IF=0;
}

The only problems, are if timer1, can wrap, between the 'get', and checking the interrupt flag, or if it can increment when being read (remember that the processor only transfers a byte at a time, for the 16bit transfer...).
The comparison, is then done on counter.full.
This saves a lot of time.

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