ll of Bascom’s wait statements and the delays embedded in other statements are essentially loops that execute the required number of times to achieve a desired time-delay. There is an internal Bascom-AVR routine that lasts 1 ms, _WAITMS. During program compilation, the Bascom-AVR compiler checks the $crystal directive and uses a specified parameter to calculate the values needed for the counting registers in order to achieve a 1 ms execution time of the _WAITMS routine (or as close as possible to 1 ms).
The _WAITMS routine is used in a loop for larger delays. For example, Waitms 100 executes the _WAITMS routine 100 times. Furthermore, the _WAITMS routine is a building block for another time-reference within Bascom-AVR, namely the 1-s-routine _WAIT. Once again, larger delays are achieved by executing the _WAIT routine an appropriate number of times within a loop.
It is obvious that no accurate timing is possible with such statements for several reasons:
- It’s impossible to calculate values for counting registers to achieve a precise 1-ms or 1-s reference, for every possible crystal frequency;
- when the basic delay routines (_WAITMS, etc.) are executed in a loop for larger delays, the execution time of the assembly language commands which make up the loop structure, get added to the basic time reference;
- when interrupts occur, their execution will extend the total duration of wait statements, if both occur simultaneously.
The Bascom-AVR compiler is written cleverly and you can rely on the wait statements as long as you don’t expect very high accuracy. The main factor affecting reasonably precise timing is to correctly specify the $crystal directive: if you use a 10 MHz crystal with $crystal = 8000000, you can expect a significant deviation from the specified time delays.
Wait and the clock division factor
There is another factor worthy of consideration, and that is the clock division factor. The option to set the clock divisor is available in most new AVR microcontrollers. For example, the ATtiny2313 microcontroller offers division factors of 1, 2, 4, 8, 16, 32, 64, 128 and 256. The ATtiny2313 is shipped with the CKDIV8 Fuse programmed, which results in a division factor of 8 at start-up. In other words, if you use an 8 MHz crystal to run the ATtiny2313, the internal clock will be only 1 MHz and you should either change the division factor at the beginning of the program or specify the $crystal to match the 1 MHz frequency.
What will happen if the clock division factor is changed dynamically during the program execution? You can specify only one parameter in the $crystal directive and the counters for the _WAITMS routine are defined during program compilation. They cannot be altered during execution. This means that all wait statements within a program will be accurate for only one clock frequency; if we change the clock frequency during program execution, wait statements will execute at an inappropriate speed and will not last the expected time.
Wait a minute!
2012_AVR_UK_33
Continue reading
Shop area
|