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

Allpool olev programmikood on aga taimeril põhinev viitefunktsioon, mida on natuke lihtsustatud. Loendamise põhimõte on sama mis tarkvaralise viite funktsioonilgi - tekitatakse soovitud arv 1 ms pikkuseid viiteid. Viite tekitamiseks on kasutusel ATmega128 8-bitine loendur 0. Eelnevalt on juba välja arvutatud, et 14,7456 Mhz taktsageduse puhul peab loenduri taktsignaal olema vähemalt 64 korda jagatud, et 1 ms jooksul 8-bitine loendur üle ei täituks. See, mis väärtust loendur omama peab, et ületäitumine toimuks 1 ms järel, on esitatud avaldise kujul ja omistatud muutujale timer_start. F_CPU on makro-keele konstant mis näitab taktsagedust hertsides. Nimetatud taktsageduse puhul peaks loenduri väärtus 25,6 olema, kuid kuna murdarve kasutada ei saa, siis loenduri algväärtuseks saab 26. Siin tekib paraku ka viga viite ajas, kuid see on üsna väike (-1,7 μs).

Tsüklis toimub loenduri algväärtustamine ja ületäitumise lipukese nullimine (sellesse 1 kirjutades). Seejärel oodatakse, kuni loendur loendab algväärtusest 256-ni, ehk ületäitumiseni. Ületäitumise hetkel läheb ületäitumise lipuke kõrgeks ja 1 ms viide ongi toimunud. Funktsiooni lõpus taimer peatatakse.

//
// Riistvaraline viide millisekundites
//
void hw_delay_ms(unsigned short count)
{	
	// Taimeri algväärtuse arvutamine
	register unsigned char timer_start = 256 - F_CPU / 1000 / 64;
 
	// Taimeri käivitamine
	timer0_init_normal(TIMER0_PRESCALE_64);
 
	// Viite muutuja nullini loendamine
	while (count-- > 0)
	{
		// Taimeri algväärtustamine
		timer0_set_value(timer_start);
 
		// Ületäitumise lipukese nullimine
		timer0_overflow_flag_clear();			
 
		// Ületäitumise ootamine
		while (!timer0_overflow_flag_is_set())
		{
			asm volatile ("nop");
		}			
	}
 
	// Ületäitumise lipukese nullimine
	timer0_overflow_flag_clear();	
 
	// Taimeri peatamine
	timer0_stop();	
}

Järgnevalt on toodud samasugune programm nagu tarkvaralise viite näiteski. Lühemal 100 ms poolperioodil LED süüdatakse, pikemal 900 ms poolperioodil kustutatakse. Tulemusena vilgatab LED iga sekundi järel. Paraku pole ka selles näites periood täpselt 1 sekund, sest programmi muude funktsioonide täitmine igas tsüklis võtab samuti aega. Täpseks ajastuseks tuleb kasutada 16-bitist taimerit koos katkestustega.

//
// Kodulabori raudvaralise viite demonstratsioonprogramm.
// Programm vilgutab ~1 sekundi järel hetkeks LED-i.
//
#include <homelab/pin.h>
#include <homelab/delay.h>
 
//
// Test LED viigu määramine
//
pin debug_led = PIN(B, 7);
 
//
// Põhiprogramm
//
int main(void)
{
	// LED-i viigu väljundiks seadmine
	pin_setup_output(debug_led);
 
	// Lõputu tsükkel	
	while (true)
	{
		// LED-i süütamine
		pin_clear(debug_led);
 
		// Riistvaraline paus 100 millisekundit
		hw_delay_ms(100);
 
		// LED-i kustutamine
		pin_set(debug_led);
 
		// Riistvaraline paus 900 millisekundit
		hw_delay_ms(900);
	}
}
en/examples/timer/hardware_delay.1267712824.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