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 User
if (seconds == 59) //60 seconds { seconds=0; minutes++; } Warum hat die Minute bei dir nur 59 Sekunden?
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 ....
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).
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.
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....
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
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
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.
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.
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
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
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.
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
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.