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