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

timer0 overflow

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



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

timer0 overflow
PostPosted: Wed May 14, 2008 8:23 pm     Reply with quote

I use timer0 to see when an event times out. It is setup so 1 tick is .4us.
right now I time out at 25ms which is 62,500 ticks, so it is within 16bits. What I would like to do is count to 100,000 ticks. I don't want to change the timer setting. What is the best way to do this? Is there an easy way to tell when timer0 overflows, or do I just keep checking to see if the next number is lower than the previous one??

Here is my current code.
Thanks
Ringo


Code:

    set_timer0(0); // timer0 is .4us per timer tick
    while(input(ccs_echo)==1)
    {
        RawData = get_timer0();
        //timeout after 25ms
        if(RawData > 62500) // .4*62500=25ms
            return(0);
    }


_________________
Ringo Davis
RLScott



Joined: 10 Jul 2007
Posts: 465

View user's profile Send private message

Re: timer0 overflow
PostPosted: Wed May 14, 2008 8:33 pm     Reply with quote

Although it is not the most efficient, if you have nothing else to do, polling the timer and checking to see if it is higher or lower than the previous value is nice and simple. Make sure you declare the values to be unsigned int16. But if you want a method that does not require storing the previous timer reading, then use the timer interrupt flag that gets sets when the timer overflows to 0. By the way, timer0 is only 8 bits on midrange PICs. Which PIC are you using?

Robert Scott
Real-Time Specialties
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

PostPosted: Wed May 14, 2008 8:36 pm     Reply with quote

Thanks, I'm using an 18f452, so it is 16 bits.
How do I read the timer interrupt flag?
Ringo
_________________
Ringo Davis
Ttelmah
Guest







PostPosted: Thu May 15, 2008 2:50 am     Reply with quote

For your application, given the count will be under 131072 (where the timer would wrap a second time), the timer flag is the best solution. effectively it means you have a 17bit counter available:
Code:

#byte PIR1=0xF9E
#bit TMR1IF=PIR1.0
#byte T1CON=0xFCD
#bite TMR1ON=T1CON.0

   int 32 RawData;
   
    set_timer0(0); // timer0 is .4us per timer tick
    TMR1IF=0; //clear the flag - must be after setting the count=0
    TMR1ON=TRUE; //enable the timer
    while(input(ccs_echo)==1)
    {
        TMR1ON=FALSE; //stop the timer
        RawData = get_timer0();
        //Now add in the 17th bit
        if (TMR1IF) bit_set(RawData,16);
 
        if(RawData > 100000) // .4*62500=25ms
            return(0);
    }

Now, this shows two things. First, I stop the timer before read it. This prevents the possibility of the first read getting (say) FFFF, and then when the flag is accessed, it'll just have wrapped, to give 1FFFF when the interrupt flag is added, rather than the correct 10000. All I have done, is make your 'RawData' value into a 32bit value, read in the count from the timer, and then if the flag is set, set the extra bit.

Best Wishes
ckielstra



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

View user's profile Send private message

PostPosted: Thu May 15, 2008 5:35 am     Reply with quote

I spotted two problems in Ttelmah's code:
1) The timer is stopped in the loop but never enabled again.
2) Stopping/starting the timer in such a tight loop slows down the timer considerably.

I tried to modify the code to solve the mentioned problems but I'm not really happy with it:
Code:
#byte PIR1=0xF9E
#bit TMR1IF=PIR1.0
#byte T1CON=0xFCD
#bit TMR1ON=T1CON.0

  int32 RawData;
   
  set_timer0(0);           // timer0 is .4us per timer tick
  TMR1IF=0;                // clear the flag - must be after setting the count=0
  TMR1ON=TRUE;             // enable the timer
  while(input(ccs_echo)==1)
  {
    if (TMR1IF)           // timer overflowed?
    {
      TMR1IF = 0;         // reset overflow flag
      RawData += 0x10000; // increment counter
    }
 
    if ((RawData + get_timer0()) > 100000) // .4*100,000=40ms
       return(0);
  }
Note that I do not disable the timer between testing TMRIF and the get_timer_0, this introduces a risk of executing the loop 1 time too many. I'm not sure how bad this is for the application but I considered it better than slowing down the timer0.
An advantage of the chosen approach is that the timing now allows very large delays, up to 2^32 ticks.

Another approach that makes me feel more comfortable is to forget about the 0.4us resolution. Why not double the timer0 prescaler and set the resolution to 0.8us? Than for counting to 50000 the 16-bit timer0 counter will fit.
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