Forum: Mikrocontroller und Digitale Elektronik ATMEGA16 UHR mit Timer0


von rene (Gast)


Lesenswert?

hallo zusammen...abe ein kleines Problem und komme nicht so richtig 
weiter...

Habe ATMEGA16 mit 7,372 MHz und habe den Timer0 wie folgt eingerichtet:

void timer0_init(void)
{ // dient zum erzeugen der Sek Takte der Offline Clock
 TCCR0 = 0x00;  //stop
 TCNT0 = 0x00;  //load counter
 OCR0  = 0x7A;  //set compare // berechnet 0x7a
 TCCR0 = 0x0D;  //start timer with Prescale 1024
}

der Interrupt wird 59mal in der Sek erzeugt und ein Counter zählt die 
1/59Sek.

Leider ist es mir nicht möglich denn Takt auf einen Wert zu senken, der 
einen Zwischencounter nicht erforderlich macht.

die Uhr sollte Sek. genau laufen. macht sie aber nicht. Abweichung ca. 
20Min/24h.

Es laufen noch andere Interrupts zum Decodiesen eines DCF Signals.
weiterhin werden 1mal pro Sekunde 7xI2C Sensoren abgefragt.

kann es sein, das ich etwas zu viel verlange???
wie macht Ihr das mit der Offline clock???

MfG
rene

von Andreas K. (a-k)


Lesenswert?

Die Möglichkeit, mit einem 8-bit Timer auf leidlich exakte Sekunden zu 
kommen, ist naturgemäss begrenzt, wenn die Taktfrequenz nicht zufällig 
genau aufgeht. Und das tut sie hier nicht, ich komme auf ca. 58,5 
Interrupts pro Sekunde. Das allein sorgt bereits für eine Abweichung von 
etwa 12 Minuten täglich.

Genauer wird das mit diesem Timer nur, wenn du den Fehler in die 
Software einarbeitest. Das dazu notwenige Verfahren sollte seit Julius 
Caesar hinreichend bekannt sein, denn die Taktfrequenz "Erdrotation" 
passt ja auch nicht genau zum Sonnenjahr.

Mit einem 16-bit Timer wird's einfacher.

von Karl H. (kbuchegg)


Lesenswert?

Sieh dir mal das hier an
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Uhr

Da sind einige Gedankengänge zu diesem Thema. Bis hin
zur endgültigen Lösung.

von AVRFan (Gast)


Lesenswert?

>Leider ist es mir nicht möglich denn Takt auf einen Wert zu senken, der
>einen Zwischencounter nicht erforderlich macht.

Wieso nicht?  Während eines Zeitraums von 20 ms kann ein mit 8 MHz 
getakteter AVR ungefähr 100000 Instruktionen abarbeiten.  Ist das in 
Deiner Anwendung wirklich zu wenig?

Der Trick bei der ganzen µC-Programmiererei ist, sich die Tatsache 
zunutze zu machen, dass 20 ms (Richtwert) für den Controller ziemlich 
lang, für Menschen dagegen ziemlich kurz ist: bei 50 Refreshs pro 
Sekunde werden Reaktionen auf Eingaben mit Tastern etc. als unmittelbar 
wahrgenommen.

Wie wäre es also, wenn Du einen (nur einen!) Timer mit z. B. 20 
ms-Interruptintervall aufsetzt, und alles, was Du an "Ticks" in Deinem 
Programm brauchst, per Software-Teilung daraus ableitest? Das einzige, 
was dann verboten ist, ist der Einsatz von Warteschleifen ("1800000 mal 
'nop' ausführen, damit anderthalb Sekunden vergehen").  Jeder Task in 
Deinem Programm prüft bei jedem 20 ms-Tick nach, ob er gerade was zu tun 
hat, tut es gegebenenfalls (was in 10 oder 100 oder 1000 Taktzyklen 
erledigt ist), und wenn alle Tasks ihre Zustände geupdatet haben, legt 
sich der µC schlafen bis der nächste Tick ihn wieder aufwacht.  Wenn Du 
willst, dass ein Task irgendwann z. B. 3 s warten soll, lässt Du eine 
Zählvariable von 150 herunterzählen, und der Task tut solange nichts 
(außer sie bei jedem 20 ms-Tick zu dekrementieren), solange sie nicht 
die 0 erreicht hat.

Vielleicht kannst Du Dich ja von diesem Ansatz inspirieren lassen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.