Hallo,
ich habe nur eine kleine Frage zur Codeoptimierung einer Uhr. Und zwar
rufe ich alle mithilfe einer ISR die main-Funktion alle 50ms auf und
frage mich nun, ob es Sinn macht mit größeren Intervallen von z.B. 500ms
zu arbeiten, da die Uhr nicht sonderlich genau geht. (ca. 5 Sekunden in
einer Woche; oder ist das in Ordnung für einen AtMega 8, der mit einem
4MHz Quarz getaktet ist?)
Folgender Code regelt den Aufruf:
Alternativ kann ich das Hauptprogramm (solange man nicht im Menü ist)
auch nur alle 500ms aufrufen. Doch hat man dadurch einen Vorteil
gegenüber der ersten Variante oder kostet das "auswerten" der
if-Bedingung genausoviel Zeit als ob ich dauerhaft im 50ms-Intervall
arbeite?
Lukas B. schrieb:> if-Bedingung genausoviel Zeit als ob ich dauerhaft im 50ms-Intervall> arbeite?
Uh.... hast du noch ein Byte RAM übrig? Bau damit einen zweiten Zähler,
der nur dein Aktualisierungsinteral abmisst. So sparst du dir deine
if-or-or-or-ORgie.
Dann:
Lukas B. schrieb:> (ca. 5 Sekunden in> einer Woche; oder ist das in Ordnung für einen AtMega 8, der mit einem> 4MHz Quarz getaktet ist?)
Jo, ganz normal. Kannst entweder versuchen den Quarz mit einem Dreko zu
ziehen, oder per Software ausgleichen.
AVR - Die genaue Sekunde / RTC
Lukas B. schrieb:> ... da die Uhr nicht sonderlich genau geht. (ca. 5 Sekunden in> einer Woche
Das läßt sich besser hinkriegen, wenn der Quarz nicht wilden
Temperaturschwankungen ausgesetzt ist.
Beitrag "Die genaue Sekunde / RTC"
Wenn die Ungenauigkeit normal ist, stört sie mich nicht. Auf ein Jahr
hochgerechnet sind das ja gerade mal ~4 Minuten pro Jahr, damit kann ich
leben, zumal der Wecker sowieso alle 6 Monate gestellt werden muss
(Sommer-, Winterzeit).
Für eine RTC habe ich leider keinen Port mehr frei, zumindest keinen von
den Interrupt-Ports.
@crazy horst: Danke, das sieht besser aus.
Lukas B. schrieb:> @crazy horst: Danke, das sieht besser aus.
Das sagst du jetzt, bevor du gesehen hast, wieviel Code der Compiler aus
dem harmlos aussehenden '% 50' macht und wie lang er dann in deiner ISR
rechnet...
Lukas B. schrieb:> Für eine RTC habe ich leider keinen Port mehr frei
Sowohl der von mir verlinkte Artikel als auch Michaels Forums-Link (aus
dem der Artikel hervorgegangen ist) enthalten Beispiel-Code wie man
ohne extra RTC-Chip rein softwaremäßig den falsch Laufenden Quarz
ausgleicht.
Lukas B. schrieb:> Wenn die Ungenauigkeit normal ist, stört sie mich nicht.
zumal der Wecker sowieso alle 6 Monate gestellt werden muss
(Sommer-, Winterzeit)
Warum "hängst" du dich nicht an die Netzfrequenz? Die EVUs sorgen schon
dafür, dass Uhren, die die Netzfrequenz als Normal nutzen, nicht "falsch
gehen".
@Εrnst B✶: Also doch wieder if(...||...,usw.)? Oder wie sieht deine
Lösung in der Praxis aus? Ich kann mir das nicht so ganz vorstellen.
@RTC: Ich gucke es mir mal an.
Lukas B. schrieb:> Also müsste ich den Timer> anders einstellen, sodass er nur alle 50ms aufgerufen wird, richtig?
ja oder wenn das nicht geht (wegen teiler) dann kannst du auch im timer
bis 50 zählen und dann erst die 50ms-Variable hochzählen.
Dann kannst du auch gleich aus dem 16bit wert ein 8bit wert machen, dann
rechnet sich dann für den µC einfacher.
Peter II schrieb:> Dann kannst du auch gleich aus dem 16bit wert ein 8bit wert machen, dann> rechnet sich dann für den µC einfacher.
Wie mache ich das denn?
ist schon deswegen ungünstig, weil die Laufzeit für
den Fall "millisekunden == 950" anders ist als für den Fall
"millisekunden == 0" (wegen "short-circuit evaluation" von logischen
Ausdrücken in C).
Spielt vielleicht im vorliegenden Fall nicht so die Rolle, aber hässlich
aussehen tut´s in jedem Fall.
Murx
Lukas B. schrieb:> Für eine RTC habe ich leider keinen Port mehr frei, zumindest keinen von> den Interrupt-Ports.
Seit wann braucht Software eine Port?
Ein Click ...
@Michael: Das war nur ein Missverständnis, ich dachte bei RTC an einen
externen Baustein.
@Murx: Ich habe es jetzt so gelöst, dass die ISR nur alle 50ms
aufgerufen wird, ich denke, das ist die eleganteste Lösung. Nur das
Problem mit den 16-bit Variablen ist irgendwie seltsam.
Lukas B. schrieb:> Momentan ist der Datentyp unsigned int, aber wenn ich ihn auf uint8_t> (etwas anderes erkennt der Compiler nicht) ändere, wird nichts mehr> hochgezählt.
uint8_t geht ja auch nur bis 255 - da passen deine 1000ms nicht rein.
Aber wenn du in 50ms schritten arbeitets dann brauchst du nur 0-200 und
das passt rein.
Zeig uns doch mal das ganze programm, wenn du immer int verwendest, hast
du noch viel mehr optimierungsmöglichkeiten als die IF abfrage.
Stimmt, du hast recht, jetzt funktioniert es. :D
Der gesamte Code befindet sich im Anhang. Wenn ihr noch Fehler oder
Optimierungspotential findet, sagt Bescheid.
P.S. Das ist mein erstes richtiges Programm, ich bitte um Nachsicht. ;)