www.mikrocontroller.net

Forum: Compiler & IDEs Timing für interne Uhr


Autor: Mario Richter (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Uwe Nagel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Mario Richter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: ---- (Gast)
Datum:

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

----, (QuadDash).

Autor: Mario Richter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.