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/03/02 21:37] – priitj | 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 ====== | ||
Line 5: | Line 6: | ||
===== Theory ===== | ===== Theory ===== | ||
- | There is quite often a need to create delays in programs of microcontrollers, | + | There is often a need to create delays in programs of microcontrollers, |
| | ||
- | 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 töötakt? | + | 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 |
- | Since when programming in advanced languages (C-language for example), the programs are not written directly on the basis of the command, in order to create a software delay, | + | When programming in advanced languages (C-language for example), the programs are not written directly on the basis of the command, in order to create a software delay, one needs to know also its compiler which converts the program to the machine code. From this depends how many instructions (and phases |
===== Practice ====== | ===== 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 kasutatav muutuja on 8-bitine, seega on ka masinkood üsna lihtne. Selleks, et tekitada pausi millisekundites, on vaja loendada palju suuremaid arve ja siis läheb ka masinkood pikemaks. Võib kasutada ka üksteise sees töötavaid tsükleid, kuid selle meetodi puhul pole kogu viide lineaarses sõltuvuses tsüklite arvust, sest iga tsükli tasemega tekivad pisikesed lisaviited. | + | 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 kasutatakse ka järgmistes näidetes. | + | 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 66: | 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 77: | 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 107: | 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 |