Na několika různých procesorech (ATmega, ARM Cortex-M3, ARM7, PIC32 ... všechno jsou to jednojádra bez operačního systému) potřebuju vědět, zda už uplynul určitý čas (např. definovaná doba svícení LED, pískání, doba do přechodu do úsporného režimu, samovolný restart po ztrátě komunikace...). Některé jevy vznikají v přerušení (takže ne v hlavní smyčce), ale většinou uplynutí času vyhodnocuju v hlavní smyčce. Pokud vyhodnocuju vypršení jednoduše rozdílem if((casZmacknuti-getCas())>30)...., tak se stává toto:
1) načte se aktuální čas (třeba funkcí getCas, nebo z globální proměnné, která obsahuje aktuální čas) do registru r2 (např. hodnota 127)
2) v přerušení se nastaví hodnota casZmacknuti na aktuální čas (např. hodnota 128), který je větší než čas v registru r2
3) po návratu z přerušení se čas události načte do registru r3
4) odečtou se hodnoty a vyjde 0xffff (při unsigned short), což je větší, než 30 a tím pádem se chybně vyhodnotí vypršení času.
Řešil jsem to několika způsoby: ukládáni časů do pomocných proměnných, dvojitá kontrola vypršení času, kontrola na předběhnutí času události před časem hodin, ...
Zatím nejpřehlednější mi přijde použití funkce na výpočet rozdílu času události a aktuálního času:
u32 getDelay(u32 timeVal) __attribute__((noinline));
u32 getDelay(u32 timeVal) {
return cas - timeVal;
}
...
if(getDelay(udalostTime)>30)cas Vyprsel();
...
Aktuální čas se u jednotlivých mikroprocesorů a programů liší rozlišením i počtem bitů podle potřeby (někdy potřebuju čas s přeností na jednotlivé takty nejrychlejších hodin mikroprocesoru, jindy stačí milisekundy), ale vyhodnocování by mělo být stejné. Pokud znáte lepší způsob (musí to být hooooodně rychlé a spolehlivé), tak sem s ním.
gamer: Vypínání přerušení jsem se chtěl vyhnout, tak jak to mám, by to snad nemělo být potřeba.