Forum: Compiler & IDEs Timing für interne Uhr


von Mario Richter (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich hab ein größeres Projekt im Kopf, und zwar will ich mir eine
Nixie-Funkuhr bauen, d.h eine Uhr, die als Anzeige die schönen,
nostalgischen Röhren verwendet (Wer's nicht kennt, mal durchgoogeln,
das lohnt sich ;-)).

Mein erster Vorversuch besteht darin, erst mal die Software, sprich die
Funkuhr mit einem 2x16 LC-Display zu realisieren. Die Uhr soll beim
Einschalten und dann jeweils nachts um 4:00 Uhr synchronisieren,
dazwischen läuft eine interne Uhr und der DCF-Empfänger ist aus.

So weit so gut, im Prinzip läuft die Software auch schon. ABER: Das
Timing passt nicht. Die Uhr läuft ca. jede halbe Stunde eine Sekunde
voraus, und das ist natürlich schon recht viel. Ich hab meine Schleifen
schon gecheckt, rein rechnerisch müsste das passen.

Ich hab den Quelltext mal angehangen, im Prinzip läuft es so ab: Ich
hab einen Interrupt, der alle 5ms aktiviert wird (über den Output
Compare Interrupt von Timer1). Das ist dann meine Zeitbasis für die
DCF-Auswertung. Darüberhinaus hab ich in der Interruptroutine einen
Zähler, der von 1 bis 200 zählt (200 x 5ms = 1s) und bei jedem Überlauf
die Uhr weiterzählt. Der µC läuft mit einem 4MHz-Quarz.

Trotz Quarz und genauer Rechnung (die wahrscheinlich doch irgendwo
einen Pferdefuß hat) hab ich diese zeitliche Verschiebung, wie gesagt
etwa 2s pro Stunde, die die Uhr falsch geht.

Woran kann das liegen ? Was kann ich noch tun ? (Sicher, ich könnte die
Zählerwerte hinfummeln, aber das scheint mir irgendwie primitiv -- es
muss doch einen Grund geben, warum das nicht ganz stimmt.)

Im Voraus vielen Dank für Eure Mühe,

schöne Grüße, Mario

von Uwe Nagel (Gast)


Lesenswert?

Ich denke, dein clock_count zählt eigentlich nur von 1 bis 199! Denn im
200. Interrupt setzt Du ihn schon wieder auf 1.
Du solltest ihn auf 0 setzen.
Allerdings würde das eine Beschleunigung von 5ms pro Sekunde bedeuten,
also etwa 18 Sekunden pro Stunde...

Da ist ja noch ein Bug:
  outp (0x4E, OCR1AH);            // (1/4MHz) * 20000 = 5ms, 20000 = 
0x4E20
  outp (0x19, OCR1AL);            // --> wegen CTC-Delay 1 abziehen !

Was ist 0x4e20-1 ? Mein Taschenrechner sagt 0x4e1f !

Uwe

von Jörg Wunsch (Gast)


Lesenswert?

Vielleicht sollte man das Hex-Rechnen ja gleich dem Computer
überlassen?

OCR1AH = (20000 - 1) >> 8;
OCR1AL = (20000 - 1) & 0xff;

Warum eigentlich überhaupt so umständlich und nicht gleich

OCR1A = 20000 - 1;

? :-)

inp/outp/cbi/sbi wirfst Du bitte gaaaanz weit weg.  Die sind seit zwei
Jahren überflüssig, in der Entwicklerversion der avr-libc gibt es sie
schon nicht mehr.

von Mario Richter (Gast)


Lesenswert?

Hallo,

super, das war's, das ist mein Fehler gewesen: Das Hex-Rechnen. 0x4E20
minus 1 ist gleich 0x4E1F ... Blöder Anfängerfehler, aber auch ;-)

Der clock_count passt jedoch, ich lass ihn ja weiterzählen, solange er
nicht auf 200 ist, so dass es am Schluss einen Durchlauf gibt, wo er
auf 200 steht. Dann geht's bei 1 weiter.

Nochmal vielen Dank an Euch beide !

@Jörg: inp/outp hab ich vernichtet, aber gibt's eine aktuelle
Alternative zu cbi/sbi ? (außer AND / OR)

Grüße, Mario

von Jörg Wunsch (Gast)


Lesenswert?

Die cbi/sbi Makros sind am Ende nur &~ bzw. | (guck im Headerfile
nach).  Warum willst Du also unbedingt eine andere Alternative haben
als die, die Standard-C ohnehin schon bietet?  Es gibt keinen Grund
für nicht-Standard-Konstrukte, wenn Standard-C das Feld komplett
abdeckt.

von ---- (Gast)


Lesenswert?

@jörg: Wie erklärst/rechtfertigst du dann den Einsatz von 'diesem'
_BV()-Makro?

----, (QuadDash).

von Mario Richter (Gast)


Lesenswert?

Hallo,

noch ein kleiner Nachtrag zu meinem Problem. Ich habe festgestellt,
dass trotz richtiger Timereinstellung die Uhr immer noch nicht 100%
synchron lief. Dann bin ich drauf gekommen, dass man bei den
Kondensatoren am Quarz verschiedene Werte testen und so den Oszillator
etwas hinziehen kann. Bei mir waren es zweimal 22 Pikofarad, die die
Uhren nun absolut gleich laufen lassen.

Grüße, Mario

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.