where : ibrtses embedded
AVR Pascal (AVRCo) Timer Interrupt
Despite AVRCo offering the timer tick as library function, without the source
it sooner or later leads to problems, eg when power save is considered, and
is therefore to be avoided.
Here, a replacement with source is provided. Contrary to the provided library
tick, a bit more has to be decided. With the 8bit Timer0, only short ticks can
be done. At 4MHz, the prescaler can be set to div 1024 and the counter can
count to 256, making the longest available tick to be 64ms. This is usually
sufficient as tick. Signalling to the main is TimerCame:bit;.
For longer ticks, consider using the 16 bit Timer1. It does 256 times more or
16seconds per tick. Another option would be incrementing/decrementing a variable
in the timer interrupt and signalling the TimerCame only when appropriate.
For the time being we'll stick with Timer0. Replacement with Timer1 is trivial.
The main
The main program initializes the interrupt, see below, then enters the
loop and checks for the flag which is set in the interrupt.
var TimerCame:bit;
begin
..
SetupTimer0; // see below
..
TIMSK:=%00000001; // enable timer0 overflow
..
EnableInts;
loop
// do whatever without the tick
...
if (timercame=1) then
//do whatever with the tick here
...
timercame:=0; // reset the timer flag
endif;
endloop;
end; // main
The timer interrupt
the timer0 is counting up until 255, where it overflows and generates this
interrupt. So the time is counted as 256 - 'the preset value'
interrupt Timer0; // timer0 overflow
begin
TCNT0:=217; //reload 100=40ms 192=16.4ms 215=10ms 250=1500us
TimerCame:=1; //signal to the main
end;
Setup of the timer interrupt
Setup is trivial. The counter value has to be set and the prescaler has
to be set. Enabling the interrupt is not done here.
procedure SetupTimer0;
begin
TimerCame:=0;
TCNT0:=217; //
TCCR0:=$05; // clk div 1024 = 250us @ 4MHz
end;
After perhaps other timers were initialized, the mask is set in the main
TIMSK:=%00000001; // enable timer0 overflow
After other interrupts are setup, the interrupts are enabled in the main
EnableInts;
additional powersaving
The advantage of this code is the simple introduction of power saving.
Just enter the sleep state and wait for the timer.
enable the sleep, in the main loop or before
MCUCR:=%1xxxdddd; // see the manual for the bits
Then in the main loop :
loop
// do whatever without the tick
...
if (timercame=1) then
//do whatever with the tick here
...
timercame:=0; // reset the timer flag
else
sleep; // enter sleep state until the timer comes
endif;
endloop;
Yes, if only the tick is executed, the main could look a bit different.
The optimization of the structure is left to the reader.
Questions ?
Suggestions?
Feedback ?
sponsored links
embedded
home
last updated :10.may.04, or perhaps later
Copyright (99,2004) Ing.Büro R.Tschaggelar