Menu

Delays Log in to Edit

Delays in AVR-Ada

There are currently two ways in AVR-Ada to control the timing.

  1. You can have busy waits down to the level of a few instructions. That is in the order of sub-microseconds
  2. You can use one of the internal timers (usually Timer2) to set up your own clock tick based on the processor speed.

See Tero's blog for comparing the accuracy of the two methods.

1. Busy waits with AVR-Wait

The package AVR.Wait provides three functions allowing delays in the order of a few cycles.

procedure Wait_3_Cycles (Count : Unsigned_8);  -- can wait up to 2^8 x 3 cycles
procedure Wait_4_Cycles (Count : Unsigned_16); -- can wait up to 2^16 x 4 cycles
procedure Wait_Cycles (Count : Unsigned_32);   -- can wait up to 2^32 cycles

The generic function AVR.Wait.Generic_Wait_USecs takes the processor speed in Hertz and the microseconds (10-6 seconds) to be delayed as generic parameters. It internally calculates at compile time the number of cycles to wait. It leads to only a few instructions at assembler level.

Example of generic instantiation from the 1-Wire package:

procedure Wait_70us is
  new Generic_Wait_Usecs (Crystal_Hertz => 8_000_000,
                          Micro_Seconds => 70);
pragma Inline_Always (Wait_70us);

The system of busy waits counting cycles only works correctly if you disable all interrupts. You should therefor limit it to less than one millisecond. All other timing are usually better achieved by the second method using a timer.

2. Internal timer driven by the processor speed

In order to obtain accurate timing the compiler has to know at what speed the processor works. If you set the processor speed in AVR.Config you can also use

delay 0.1;

on the primary MCUs.

The above standard Ada delay works if you have applied the corresponding patch when building the cross compiler and when using AVR.Real_Time.Clock. If you don't need any of the other timing routines you have to "with" at least that package in the main procedure.

with AVR.Real_Time.Clock;
pragma Unreferenced (AVR.Real_Time.Clock);

Related

Wiki: Examples
Wiki: Home