Reálný čas - je ATmega32 schopna generovat přesný čas?

Ahoj,

mam atmegu32, dělám domácí alarm. Chtěl bych mít na displeji hodiny, abych mohl evidovat aktivace a deaktivace alarmu.
Je atmega32 sama schopna generovat přesný čas po sekundách s minimální odchylkou nebo musím použít extermí obvod např. DS1302 ?
Pokud je schopna. Prosim o sběžný navod, jak to realizovat.

Nejsem v tom moc sběhlý. diky za info

:arrow_right: administrator: přejmenováno z "ATmega32 - reálný čas ?"

nO KED POUZIJES EXTERNY Rtc obvod tak ma zaroven zalohovany cas kondikom…
ZAza u uP musis mat prerusenie aby to slo presne… a rozne odskoky a priskoky mozu sposobit nepresnost casu.

Lze to, přesnost je dána pouze přesností oscilátoru procesoru.
Spustíš čítač a aktivuješ mu přerušení při přetečení. V tom přerušení si budeš počítat kolikrát přetekl (např. každých 100ms) a až napočítáš celou vteřinu, přičteš si 1 ke vteřinám. Po 60 vteřinách přidáš k minutám atd… Počet přetečení čítače za vteřinu ani nemusí být celočíselný násobek. Vyžaduje to sice kousek programu navíc, ale lze tam dolaďovat přesnost když si zakomponuješ podporu :wink:. Akorát nevím, jakou stabilitu udrží oscilátor v procesoru s porovnáním s externím obvodem.

Tak se mi to podařilo. No ale mam trosku problem s přesnosti. Při frekvenci procaku 1MHz. Kazdé 488té přetečení je 1 sekunda. (pred delicka 8x) Avšak přesně by to mělo být: 488,281250000. No a ted prave nevim jak to udelat, abych tam dostal i tech 0,28125 cyklu. :frowning:

Jo a nevite jaka je funkce na prevod z cisla na pole znaků?

tzn. z unsigned char cislo; => unsigned char text] ?

diky

Předpokládám, že jedeš na interním RC - tam ti to bude lítat i 2% - v tom se 0,2… přetečení ztratí :laughing:. Každopádně až pojedeš na krystalu, tak prověď následující. Přidej ještě 1 přetečení. Potřebuješ, aby ti při tom přetečení navíc napočítal timer ještě 72. To zařídíš tak, že do počítacího registru čítače přičteš 256-72=184. Nezapisuj tam konstantu, ale skutečně přičti hodnotu, protože reakce na přerušení může být různá a čítač už má nějaké neurčité číslo napočítané. Tím přičítaným číslem si pak můžeš tu přesnost doladit v krocích po 0,0008%. Také to neprováděj v přerušení, kde aktualizuješ všechny časové proměnné - za těch 72 taktů bys nemusel celou obsluhu stihnout. Doporučuju to udělat až 1 přetečení po aktualizaci.

Atmegy mají možnost připojení hodinového krystalu, jeden čítač je na to přímo určen a nabízí 10-bit prescaler, takže se dá pohodlně generovat přerušení každou sekundu (max. každých 8s). V tomto režimu, ale musí MCU běžet na interní oscilátor

Pravda. Akorát mega32 má pro tento účel samostatné piny (TOSC) ve spojení s timerem2 (asynchro mód), takže by neměl být problém, aby měla hlavní hodiny z rychlého krystalu a timer2 bežel z 32,768kHz.

Ano mají, ale plnohodnotné RTC to není. Neobsahuje totiž žádné registry času ani kalendář, jako je to běžné u externích RTC. O to se musí postarat programátor. Zatím tu nebyla zmínka o tom, zda se má čas udržet i po výpadku napájení. To je docela velký problém vyžadující velmi dobrou znalost celého MCU. Neznalost povede k velké spotřebě proudu (až stovky uA), náhodnému zpožďování a ztráty času.
Začátečníkům bych spíše doporučil, pokud s tím nechtějí experimentovat, nějaký externí RTC třeba i s integrovanou baterií nebo ještě lépe s integrovaným krystalem a připojit to přes SPI nebo I2C k MCU jakéhokoli typu. Je to mnohem jednodušší to odladit a je to i spolehlivější.

Pokud někdo chce použít Timer 2 jako RTC na čipu MCU, připomínám, že MCU nesmí nikdy projít RESETem. To by znamenalo vynulování Timeru 2 včetně jeho registrů a zastavení oscilátoru. Jinými slovy, MCU by přišlo o čas.

souhlasím s Technikem - v aplikacích kde je potřeba pracovat s reálným časem je opravdu výhodnější používat nějaké to “hotové” RTCčko - nejběžnější jsou asi DS 1302 od Dallasu, nebo PCF 8583 od Phillipsu - ten první dokonce nabízí obvod pro dobíjení akumulátoru - ten druhý zas má výstup na kterém je 1Hz a mnoho dalších funkcí.
Na druhou stranu to znamená vytvoření funkcí pro čtení a zápis RTC - (zde mají výhodu uživatelé Codevisionu, který obsahuje pro nejběžnější I2C a 1wire obvody hotové knihovny) a nutnost prostudovat příslušný datasheet.

Ale jako “cvičení” napsat program pro RTC - proč ne?

TAk tu som nieco nakopiroval je tam I2C pripojitelna na lubovolne 2piny + RTCPCF8563 ale nemal by to byt problem prerobit na 8583
Je to v cecku pre PIC18F ale dasato prehodit na AVR kedze C :smiley:

Trocha je to neohabane lebo je to skopirovane s viacerych knihovien. NA zaciatku je I2C a na konci konkretne ovladanie PCFka res citanie udajov z neho, zapis by nemal byt problem…niekdy dokoncim…len momentalne vela prace.
I2C pcf8563 I2C.doc (28 KB)

Já to nechápu chlapi. Co delám špatně.

#define F_CPU 1000000UL // 1 MHz

Jednoduchy vypocet předděličkou 8x:
/* Interrupt Aktion alle
(1000000/8)/256 Hz = 488,28125 Hz
bzw.

tedy abych dosáhl 1s, musím tedy napočítat 488 přetečení + něco málo.

Ať dělám co dělám, trvá to oněco déle než vteřinu. asi po 10 minutách je rozdíl už 1 vteřina. Takže 255 + 233 = 488. Pak prictu v poslednim preruseni 184 tedy B8 v hexa. V čem dělám chybu ?

kod:

TCCR0 = (1<<CS01); // Prescaler 8
TIMSK |= (1<<TOIE0); // Overflow Interrupt erlauben
sei(); // Global Interrupts aktivieren

ISR (TIMER0_OVF_vect)
{
pocitadlo++;
if (max == 0 && pocitadlo == 255) { pocitadlo = 0; max = 1;}
if (max == 1 && pocitadlo == 233) TCNT0 += 0xB8;
if (max == 1 && pocitadlo == 234) { pocitadlo = 0; max = 0;
t.sekunda++; }
}

Vypocet, ktory si predviedol dava na kazdych 10 minut chybu 0,34 sekundy. To, co si nameral preto cca zodpoveda naprogramovanemu. To je totizto rozdiel medzi 488 a 488,28125.
Program som podrobne neskumal. Je taky divny - z hladiska toho, ako treba periferiu optimalne pouzivat. Ale ak je tam naprogramovane to co tvrdis a delis 256 a 488, potom je nespravne generovany cas presne to, co si si naprogramoval.

  1. ako si prisiel na frekvenciu 1MHz? Preco nepouzijes Xtal napriklad 14.7456MHz?

14745600/1024 = 14400

a kazdych 144 preruseni od casovaca inkrementujes jednu stotinu sekundy presne.
Alebo Xtal 7372800. To su uplne bezne hodnoty Xtalov.

  1. Ak chces robit nejake harakiri s casovacom pre deliaci pomer iny ako je 8/64/256/1024 treba pouzit mod 2. To je taky, kedy cnt pocita iba do hodnoty OCR0.

1000000MHz/256 a potom do OCR0 (casovac v mode 2) vlozis hodnotu 125, prerusenie dostanes PRESNE (ako len netemperovany Xtal moze byt) 125 krat za sekundu. Ziadne solichy a ziadne nepresnosti, ked sa zda ze tie desatiny, stotiny a tisiciny v prensych podieloch mozes zanedbat.

Doporucujem prestudovat vlastnosti CNT. Velmi dobre by sa na tuto ulohu hodil casovac 1, ktory je 16 bitovy.

Ak chces na generovanie presneho casu pouzit interny RC, na to hned zabudni. Ale o tomuz myslim bola diskusia v predchadzajucom.

Daj vediet, ako si dopadol.

P.S.
este k tvojmu programu. Co to tam vlasnte stvaras.
Uz ked chces napocitat do 488 nie je lepsie zadefinovat premennu pocitadlo ako int? Napriklad uint16_t ?

potom

pocitadlo++
if (pocitadlo == 488) {
pocitadlo = 0;
sekudna++; // toto treba samozrejme rozvinut
}

ale ako som uz pisal. Daleko lepsie je pocitat s casovacom do 250 (mod 2 top to OCR0=250) a kazdy patsty prechod inkrementovat sekundu.