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

delay vs timer0

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



Joined: 03 Jan 2012
Posts: 3

View user's profile Send private message

delay vs timer0
PostPosted: Sun May 13, 2012 4:19 pm     Reply with quote

times I am trying to develop something to replace the delay of the PIC by a timer count.

In my project I'm counting five different time, it happens that if I set with IF, the five routines my time goes into space rsrsrsrs ... as the basis of counting does not work in practice I think I need to connect the timer - set time (to count) off the timer ... and so.

I am using the timer zero.

Follows a small example of one routine.
Code:
 
WHILE(1)
  {
  if(cont==2930) // 1,5S
  {
  output_toggle(PIN_a0);
  cont=0;
  }

  if(cont==(value) //
{

  }
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19219

View user's profile Send private message

PostPosted: Mon May 14, 2012 4:18 am     Reply with quote

It is not very clear from your post what you actually want. However some comments:
Testing 'for' a timer value, will rarely work. Unless the timer is updating _very_ slowly, and the loop doing the testing is fast, you will almost certainly 'miss' an exact count.
Do you have to use timer0?.

The 'standard' way of dealing with generating 'timers', without using delays, is to have effectively a 'countdown', handled using the interrupt.
You don't tell us your master clock rate, or chip, so just an 'example-ish'.

Code:

//Chip configuration, and clock setting here

//Assuming a 4MHz master clock.
//These values set the delays
#define FIRST_TIMER (99)
#define SECOND_TIMER (249)
#define TIMER_PRELOAD (65536-78) //See comment in int handler
int1 first_event=FALSE;
int1 second_event=FALSE;

#INT_TIMER0
void tick(void) {
    static int16 idelay1=FIRST_TIMER;
    static int16 idelay2=SECOND_TIMER;
    //Get here every time timer0 reaches 65535, and wraps to 0
    //Using 4MHz master clock, /128 divisor, so timer0 counts every
    //4000000/(4*128)th second - 7812*/second. So 1/100th second
    //is about 78 counts - hence 'preload' value
    set_timer0(TIMER_PRELOAD);
    //So we get here _about_ 100* per second
    if (idelay1!=0) --idelay1;
    else {
        idelay1=FIRST_TIMER;
        first_event=TRUE;
    }
    if (idelay2!=0) --idelay2;
    else {
        idelay2=SECOND_TIMER;
        second_event=TRUE;
    }
    //decrement counters _if_ they are non zero
    //when they get to zero, signal the 'event', and reset the counters
}

void main(void) {
    //Now main code - will need configuration to suit chip peripherals here
    setup_timer_0(T0_DIV_128 | T0_INTERNAL);
    //Running the timer off the internal master clock/128
    set_timer0(TIMER_PRELOAD);
    clear_interrupt(INT_TIMER0); //In case it has triggered already
    enable_interrupts(INT_TIMER0);
    enable_interrupts(GLOBAL);

    do {
        //Now the running code.
        //Imagine I want a one second delay, and a 2.5 second delay,
        //toggling two pins at these intervals - using A0, and A1
        //change to suit hardware - actual times are defined by
        //'FIRST_TIMER', and 'SECOND_TIMER', in 100th second ticks(-1)
        if (first_event) {
            first_event=FALSE;
            output_toggle(PIN_A0); //toggle first pin once per second
        }
        if (second_event) {
            second_event=FALSE;
            output_toggle(PIN_A1); //toggle second pin 2.5 seconds
        }
    } while (TRUE);
}


Now, this uses a 'tick' event, happening at about 100* per second. It decrements two counters, _if they are non zero_. In the main code, you simply test the flags saying that the time has expired. Once the flag is set, it remains set, till it is cleared in the main code. So if the main loop takes a bit of time, all that will happen is that the 'service' will happen a little late, but the timing carries on at the required rate.

The point about the question 'do you have to use timer0', is that if you want really accurate times, timer2, is generally 'better'. This can be set to clear _itself_ at a specific count. With the code as shown, the timer would trigger the interrupt 78/7812.5 of a second after it is loaded. It takes about 60(ish) instructions to get into the interrupt (potentially about 0.46875 counts), so the code ought to tick just fractionally over 100* per second. It is that 'fractionally over', which timer2 (or on later PICs some of the other timers), avoid.

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