This is an old revision of the document!


Table of Contents

Hardware delay

Necessary knowledge: [HW] Controller module, [AVR] Counters/Timers, [LIB] Pins, [LIB] Delay, [LIB] Timers, [PRT] Software delay

Theory

The software delay is not the only method for creating breaks. The same can be done using timer. Timer is a hardware which counts up or counts down with a certain frequency. The clock frequency of the timer can be generated from microcontroller’s frequency or from some kind of other outside pace. The clock frequency can usually be divided – to get smaller frequency. This is done with prescaler. Important fact is that the fixed clock frequency timer’s value is related to the time linearly. The time can be calculated by multiplying the period of the clock frequency of the timer with the value of the timer

The events which come with the changes of AVR timer.

AVR counters can be made informing about overflow of the counter or achieving compare mach. Overflow happens when the counter has the maximal possible value and it start all over again form 0. The controlling of achieving the value is done on the moment of growth of the counter’s value and it is done by comparing the new value with the value given by the user. On the occurrence of the event, the bits in the status indexes of the AVR are automatically set as high.

For generating a delay using a timer, it is sufficient when only the timer is set and waiting for the status bit to go high. Different from the software delay, the work of the timer is not depending on the compiler, it makes using them more reliable. On the other hand the setup of the AVR counter may be fairly troublesome, thanks to their diversity (or their complexity). Depending on the microcontroller’s timing signal, may happen that it will not divide exactly with the desired delay period and the delay will nit be accurate.

Practice

The program code below is a delay function basing on a timer, which is a little bit simplified. The principle of counting is the same as it is at software delay function – a desired amount of 1 ms long delays are produced. The delay is produced with an 8-bit ATmega 128 counter 0. It is calculated previously that at clock frequency 14,7456 Mhz the timing signal has to be divided at least 64 times, so that the counter would not reach to overflow in 1 ms. The value which that the counter must have so that the overflow occurs after 1 ms presented on the form of expression and the variable is timer_start. F_CPU is a constant in macro-language, which shows clock frequency in Hz. This clock frequency should be 25,6 at the moment but since we can not use fractions, the initial value will be 26. Unfortunately arises here a mistake in delay time, but it is fairly small (-1,7 μs).

In the cycle takes place initialing of the counter and zeroing the flag of the overflow (by writing 1 into that). After which is waited until the counter counts to 256 from the initial value, i.e. to the overflow. At the moment of the overflow the flag goes high and the delay of 1 ms id happened. In the end of the function the timer is stopped.

//
// Hardware delay in milliseconds.
//
void hw_delay_ms(unsigned short count)
{	
	// Calculating the initial value of the timer.
	register unsigned char timer_start = 256 - F_CPU / 1000 / 64;
 
	// Starting the timer.
	timer0_init_normal(TIMER0_PRESCALE_64);
 
	// Counting the variable of the delay to the 0.
	while (count-- > 0)
	{
		// Initializing the timer.
		timer0_set_value(timer_start);
 
		// Zeroing the overflow flag.
		timer0_overflow_flag_clear();			
 
		// Waiting for overflow.
		while (!timer0_overflow_flag_is_set())
		{
			asm volatile ("nop");
		}			
	}
 
	// Zeroing the overflow flag.
	timer0_overflow_flag_clear();	
 
	// Stoping the timer.
	timer0_stop();	
}

The following is similar program as it was in the example of the software delay. In the shorter 100 ms half-period the LED is lit and on the longer 900 ms half-period it is switched off. The result is that the LED is blinking after every second. Unfortunately, in this example the period isn’t exactly 1 second, because executing other functions of the program takes also time. For exact timing a 16-bit timer with interruptions must be used.

//
// Demonstration program of harware delay of the Homelab.
// The Program blinks LED for a moment after every ~1 second.
//
#include <homelab/pin.h>
#include <homelab/delay.h>
 
//
// Determining the pin of the Test LED.
//
pin debug_led = PIN(B, 7);
 
//
// Main program.
//
int main(void)
{
	// Setting the pin of the  LED as output.
	pin_setup_output(debug_led);
 
	// Endless loop.	
	while (true)
	{
		// Lighting the LED.
		pin_clear(debug_led);
 
		// Hardware delay for 100 milliseconds.
		hw_delay_ms(100);
 
		// Switch off of the LED.
		pin_set(debug_led);
 
		// Hardware delay for 900 milliseconds.
		hw_delay_ms(900);
	}
}
en/examples/timer/hardware_delay.1267716626.txt.gz · Last modified: 2020/07/20 09:00 (external edit)
CC Attribution-Share Alike 4.0 International
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0