Oneskorenia s AVR: Rozdiel medzi revíziami
Zo stránky SensorWiki
Bez shrnutí editace |
|||
(Jedna medziľahlá úprava od rovnakého používateľa nie je zobrazená.) | |||
Riadok 14: | Riadok 14: | ||
<div style='text-align: center;'> | <div style='text-align: center;'> | ||
[[Súbor:MIPS_AtmelStudioFCPU.png | [[Súbor:MIPS_AtmelStudioFCPU.png]]<BR> | ||
''Vkladanie informácie o frekvencii procesora pre kompilátor.'' | ''Vkladanie informácie o frekvencii procesora pre kompilátor.'' | ||
</div> | </div> | ||
Riadok 52: | Riadok 52: | ||
<references group="REF"/> | |||
Aktuálna revízia z 10:30, 8. február 2021
Poznámka k používaniu fukncie _delay_ms()
Funkcia _delay_ms() pozdrží dobu vykonávania programu na čas zadaný argumentom funkcie. Aby funkcia správne fungovala na rozličných procesoroch v rozličných konfiguráciach, potrebuje vedieť, akou frekvenciou procesor pracuje. Robí sa to tak, že zadefinujeme makro F_CPU ako frekvenciu v Hz. Pre Arduino kompatibilné dosky je to
#define F_CPU 16000000UL
Niekedy je však výhodné použiť ten istý zdrojový kód programu aj viackrát a preto nie je dobré priamo vkladať frekvenciu do kódu. Dá sa to urobiť aj dodatočne, definovaním hodnoty v príkazoch pre prekladač. V Atmel Studio je prístup cez Project > (ProjectName) Properties > Toolchain > AVR/GNU C Compiler > Symbols, treba tam potom pridať takýto výraz
F_CPU=16000000
pozrite aj obrázok.
Funkcia je deklarovaná nasledovne
void _delay_ms ( double __ms )
// Perform a delay of __ms milliseconds, using _delay_loop_2()
Vyššie uvedená deklarácia funkcie, ktorá je predpripravená spolu s kompilátorom avr-gcc nám hovorí, že argumentom je počet milisekúnd oneskorenia, ktorým môže byť až 32-bitové celé čislo (double long int) alebo desatinné čislo s dvojitou presnosťou (double). Ktorá verzia je platná záleží na parametroch kompilátora (či zapneme aj používanie plávajúcej aritmetiky float, ktorá je default vypnutá, pretože zaberá veľa miesta). Zdalo by sa teda, že napríklad vytvoriť oneskorenie 1 sekunda je celkom jednoduché, stačí ako parameter vložiť číslo 1000.
Nie je to však také jednoduché. Dokumentácía k prekladaču[REF 1] sa píše doslova
The maximal possible delay is (262.14 ms/F_CPU) where F_CPU is in MHz.
Podobná poznámka je aj priamo v delay.h a pre frekvenciu 16 MHz to znamená, že maximálne oneskorenie, ktoré vieme touto funkciou vygenerovať je 16 milisekúnd! Preto si musíme napísať vlastnú funkciu, ktorá bude volať _delay_ms() s nejakým rozumným parametrom (1ms alebo 10ms) a tak dosiahneme potrebné dlhšie oneskorenia.
// this wrapper function calls _delay_ms with a known value of 1
// if you call _delay_ms(variable) then the floating point library
// is going to be included and your output file gets much larger
void delay_1ms(uint16_t ms)
{
uint16_t i;
for(i=0;i<ms;i++)
_delay_ms(1);
}
A na záver ešte jedna poznámka, že hodnota oneskorenia by mala byť kompilátoru známa v čase prekladu, aby mohol daný výraz vyhodnotiť a nahradiť ho výsledkom. V opačnom prípade je na počet cyklov použitý výpočet, ktorý vyvolá potrebu použitie kniznice pre pracu s reálnymi číslami math.h čím veľkosť programu vzrastie o viac ako 2kB.
Celkom na záver pozorovanie, ktoré sme však zatiaľ neoverovali, že ak kompulátor optimalizuje preklad s prepínačom -O1, pribalí aj celú math knižnicu, ale už -O2 ju vynechá. Podobne je to pre -Os.
- ↑ AVR Library documentation of 'delay.h'.