|
|
View previous topic :: View next topic |
Author |
Message |
edybahia
Joined: 03 Jan 2012 Posts: 3
|
delay vs timer0 |
Posted: Sun May 13, 2012 4:19 pm |
|
|
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: 19539
|
|
Posted: Mon May 14, 2012 4:18 am |
|
|
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 |
|
|
|
|
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
|