-
Timer ungenau?
Zuerst einmal: Hallo!
Ich lese schon einige Zeit immer wieder im Forum und hole mir dadurch nützliches Wissen! Und eines muss gesagt werden, das Forum ist wirklich toll!
Jetzt muss ich aber doch einmal selbst schreiben, da ich nicht mehr weiterkomme!
Ich beiße mir nun schon seit 2-3 Tagen die Zähne an den Timern aus. Irgendwie habe ich damit leider so meine Probleme. Ich habe zwar die Vorladewerte mehrmals erfolgreich berechnet, komme aber in der Praxis nie zum richtigen Ergebnis.
Zuerst ging ich davon aus, dass die Timer mit dem externen Quarz arbeiten...Nach einigen Versuchen kam ich leider drauf, dass dies nicht so ist?
Ich habe mir dann Gedanken gemacht ob es noch irgendwo einen Takt gibt und habe es einmal mit dem Takt des Atmegas probiert. Und siehe da, bei einem Takt von 8 MHz und einem Vorladewert von 34285 an Timer1 war ich einer Sekunde nicht mehr so fern.
Meine neue Erkenntnis ist also, es ist vom Takt des Atmegas abhängig. Stutzig macht mich nur, dass ich eigentlich immer was von einem Quarz lese, welcher den Takt angibt.
Zur Annäherung habe ich ein kleines Programm geschrieben. Dieses gibt bei jedem Interrupt, also rein theoretisch, jede Sekunde die Uhrzeit und einen Zählerstand aus. Damit war es mir möglich Korrekturen beim Vorladewert zu treffen. Dies mache ich nun schon seit einem Tag mit mehreren Läufen, bekomme das aber nicht unter Kontrolle. Heute war dann ein Stromausfall und es fiel mir auf, dass bei gleichem Vorladewert in zwei Läufen die Abweichung unterschiedlich hoch ist. Im 1. Lauf war es eine Sekunde auf 20 Minuten und im 2. Lauf waren es 2 Sekunden auf 20 Minuten.
Kann mich bitte jemand aufklären, warum und wie das möglich ist?
Zum Einsatz kommt ein myAVR USB Board inkl. Display mit einem Atmega8.
Mein Annäherungsprogramm:
Code:
$regfile = "m8def.dat"
$crystal = 32768000
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
Config Lcd = 16 * 2
Config Portd = Output
Config Timer1 = Timer , Prescale = 256
On Timer1 Timer_irq
Enable Timer1
Const Timervorgabe = 33742
Dim Zaehler As Integer
Zaehler = -1
Config Pinc.2 = Output
Led3 Alias Portc.2
Enable Interrupts
Config Clock = Soft
Timer1 = Timervorgabe
Time$ = "00:00:00"
Do
Loop
Timer_irq:
Timer1 = Timervorgabe
Zaehler = Zaehler + 1
If Zaehler = 60 Then Zaehler = 0
Cls
Lcd Time$ ; " " ; Zaehler
Return
DANKE!
Lg
Phips[/code]
-
Ich hab zwar keine Ahnung von Bascom. Aber was die Taktquelle angeht is es immer die, die du dem ATmega mit den Fuses angibst.
Stellst du die Fuses auf internen 8Mhz. läuft der Timer auch mit diesen. Stellst du auf extern läuft der Timer auch mit dem externen Quarz.
Zusätzlich kannst du noch einen Prescaler (Vorteiler) vorgeben. Beispielsweise 1024 dann wird der Timer mit Takt/1024 laufen.
Hoffe das meinstest du!?
Edit:
Code:
$crystal = 32768000
scheint mir recht hoch für nen mega8 oder täusch ich mich?
-
Hallo,
danke für die schnelle Antwort! Das schafft schon einmal ein wenig mehr Klarheit.
Takt habe ich via Fuses auf 8 MHz und einen Prescaler von 256.
Die $crystal Angabe wurde mir von einem Freund so empfohlen, er meinte vielleicht hilft es. Habe jetzt aber noch einmal nachgelesen, da sollte der Takt des Atmega drinstehen. Habe dies eben korrigiert. Danke für den Hinweis!
Versuche es eben noch einmal mit der richtigen $crystal-Angabe und dem korrekt errechnetem Vorladewert. Mal sehen was diesmal dabei herauskommt.
DANKE!
Mfg
Phips
edit: Leider läuft das Programm schon nach einer Minute und zehn Sekunden mit einer Sekunde Vorsprung. Schade!
-
Der interne Oszillator ist sehr ungenau und für eine Uhr ungeeignet.
Du könntest dich zwar mit dem Vorladewert hin tasten, solltest du aber einmal den Kontroller tauschen, fängt das wieder von vorne an.
Am besten einen Quarz nehmen, und zwar einen krummen wie z.B. 7,3728MHz, dieser Wert lässt sich besser teilen.
-
Hallo,
eigentlich wollte ich mit Hilfe des Timers einen Tachometer realisieren und benötige ihn somit zum Stoppen einer extrem kurzen Zeitspanne.
Sind durch diese Ungenauigkeiten auch die Schwankungen zu erklären? Einmal schneller, einmal langsamer?
Da ich in meinem Projekt auch eine Uhr geplant habe, habe ich so und so einen 32,768 MHz Quarz als Uhrenquarz. Kann ich diesen auch gleichzeitig für den Timer verwenden?
DANKE!
Mfg
Phips
-
Das gemeine beim internen Oszillator ist noch, dass dessen Frequenz von der Betriebsspannung und der Temperatur abhängt. D.h. auch wenn du den jetzt so gut einstellst, dass es passt: Lass es mal kälter/wärmer werden und schon stimmts nicht mehr.
Ich hab an einem Projekt nen 16MHz Quarz hängen; da läuft die Uhrzeit seit 3 Monaten ohne merkliche Abweichungen.
32,768MHz sind für nen ATMega zu viel. Sollten das eher kHz sein?
-
Hallo Jaecko,
danke für deine Antwort. Du hast mein Rätsel gelöst! Die Temperaturabhängigkeit dürfte wohl das große Problem sein!
Auch mit dem Quarz hast du recht, da habe ich wohl den falschen SI Prefix erwischt...es sind 32,768 kHz. So das es eben mit einem Prescaler von 256 genau 128 überläufe pro Sekunde ergibt.
Problem ist eben nur, dass ich den Quarz für die "Soft Clock" benötige und den Takt aber auch für meine Berechnung benötigen würde.
Ich habe gestern Abend noch versucht die Fuses über das myAVR-Progtool zu setzen, aber ohne Erfolg. Setze ich sie auf "ext. Low-Freq. Crystal; Start-Up time: 32K CK + 64 ms; [CKSEL=1001 SUT=10]", so wie es laut der Anleitung mit einem Uhrenquarz richtig ist, macht mein Atmega keinen Strich mehr. (CKOPT wurde natürlich auch aktiviert) Setze ich ihn wieder zurück auf die letzten Einstellungen, funktioniert wieder alles!
DANKE!
Mfg
Phips
-
hmmm,
welche Hardware nutzt du?
Habe in Gedanken mal ein myAVR-Board unterstellt , da du das myAVR-Progtool nutzt.
Wenn dem so ist, wundert mich, dass du die Fuses wieder auf interne Frequenz setzen konntest.
Denn, wenn du auf externe Frequenz umgestellt hast und er keinen Strich mehr macht würde ich vermuten, macht er nichts, weil er keine Taktquelle mehr hat.
Ohne Taktquelle würdest du aber die Fuses nicht zurückgesetzt bekommen.
"Ein Teufelskreis"
Gruß
BoGe-Ro
-
Der freilaufende Takt des AVR ist ziemlich ungenau, warscheinlich bis
2prozent Abweichung. Meine Erfahrung beim Bau einer Messkette,
wobei binnen einer Minute mehrere Messwerte übertragen werden, lag bei
fast 2 Sekunden am Ende der Minute. War für meine Zwecke jedoch nicht
so wichtig. Anderes Beispiel: Das Auslesen über die UART funktionierte
mit 9600 nur noch in Ausnahmefällen, mit 4800 so zu fifty/fifty und erst
mit 2400 halbwegs stabil. Für zeitrelevante Dinge also immer einen Quarz mit den ggffll. 2 Cs, also nur ein paar Cent mehr Aufwand. VG Micha
-
Für timingkritische Programme geht nix ohne Quarz, am Einfachsten nen
Baudratenquarz.
Für ganz genau dann evtl. nen temperaturstabilisierten Quarzoszillator.