Kurze Frage zu Codeoptimierung

Gast #2406005
Lesenswert?

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:
1
if(millisekunden == 950 || millisekunden == 900 || millisekunden == 850 || 
2
     millisekunden == 800 || millisekunden == 750 || millisekunden == 700 ||  
3
       millisekunden == 650 || millisekunden == 600 || millisekunden == 550 ||  
4
     millisekunden == 500 || millisekunden == 450 || millisekunden == 400 ||  
5
     millisekunden == 350 || millisekunden == 300 || millisekunden == 250 || 
6
     millisekunden == 200 || millisekunden == 150 || millisekunden == 100 ||  
7
     millisekunden == 50  || millisekunden == 0)
8
      updateTime = 1; //setzen des Aktualisierungsflags

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?
1
if(mode != 0 && 
2
    (millisekunden == 950 || millisekunden == 900 || millisekunden == 850 || 
3
     millisekunden == 800 || millisekunden == 750 || millisekunden == 700 ||  
4
       millisekunden == 650 || millisekunden == 600 || millisekunden == 550 ||  
5
     millisekunden == 500 || millisekunden == 450 || millisekunden == 400 ||  
6
     millisekunden == 350 || millisekunden == 300 || millisekunden == 250 || 
7
     millisekunden == 200 || millisekunden == 150 || millisekunden == 100 ||  
8
     millisekunden == 50  || millisekunden == 0))
9
      updateTime = 1; //setzen des Aktualisierungsflags
10

11
  //ist der Anzeige-Modus aktiv, nur alle 500ms aktualisieren
12
  if(millisekunden == 500)
13
      updateTime = 1;
#2406010
Lesenswert?

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
Gast #2406035
Lesenswert?

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.
#2406058
Lesenswert?

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.
Gast #2406066
Lesenswert?

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".
Gast #2406085
Lesenswert?

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.
Gast #2406122
Lesenswert?

Lukas B. schrieb:
1
> if(millisekunden == 950 || millisekunden == 900 || millisekunden == 850 || 
2
>      millisekunden == 800 || millisekunden == 750 || millisekunden == 700 ||  
3
>        millisekunden == 650 || millisekunden == 600 || millisekunden == 550 ||  
4
>      millisekunden == 500 || millisekunden == 450 || millisekunden == 400 ||  
5
>      millisekunden == 350 || millisekunden == 300 || millisekunden == 250 || 
6
>      millisekunden == 200 || millisekunden == 150 || millisekunden == 100 ||  
7
>      millisekunden == 50  || millisekunden == 0)

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
Gast #2406141
Lesenswert?

@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.
Gast #2406150
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren