www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Uhr läuft ungenau


Autor: Michael (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Guten Tag!

Ich bin gerade dabei mit dem AT90S8535 eine Uhr zu realisieren.
Ich verwende da den 16Bit Timer1. Den Timer1 habe ich auf 100ms
eingestellt.
Jetzt läuft meine Uhr nicht genau.
Wie kann ich softwaretechnisch das so lösen, dass meine Uhr genau
läuft?

Im Forum habe ich schon ein paar Anregungen gelesen. Das alles bringt
mich nicht weiter.
Für Unterstützung bin sehr dankbar.

Gruß

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Im Forum habe ich schon ein paar Anregungen gelesen. Das alles bringt
mich nicht weiter."

Wie soll man Dir dann noch helfen?

Autor: Daniel Nöthen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vergleiche doch einfach mit einer Funkuhr, wie ungenau deine Uhr läuft.
Läuft sie pro Tag 2 Sekunden vor/nach, dann wirkst du per Software dem
entgegen.

Gruß,
Daniel

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Daniel!

Eine andere Möglichkeit gibt es nicht, um festzustellen wie weit die
Uhr wegläuft?

Autor: Daniel Nöthen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Doch, Du könntest Messen wie ungenau Deine Quarzfrequenz ist und dann
rechnen...
Glaub der Weg mit der Funkuhr ist aber um einiges leichter.

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aber natürlich geht's auch anders: hinreichend genauen Frequenzzähler
besorgen ;-) und an einem separaten Takt-Ausgang die Frequenz messen
(am Quarz natürlich nicht, verfälscht die Messung).

Genauer wird's übrigens auch dann, wenn der Timer nicht in der
Interrupt-Routine neu gesetzt wird, sondern der CTC-Modus genutzt wird,
in dem sich der Timer selbst bei erreichen des Limits neu setzt.
Ansonsten ist die u.U. recht variable Interrupt-Latency mit in der
Kalkulation drin. Ich weiss freilich grad nicht, ob der AT90S8535 den
CTC-Mode kennt.

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmmm...danke für die zahlreichen Infos.
Was wäre jetzt am besten zu realisieren? Auf jedenfall will ich den
Timer1 nutzen und ohne externe Bauteile.

Autor: peter dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Jetzt läuft meine Uhr nicht genau.
Wie kann ich softwaretechnisch das so lösen, dass meine Uhr genau
läuft?"

Das ist Wischiwaschi !

"Genau" ist keine Zahlenangabe !


Sag doch einfach:

Die Abweichung beträgt > xx Sek./Tag.
Ich benötige aber < yy Sek./Tag.

Dann erst kann man auch was dazu sagen.


Peter

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
und was heisst "ohne externe Bauteile"? Du meinst doch nicht etwa den
internen RC-Osz als Zeitbasis? Dann vergiss es direkt.
Deutlich besser bist du da mit der Netzfrequenz bedient, die
Langzeitstabilität ist ziemlich gut.

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Differenz zwischen Funkuhr und eigene Uhr beträgt 20 Sekunden bei
einer Läufzeit von 1 Stunde. Meine Uhr läuft 20 Sekunden vor.

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und als Taktquelle benutzt Du ... den internen RC-Oszillator?
Der ist ungenau. Soll's genauer sein, wirst Du um einen
temperaturkompensierten Quarzoszillator ("Quarzofen") kaum
herumkommen.

Oder Du vergisst die Idee und implementierst statt dessen eine Funkuhr.

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry ich hab mich da vertan. Ich habe einen 8Mhz Resonator am
Controller hängen.

Autor: Stephan Hochberger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und welche Toleranz und Stabilität hat wohl der Resonator so???

Autor: Andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi!

Du hast hier folgendes:

if (zehntelsek < 9) ++zehntelsek;
else
    {
     zehntelsek = 0;
     if (sekunden < 59) ++sekunden;
     else
        {
        sekunden = 0;
        if (minuten < 59) ++minuten;
        else
           {
           minuten = 0;
           if (stunden < 23) ++stunden;
           else
              {
              stunden = 0;
              }
           }
        }
    }

Solte das nicht besser so sein um jede Sekunde, Minute und Stunde
wirklich voll zu kriegen?

if (zehntelsek < 10) ++zehntelsek;
else
    {
     zehntelsek = 0;
     if (sekunden < 60) ++sekunden;
     else
        {
        sekunden = 0;
        if (minuten < 60) ++minuten;
        else
           {
           minuten = 0;
           if (stunden < 23) ++stunden;
           else
              {
              stunden = 0;
              }
           }
        }
    }

1 Sekunde sind ja 10 Zehntel Sekunden und nicht 9 Zehntel, 1
Minute/Stunde 60 Sekunden/Minuten und nicht 59.

So ne krasse Abweichung liegt glaube ich nicht an dem externen Quarz
oder an einem um 1 zu geringen Timer-Wert.
Ansonsten schadet es nicht, das setzen des Timers am Anfang der ISR zu
schreiben.
Für 1 Zehntel Sekunde brauchst Du dann 8000000/64/10 = 12500.
Für die Timerregister dann 65536 - 12500 = 53036 (CF2C).

Gruß
Andi

Autor: Andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab da was vergessen:

           if (stunden < 24) ++stunden;

Gruß
Andi

Autor: Jens123 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast da
if(zehntelsek < 10) ++zehntelsek;

hiess das nicht wenn zehntelsek kleiner 10 ist??

wieso machst du das nicht so:

if(zehntelsek == 9)
{
   zehntelsek = 0;
   ++sekunden;
}


if(sekunden == 59)
{
   sekunden = 0;
   ++minuten;
}

irgendwo hatet ich mal gelesen, dass man vermeiden soll sehr tiefe
verschachtelungen zu programmieren..


wie setzt du denn zehnztelsekunden mit einem timer??

Gruss Jens

Autor: Andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wieso nur bis 9, 59 oder 23 Zählen?
Eine ganze Sekunde hat 10 1/10-Sekunden, eine ganze Minute/Stunde hat
60 Sekunden/Minuten und ein Tag 24 Stunden.
Also muß bis 10, 60, 60 und 24 hochgezählt werden.

Beispiel:
10 mal die 1/10-Sekunden um eins erhöhen:

Ausganswert  0
 + 1 1/10 =  1 ( 1. mal) ZehntelSek < 10
 + 1 1/10 =  2 ( 2. mal) ZehntelSek < 10
 + 1 1/10 =  3 ( 3. mal) ZehntelSek < 10
 + 1 1/10 =  4 ( 4. mal) ZehntelSek < 10
 + 1 1/10 =  5 ( 5. mal) ZehntelSek < 10
 + 1 1/10 =  6 ( 6. mal) ZehntelSek < 10
 + 1 1/10 =  7 ( 7. mal) ZehntelSek < 10
 + 1 1/10 =  8 ( 8. mal) ZehntelSek < 10
 + 1 1/10 =  9 ( 9. mal) ZehntelSek < 10
 + 1 1/10 = 10 (10. mal) ZehntelSek NICHT < 10 also auf 0 setzen und
Sekunden auf die gleiche Art mit 60 bearbeiten.

Gruß
Andi

Autor: Michael Wilhelm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Andi,

mit 9,59 und 23 ist das okay, weil bei 0 mit dem Zählen angefangen
wird.
MW

Autor: Benedikt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein großer Fehler ist das Nachladen des Timers. Du weißt nie genau, wann
die Interruptroutine gestartet wird, daher müsstest du das Timerregister
auslesen, schauen wieviel Zeit seit dem eigentlichen
Interruptauslösenden Zeitpunkt vergangen ist und den neuen Wert
dementsprechend verringern. Ich habe mich mit den Timern des AVR noch
nie so wirklich genau beschäftigt, aber hat der Timer keine Autoreload
Funkion so wie der Timer beim 8051 ?

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hat jemand einen Vorschlag wie ich meine Uhr jetzt genauer hinbekomme?

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Als erstes könntest Du Dir ja mal die verschiedenen Antworten in genau
diesem Thread hier durchlesen - Stephan hat Dir beispielsweise eine von
Dir unbeantwortete Frage gestellt.

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Benedikt: ob nun bei den AT90 weiss ich grad nicht, aber mindestens die
neueren Version haben einen Modus für automatischen Reload, den CTC-Mode
den ich oben schon erwähnte.

Autor: Michael (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Stephan!


Der Resonator hat folgende Toleranz siehe Anhang.

Autor: Stephan Hochberger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Für eine Uhr ist die Toleranz mE zu hoch. +/- 10s/h oder 4min/d
Mit Abgleich wird eine Abweichung von vielleicht 1s/h möglich sein.
Nimm lieber einen Quarz, oder besser Quarzofen.

Für die 20 Sekunden Abweichung muß es aber wohl noch nen anderen Grund
geben.

Autor: Michael (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Stephan!

Was meinst du zu meinem Quellcode. Ist der Compare Mode Interrupt
besser geeignet oder ist der Overflow Interrupt ausreichend?
Kann man sonst noch bei meinem Quellcode was verbessern?

Im Forum habe ich einene Beitrag von peter dannerger gelesen.
Da beschreibt er wie er seine Uhr programmiert hat. (siehe Quellcode)
Leider verstehe ich da nicht was er da macht.

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo....

Autor: Armin Kniesel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe immer am Anfang der Timerinterrupts den aktuellen Timerwert aus
dem Register ausgelesen und diesen Wert mit dem "Neuladen"-Wert
kombiniert. Weil bis das Programm in die Interruptroutine kommt vergeht
eine ungewisse (?) Zeit. Und diese kann man im Timerregister auslesen
und somit kompensieren.

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Armin!

Geht das auch mit dem Overflow Interrupt?

Autor: Jens123 (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
ich hatte sowas mal in asm geschrieben (mein erstes programm)

dabei hatte ich einen IOclock von 8MHz (interner RC Oszilator) und
einen externen quarz 32.irgendwas kHz (Uhrenquarz) an TOSc1 / 2.
ich hatte diese Uhr 2 Tage laufen lassen und konnte keine ungenauigkeit
erkennen..

zum testen hatte ich das ganze mal mit uart aufgebaut und immer dann,
denn der int handler aktiv wurde ein zeichen an den PC gesendet
mit dem Terminalprogramm bon Br@y (grosser lob) enpfanngen und mir die
Zeiten angeschaut, in den ndie Daten kahmen
war sehr genau..

im Anhang ist das Grundprogramm mit den Timersettings etc in ASM!!

Gruss Jens

Autor: Profi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie oft denn noch?
Die Idee mit dem Quarzofen ist zwar naheliegend, aber absolut unnötig.
Wie oft denn noch?
Die Idee mit dem Quarzofen ist zwar naheliegend, aber absolut unnötig.
Messe die Temperatur des Quarzes/Resonators und nimm aus einer
LookUp-Tabelle den passenden Teilfaktor.
So könntest Du sogar mit dem Resonator ausreichend genau werden.

Zum Timerproblem gibt es mehrere Möglichkeiten:
1. freilaufender Timer (ohne explizitem Nachladen) mit AutoReload
2. freilaufender Timer ohne jeglichem Reload, bei dem der Compare-Wert
aus dem vorhergehenden mittels ADD-Befehl berechnet wird.


Wenn Dir die Dekodierung des DCF77-Signals zu kompliziert ist, kannst
Du auch dessen hochstabilen 77,5kHz-Träger teilen oder nur die
Sekundenimpulse zählen (es werden aber nur 59 Sekundenimpulse pro
Minute gesendet, den einen fehlenden (zum Minutenwechsel) musst Du
selbst generieren).

Jeder bessere Uhrmacher hat eine "Quarzwaage", die akustisch oder
induktiv den Sekundenimpuls der Uhr aufnimmt und die Abweichung sofort
anzeigt (eigentlich ein hochauflösender Frequenzzähler).

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.