Udělal jsem časovač, zhruba jednou za sekundu spustí nějakou funkci.
Teď ale budu potřebovat přesnější čas (např. aby zpoždění za 20 minut nebylo větší než několik sekund). Předpokládám že bude nutný krystal - jaký ? Frekvence menší nebo větší ? Třeba tento gme.cz/cz/q-10mhz-p131-009.html ? Poběží mi na stejné frekvenci jako krystal i procesor ATMega168 nebo jenom časovač ? Zapojení je s kondenzátory cca 12p na obou stranách o zem ?
A druhá věc - jdou nějak udělat priority přerušení ? Aby se mi čas aktualizoval každou sekundu i když budu mezitím obsluhovat tlačítka ? To znamená vždy na chvilku vyskočit z obsluhy tlačítek a po aktualizaci času se vrátit zpět na obsluhu tlačítek ?
Díky za info
administrator: přejmenováno z "Pár rad začátečníkovi"
Krystal můžeš použít vpodstatě jakýkoli, ale bylo by vhodné, aby byla jeho hodnota celočíselně dělitelná mocninou dvojky (dostupnou děličkou timeru) a požadovaným rozlišením abys nemusel provádět ruzná časově závislá harakiry.
Tedy např. chceš mít rozlišení(četnost přetýkání timeru) 0.1s a krystal 20MHz. S tím si 16b timer poradí ve spolupráci s děličkou 64 (vyšší děličky nedají celočíselný počet taktů timeru za 0.1s).
20e6 * 0.1 / 64 = 31250. Při děličce 64, krystalu 20MHz a timeru nastaveném tak, že je jeho TOP = 31249 ti tedy přeteče krystal 10x za vteřinu. Napočítat z toho 20 min už pak není problém .
Přerušení zde prioritu nemají. Kdo dřív přijde, ten dřív mele . Jde ovšem zařídit, aby mohlo být přerušení přerušeno (nested interrupts). Buď vložíš sei() na začátek jeho obsluhy, nebo lépe použiješ makro ISR_NOBLOCK.
ISR(XXX_vect, ISR_NOBLOCK)
{
...
} Každopádně přerušení mají být napsány tak, aby byly co nejkratší. Takže např. půlvteřinová obsluha tlačítka jak jsi to měl v kódu ve vlákně výše, tam nemá co dělat. V takovém případě si máš jen v přerušení nějak označit, že nastalo (do globální proměnné) a obsluhu vyřešit až na ni dojde řada v mainu. Záleží ovšem na konkrétním případě, na prioritách a potřebných odezvách. Tedy třeba čas je třeba aktualizovat každou sekundu, nebo častěji, ale jeho zobrazení je zcela podřadná a dlouhá činnost, která může vklidu počkat.
Obsluha tlacitok nema preco trvat dlhsie ako 10us. Bude to skor vyrazne menej ako viac. Za tuto dobu procesor spravi pri 18.432MHz maximalne 184 instukcii co je viac ako dost pre obsluhu 3-4 tlacitok.
Na zaklade akej udalosti testujes tlacitka, na zaklade nejakeho ineho prerusenia ked potrebujes riesit arbiter preruseni, alebo v lavnej slucke. Ak v hlavnej slucke, vobec ta nemusi trapit priorita prerusenia. Co tak testovat tlacitka od casovaca, napriklad 1x za 10ms, od toho isteho ktory odpocita pozadovany cas?
Ak prerusenie od casovaca prichadza prerusenie 1x za 10ms a ak nastanu dve prerusenia tesne za sebou a to druhe bude od casovaca, mas rovnych 10ms na spracovanie prerusenia od casovaca. Timer predsa neprestane pocitat vstupne impulzy len preto, ze sa neobsluzi prerusenie. Takze ziaden strach, ze by sa Ti nieco nestihalo a casovanie by sa ocitlo v sklze. Je uplne jedno, ci prerusenie obsluzis 1ms od nastania udalosti alebo 5 ms od udalosti. Na presnost pocitania casu to nebude mat absolutne ziaden vplyv.
cim vyssia frekvencia, tym vyssia spotreba. hodnoty si najdes pekne graficky spracovane v datasheete. To je jedine kriterium pre vyber Xtalu.
Obsluha tlačítek je udělaná v přerušení. A mám je udělaný tak, že při ťuknutí se změní hodnota proměnné o jedna, při držení se mění po deseti. Takže to přerušení může být docela dlouhé. Funguje to dobře, ale asi by bylo rozumý předělat.
Ak sa pri drzani meni cislo o desat, potom za 1ms (milisekundu!!!) Ti musi premenna menit hodnoty cez 1000. Co je to za blbost? Takto sa neda predsa ziadne cislo rozumne nastavit. Alebo to pouzivas ako generator nahodneho cisla pre hraciu kocku? Len mi nenapis, ze po kontrole stlacenia tlacitka v preruseni vlozis do tohto prerusenia funkciu delay().
Ziadne prerusenie NESMIE byt dlhe. Inak to cele straca zmysel. To si tie tlacitka vyhodnocuj v hlavnej slucke a tam sa s nimi nimri kolko ti srdce raci, ale nie v preruseni. To je jednoducho blbost.
Martin: Tím si můžeš být téměř jist(viz poslední stránka výše odkazovaného tématu) .
Ale abych jenom nepindal.
johnn: Když už budeš mít v systému nějak implementované hodiny (třeba s tikem 0.1s nebo jak se ti bude líbit), bylo by rozumné odvodit ono přičítání právě od nich.
Příklad: v přerušení si přičteš jednotku a označíš si, že bylo tlačítko stisknuto. Pak už stačí jen v mainu po každém tiku zkontrolovat tu značku a pokud říká “stisknuto” a tlačítko je opravdu stále stisknuto, přičteš 10. Jakmile bude tlačítko uvolněno, značku si vynuluješ.
Zrovna mě to napadlo, netvrdím, že je to optimální .
Teďko mi tady zaskočil problém. Program mi normálně funguje (včetně reakcí na tlačítka), pokud mám zapojený programátor v počítači. Jakmile programátor z počítače vypojím, program funguje, ale jakmile zmáčknu tlačítko, funguje špatně - špatné zobrazování na displeji (jiná čísla i znaky), občas i špatně zobrazená teplota, tlačítko nezvětší proměnno o jedno ale o více, při jiném tlačítku běží program od začátku.
Čím to může být ? Špatný program nebo programátor nebo něco jiného?
Ty tam nemáš ani odpory? A port PC ti stále žije? Zřejmě dobrej oddíl.
Ke každýmu tlačítku dej pull-up tak 10k a mezi “programátor” a mcu natlač odpory aspoň 330Ohm.
Tak jsem tam dal odpory. U tlačítek jsem je už měl. A dělá to stejně to samé. A programátor je teďko s odporama nějak méně spolehlivý - občas vyhazuje chybu a musím mu dát příkaz znovu.
Ale když tam dam program, který nemá přerušení v přerušení, tak to funguje dobře i bez kabelu. Takže já raděj zatím pořádně dodělám tu obsluhu tlačítek aby nemuselo být přerušení v přerušení. Programátor zatím budu považovat za dobrý.
a ještě otázečka - má cenu u tlačítek čekat na nějaké zákmity ? - to znamená při stisknutí se optat třeba po 10 milisekundách a až potom říci že tlačítko bylo stisknuto ?
Spolehlivost správného naprogramování se sice trochu sníží, ale to samé platí i o šanci na zničení portu.
Ten programátor není dobrý - je nebezpečný pro PC.
U tlačítek záleží co je to za tlačítka. Pokud jsou to klasické mikrospínače s hysterezí, tak stačí i půl milisekundy.
Kdybys sem hodil kus kódu abychom věděli, o čem se vlastně bavíme, taky by to třeba pomohlo .
Teď se snažím udělat tlačítka. Ideálně by to bylo takto (v přerušení přerušení mi to běhalo) - po ťuknutí po 10ms (zákmit) zkusím znovu přečíst, pokud bude opět stisknuto, přičtu k neznámé 1. Pokud bude stisknuto i po 300ms, přičtu 9 (takže celkem 1 nebo 10 a zobrazim). Pokud bude i poté po 300 ms stále drženo, tak budu přičítat 10 a zobrazovat (po 300ms), dokud nepustím.
Takže ve výsledku se krátké ťuknutí rovná přičtení 1, delší ťuknutí a případné držení se rovná stálé přičítání 10.
Ale teď vůbec nevím jak na to. Nebylo by nejlepší v hlavní smyčce programu jednou za 10 ms (klidně i více) číst tlačítka, ukládat si jejich stav. Pokud bude stav jednou za několik přečtení stejný, tak změnit hodnotu ?
Tak už mi to jde. Doupravil jsem ty tlačítka. V hlavní smyčce programu se jednou za 50 ms čte stav tlačítek a jejich stav se ukládá. Pokud je několikrát po jejich přečtení stejný, změní se hodnota. Takže mi vypadlo jedno (občas i dlouhé) přerušení, takže se mi už nevyskytuje přerušení v přerušení. Funguje s programátorem i bez něj.
Ještě by mi prosím zajímalo - jak udělat s pinu kde je reset normální výstup (PC6) ? Běžné DDRC= (1<<PC6); PORTC = (0 <<PC6); nefunguje.
Díky za informaci
Ale teraz vážne, ak chceš normalne pracovať a preprogramovávať procesor cez ISP (nie SPI, ale ISP, čiže in system programing) na reset nešiahaj. Ak Ti nevadí procesor neustále vyťahovať z aplikácie a dávať ho do HV programátora kvoli jednej ušetrenej nožičke procesora, tak kludne baštrnguj s poistkou od resetu. Na Tvojom mieste by som radšej použil procesor s viacerymi nožičkami.
Tak už mám doma krystal - zapojen i s kondenzátorama. Jak mám přinutit procesor, aby pracoval s frekvencí krystalu ? Co jsem se díval tak něco jako CKSEL3…1 na 001 ? A ještě SUT1…0 na něco ?