This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
en:examples:timer:software_delay [2010/02/08 12:58] – mikk.leini | en:examples:timer:software_delay [2020/07/20 09:00] (current) – external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | < | ||
====== Software delay ====== | ====== Software delay ====== | ||
- | //Vajalikud teadmised: [HW] [[en: | + | //Necessary knowledge: [HW] [[en: |
- | ===== Teooria | + | ===== Theory |
- | Tihti on mikrokontrollerite programmis vaja tekitada viiteid, et tegevusi ajastada või nende lõppu oodata. Üks idee poolest lihtsamaid meetodeid mikrokontrolleri tegevuses paus tekitada on selle protsessor mingi muu tegevusega üle koormata | + | There is often a need to create delays in programs of microcontrollers, it is necessary to time the actions or wait them to end. By its concept one of the easiest methods for creating a break in the work of a microcontroller is overloading its processor with some alternative action – for example order it to count big numbers. From the stroke frequency of the processor can be calculated to which number it should count in order to get a certain time delay. Counting a number from zero up to the value of the stroke frequency of the processor in hertz-s, should theoretically create a delay for one second. For number of reasons this is not as simple in practice. |
+ | |||
+ | If the processor of the microcontroller calculates using numbers which’s binary form is as wide as its inner bus (AVR has 8 bits), then it takes one firing stroke of the processor to perform one arithmetical operation for example adding 1 to any value. In order to operate with thousands or millions the number has to be 16 or 32 bit and for an 8 bit processor it takes more than one firing stroke to calculate them. Hence when dealing with large numbers, one has to be familiar with the inside of the processor – exactly its commands. | ||
- | Kui mikrokontrolleri protsessor arvutab arvudega, mille kahendkuju on sama lai kui selle sisemine siin (AVR puhul 8-bitti), siis protsessoritel võtab üks aritmeetiline tehe, näiteks arvu liitmine ühega, aega 1 protsessori töötakt. Selleks et arvutada tuhandete või miljonitega, peab arv olema 16- või 32-bitine ja nende arvutamiseks kulub 8-bitistel protsessoritel rohkem kui 1 töötakt. Niisiis, suurte arvude puhul peab tundma protsessori sisemust - täpsemalt selle käsustikku. | + | When programming in advanced languages |
- | Kuna kõrgtaseme keeles (näiteks C-keeles) programmeerides ei kirjutata programmi otse käsustiku baasil, peab tarkvaralise viite tekitamiseks tundma ka kompilaatorit, | ||
- | ===== Teooria praktikas | + | ===== Practice |
- | Järgnevalt on toodud näide tarkvaralise viite tekitamisest | + | The following is an example of generating software delay with AVR microcontroller. A part of a program in C-language is written, which counts the variable x of for-cycle from 0 to 100. Inside each cycle a no-action empty instruction is completed. It is needed, because if the content of the cycle is empty, the compiler optimizes it out of the program as it considers this to be useless. |
<code c> | <code c> | ||
unsigned char x; | unsigned char x; | ||
- | // Tsükkel seni kuni x on 100 | + | // Cycle until x is 100 |
for (x = 0; x < 100; x++) | for (x = 0; x < 100; x++) | ||
{ | { | ||
- | // Tühiinstruktsiooniga | + | // With empty instruction |
asm volatile (" | asm volatile (" | ||
} | } | ||
</ | </ | ||
- | Siinkohal on aga toodud sama C-keele programmilõik pärast kompileerimist. Vasakpoolsed | + | This is the same part of a program after compiling. 2 hexadecimal numbers |
<code asm> | <code asm> | ||
- | 80 e0 | + | 80 e0 |
- | 00 00 | + | 00 00 |
- | 8f 5f subi r24, 0xFF | + | 8f 5f subi r24, 0xFF ; subtracting |
- | 84 36 | + | 84 36 |
- | e1 f7 brne .-8 | + | e1 f7 brne .-8 |
</ | </ | ||
- | Kompileeritud kujul on näha, mis tegelikult | + | |
+ | In the compiled form can be seen, what is actually happening with the cycle of the C-language and it can be used to calculate how many clock sycles is needed to complete a cycle of one period. The information about the effect of the instructions and operating time can be found from AVR’s instructions datasheet. In the given example, it takes 4 clock cycles to complete | ||
(1 + 100 ⋅ 4 + 1) / 14745600 = 27,26 μs | (1 + 100 ⋅ 4 + 1) / 14745600 = 27,26 μs | ||
- | Näites tekitatud viide on mikrosekundites ja kasutav muutuja | + | The delay produced in the example, is in microseconds and the variable used is 8-bit so the machine code is fairly simple. In order to produce a break in millisecond, we need to count much larger numbers and thus the machine code gets longer. Cycles working inside each other may also be used, but with this method the delay is not in linear relation with the number of the cycles because with each level of cycle a small extra delay occurs. |
+ | |||
+ | The goal of this exercise is not creating precise software delay on the level of machine code, because it is quite an accurate work and we already have the functions necessary to produce delays in the avr-libc and in the library of the HomeLab. Those are used also in the following examples. | ||
- | Käesoleva harjutuse eesmärk ei ole siiski masinkoodi tasandil täpset tarkvaralist viidet tekitada, sest see on üsna peen töö ja pealegi on viite tekitamiseks avr-libc ja Kodulabori teegis juba funktsioonid olemas. Need tulevad ka näites kasutusele. | + | When dealing with the software delay it is important to know, that regardless its basic simplicity; it is extremely inefficient method from the power consumption point of view. During all of these clock rates when the microcontroller is counting the useless, energy is consumed. So if using applications operating |
- | Tarkvaralise viite puhul on aga oluline teada, et hoolimata oma põhimõttelisest lihtsusest on see äärmiselt ebaefektiivne meetod energiatarbe seisukohast. Kõigil neil taktidel, mil mikrokontroller tegeleb kasutu loendamisega, | ||
- | ===== Praktika | + | ===== Practice |
- | Järgnev programmikood käib tarkvaralise viite funktsiooni | + | The following code of a program is about software delay function |
<code c> | <code c> | ||
// | // | ||
- | // Tarkvaraline viide millisekundites | + | // Software delay in milliseconds. |
// | // | ||
void sw_delay_ms(unsigned short count) | void sw_delay_ms(unsigned short count) | ||
{ | { | ||
- | // Viite muutuja nullini loendamine | + | // Counting the variable of the delay to 0 |
while (count-- > 0) | while (count-- > 0) | ||
{ | { | ||
- | // 1ms viide spetsiaalse funktsiooniga | + | // 1ms delay with a special function. |
_delay_ms(1); | _delay_ms(1); | ||
} | } | ||
Line 65: | Line 69: | ||
</ | </ | ||
- | Toodud funktsiooni kasutamiseks on järgnev programm, mis tekitab lõputus tsüklis kaks viidet: 100 ms ja 900 ms. Lühema viite jooksul | + | The following program is for using the given function, this creates two delays in the endless loop: 100 ms and 900 ms. During the shorter delay LED is lit and during the longer it is switched off, the result – the LED is blinking periodically |
<code c> | <code c> | ||
// | // | ||
- | // Kodulabori tarkvaralise viite demonstratsioonprogramm. | + | // The demonstration program of the software delay of the HomeLab. |
- | // Programm vilgutab | + | // The program is blinking a LED for a moment after ~1 second. |
// | // | ||
#include < | #include < | ||
Line 76: | Line 80: | ||
// | // | ||
- | // Test LED-i viigu määramine | + | // Determining the pin of the test LED |
// | // | ||
pin debug_led = PIN(B, 7); | pin debug_led = PIN(B, 7); | ||
// | // | ||
- | // Põhiprogramm | + | // Main program |
// | // | ||
int main(void) | int main(void) | ||
{ | { | ||
- | // LED-i viigu väljundiks seadmine | + | // Setting the pin of the LED as output. |
pin_setup_output(debug_led); | pin_setup_output(debug_led); | ||
- | // Lõputu tsükkel | + | // Endless loop |
while (true) | while (true) | ||
{ | { | ||
- | // LED-i süütamine | + | // Lighting the LED |
pin_clear(debug_led); | pin_clear(debug_led); | ||
- | // Tarkvaraline paus 100 millisekundit | + | // Software delay for 100 ms |
sw_delay_ms(100); | sw_delay_ms(100); | ||
- | // LED kustutamine | + | // Switching off the LED |
pin_set(debug_led); | pin_set(debug_led); | ||
- | // Tarkvaraline paus 900 millisekundit | + | // Software delay for 900 milliseconds. |
sw_delay_ms(900); | sw_delay_ms(900); | ||
} | } | ||
Line 106: | Line 110: | ||
</ | </ | ||
- | Kuigi näib, et LED vilgatab tõesti | + | Although it seems that the LED blinks in every 1 second, the time is actually a little bit longer, because the callouts of LED’s and delay functions are taking a couple of clock rates of the microcontroller |