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
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
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.
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
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.
@jörg: Wie erklärst/rechtfertigst du dann den Einsatz von 'diesem' _BV()-Makro? ----, (QuadDash).
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.