mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ist meine software Uhr sauber programmiert?


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

Bewertung
0 lesenswert
nicht lesenswert
Moin,

ich habe eine Uhr ohne ISR geschrieben die leider alle ~20min eine gute 
Sekunde vorgeht.

Ich benutze einen Atmega328P mit einem externen 20Mhz Quarz an xtal. Die 
Fuses sind dementsprechend gesetzt von daher gehe ich "erstmal" davon 
aus das damit nichts verkehrt ist.

Kann mir jemand sagen ob meine Zählvariablen denn vom Grundsatz stimmen 
(mal angenommen das das Quarz exakt mit 20Mhz schwingt). Ich vermute 
nämlich eher das meine Zählvariablen fehlerhaft sind.

Was habe ich programmiert:
Der Takt von 20Mhz wird durch den Prescaler von 256 des Timer0 auf genau 
78125 runtergebrochen. Würde ich den Zähler TCNT0 bei 125 wieder 
zurücksetzen könnte ich eine Hilsvariable bis 625 zählen lassen und 
hätte zumindest in der Theorie einen genauen Takt von 1sek. Leider nur 
in der Theorie :(

Danke an alle Antwortenden!

gruß f.

: Verschoben durch Moderator
Autor: Thomas Forster (igel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
if (seconds == 59) //60 seconds
        {
          seconds=0;
          minutes++;
        }

Warum hat die Minute bei dir nur 59 Sekunden?

Autor: Ro N (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich gehe schwer davon aus, dass wenn deine Routine, die Werte 
auszuschreiben ausgeführt wird, TCNT0 schon wieder über 124 ist. D.h. du 
verpasst da einen, vielleicht sogar mehrere Überlaufe. Prüfe auf >=.
Ich würde im Interrupt timer0_counter hochzählen, ein Flag setzen und in 
der Hauptschleife prüfen ...
Selbst wenn der Oszi nicht so genau ist (Temperatur, Drift, ...) ist 1s 
pro 20min definitiv zu viel ....

Autor: Thordy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thomas F. schrieb:
> if (seconds == 59) //60 seconds
>         {
>           seconds=0;
>           minutes++;
>         }
>
> Warum hat die Minute bei dir nur 59 Sekunden?

Ich glaube auch das du hier eine 60 statt der 59 eintragen musst. Du 
setzt die 59 nämlich wieder direkt auf 0 obwohl die Sekunde noch nicht 
abgelaufgen ist.

Ansonsten würde ich versuchen die LCD Routine nicht ständig 
aufzurufen(raus aus der while).

Autor: Peter II (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ro N schrieb:
> Ich gehe schwer davon aus, dass wenn deine Routine, die Werte
> auszuschreiben ausgeführt wird, TCNT0 schon wieder über 124 ist. D.h. du
> verpasst da einen, vielleicht sogar mehrere Überlaufe.

nicht bei einen Vorteiler von 256.

Es wird ja in einer minischleife nur dieser wert verglichen. Das kann 
nicht das Problem sein.

Wenn das Programm irgendwann mal mehr machen musst, wird es zu einem 
Problem.

Autor: Thordy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thordy schrieb:

> Ansonsten würde ich versuchen die LCD Routine nicht ständig
> aufzurufen(raus aus der while).

Sorry hab nicht richtig hingeguckt. Du rufst die garnicht ständig 
auf....

Autor: egberto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und warum nimmst du keine ISR?
Das hätte den Vorteil, das du das ganze zeitkritische bzw. 
Counter/Vergleichs Zeugs vom Hauptprogramm getrennt hättest und dich in 
der weiteren Programmierung nicht mehr darum kümmern müsstest.

Grüße,

egberto

Autor: Philipp K. (philipp_k59)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schonmal die Frequenz vom Quarz gemessen?

Für 1 Sekunde in 20 Minuten müsste der Quarz 20.016.666Hz Takten oder 
deine Zähler sich um 16.666/256=0,065 Takte die Sekunde verzählen..

Das macht dann knapp 78 Takte in 20 Minuten.

: Bearbeitet durch User
Autor: fldrms (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin & Danke für Eure Antworten!

Ich denke auch das im Gleichsetzen meiner Variablen der Hund begraben 
liegt.
Bei TCNT0 == 124 & timer0_counter == 624 & seconds == 59 geht mir 
jeweils ein "count" verloren.

Für eine genaue Sekunde benötige ich bei einem prescale von 256 und 
20Mhz
- 125 "Ticks" bei TCNT0 müssen lauten TCNT0 <= 125
- 625 "Ticks" bei timer0_counter müssen lauten timer0_counter <= 625
- 60 "Ticks" für eine Sekunde müssen lauten seconds <= 60

Alles natürlich unter der Annahme das der Quarz sauber tickt.

mfg f.

Autor: fldrms (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
egberto schrieb:
> Und warum nimmst du keine ISR?
> Das hätte den Vorteil, das du das ganze zeitkritische bzw.
> Counter/Vergleichs Zeugs vom Hauptprogramm getrennt hättest und dich in
> der weiteren Programmierung nicht mehr darum kümmern müsstest.
>
> Grüße,
>
> egberto

Moin,

das wird der nächste Schritt werden. Ich wollte nur erstmal gegengeprüft 
bekommen ob denn überhaupt der Grundgedanke per Softwarelösung stimmt. 
War mir doch recht uneinig wegen den Variablen. Sprich ==124 oder <=125 
etc.

Autor: fldrms (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
fldrms schrieb:
> - 125 "Ticks" bei TCNT0 müssen lauten TCNT0 <= 125
> - 625 "Ticks" bei timer0_counter müssen lauten timer0_counter <= 625
> - 60 "Ticks" für eine Sekunde müssen lauten seconds <= 60

- 60 "Ticks" (Sekunden) für eine Minute müssen lauten seconds <= 60

Autor: Philipp K. (philipp_k59)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andere Idee bevor hier alles den Code auseinandernimmt..

Zähle die Sekunden in einer Extra Variable komplett hoch und Vergleich 
das mit deinen Minuten*60+Sekunden.

: Bearbeitet durch User
Autor: fldrms (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
fldrms schrieb:
> fldrms schrieb:
>> - 125 "Ticks" bei TCNT0 müssen lauten TCNT0 <= 125
>> - 625 "Ticks" bei timer0_counter müssen lauten timer0_counter <= 625
> - 60 "Ticks" (Sekunden) für eine Minute müssen lauten seconds <= 60

So jetzt hab ich mich selbst verhaspelt...

hoffentlich richtig ist:
>> - 125 "Ticks" bei TCNT0 müssen lauten TCNT0 == 125
>> - 625 "Ticks" bei timer0_counter müssen lauten timer0_counter == 625
> - 60 "Ticks" (Sekunden) für eine Minute müssen lauten seconds == 60

Sonst würden die Schleifen ja für jeden Wert kleiner einmal durchlaufen 
werden. Damit würde eine Sekunde definitiv nicht mehr stimmen.

Autor: Philipp K. (philipp_k59)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
fldrms schrieb:
> Alles natürlich unter der Annahme das der Quarz sauber tickt.

Angenommen während Du schon so schön alles auseinander klamüserst..

Der Quarz tickt nicht Sauber.. Das kann eben mal je nach Temperatur in 
den letzten 3-4 Stellen variieren. Das sind eben mal 1,5 Takte hinter 
dem Divider die Du ja schon genau zählen möchtest.

Bedeutet bei 30ppm Standard Toleranz und 20ppm Abweichung eben mal 
960.0000 Ticks in 20 Minuten.. immerhin genau eine 20/Sekunde.. Dann 
würdest Du dich spätestens in 20 Stunden wieder Fragen woher die Sekunde 
kommt.

Das Problem ist, die Quarze sind Super um Signale in einer Sekunde zu 
messen..

z.B 1uS sind ca 20 Takte.. ob da nun wegen der Grundtoleranzen/PPM 2 
mehr oder weniger rausspringen ist egal, für eine Uhr addiert sich 
dieser Fehler spätestens nach einem Tag oder 1Stunde und 3 
Temepraturschwankungen hoch.

EDIT: Übrigens ein Keramikresonator hat auch mal 10%-20%Toleranz.. das 
heisst der Tikt eben auch mal nur 19,5Mhz und ist in vielen Arduinos 
verbaut.. merkt auch keiner wenn er nicht Sekunden zählen will.

: Bearbeitet durch User

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.