Hallo Zusammen,
ich brauche für ein neues Projekt eine Uhr auf meinem Mega32.
Timer 1 ist leider schon belegt, bzw. wird später für ne andere Funktion gebraucht, wozu ich einen 16 Bit Timer brauche.
Daher kommt eigentlich nur Timer 2 in Frage. Der Mega32 ist auf der RN-Control und hat nen 16000000Hz Quarz.
Nun habe ich mir überlegt, ich teile 16000000 erstmal durch 256 (Prescale). Dann komme ich auf 62500.
Ich lasse meinen 8 Bit Timer von 5 an zählen, so komme ich auf 250 Schritte, also 62500/250= 250.
Jetzt erstelle ich eine Variable die ich in der ISR von Timer 2 um 1 erhöhe.
Zusätzlich wird hier der Timer wieder auf 5 gestellt.
In meiner normalen Do Loop schleife lasse ich jetzt sobald die Variable auf 250 ist sie zurück auf 0 setzen und erhöhe meine Sekunden um 1.
Dann noch über ein paar If Than befehle bei 60s zurück auf 0 und die Minuten +1.
Das läuft alles soweit gut, nur bekomme ich extreme Abweichungen. Der Mega32 hängt pro Minute mehrere Sekunden hinter der Zeit. Woran kann das liegen?
Ich programmiere auf nem alten 95 Rechner ohne Internet, daher ist es schwer den Code hier rein zubekommen, werde ihn aber versuchen morgen auf cd zu brennen und dann hier reinzustellen
Ich hoffe ihr versteht mein Probelem und könnt mir helfen
Viele Grüße
Dominik
MfG (Mit feinem Grübeln) Wir unterstützen dich bei deinen Projekten, aber wir entwickeln sie nicht für dich. (radbruch) "Irgendwas" geht "irgendwie" immer...(Rabenauge) Machs - und berichte.(oberallgeier) Man weißt wie, aber nie warum. Gut zu wissen, was man nicht weiß. Zuerst messen, danach fragen. Was heute geht, wurde gestern gebastelt. http://www.youtube.com/watch?v=qOAnVO3y2u8 Danke!
Mein Vorschlag:
- Prescaler von 1024 verwenden, daraus ergibt sich eine Frequenz von f_Timer = 15625 Hz
- CTC Mode benutzen, Timer Compare Match bei OCR2 = 125-1
- TIMER2_COMP Interrupt aktivieren, die ISR wird nun 125mal die Sekunde aufgerufen
- in der ISR eine Variable inkrementieren, und bei 125 zurücksetzen und eine Minute ist um
Hallo,
An der ISR kann es natürlich liegen, das wird es auch wahrscheinlich sein.
leider verstehe ich die Idee vom Hardware-Entwickler nicht so ganz.prescaler auf 1024 ok, aber weiter???
Was bedeutet ctc bei orc2 = 125-1?
Und was genau meinst du mit timer2_comp interrupt?
Hättest du oder vielleicht wer anders ein paar Zeilen Code die das zeigen?
Im ctc Modus errechne ich ja den Vergleichswert wie folgt:
Quarz-Frequenz/prescaler/2/gewünschte-frequenz
Bei mir also 16000000/1024/2/1 = 7812,5 also zu groß für nen 8 Bit timer
was meinst du mit 125-1?
Viele grüße
Dominik
Geändert von Dominik009 (20.12.2013 um 01:10 Uhr)
Hallo Dominik,
deine Lösung und die von Hardware-Entwickler liegen von der Berechnung her nicht weit auseinander.
Bei dir: Prescale 256, Timer läuft nach 250 Ticks über, Zähler läuft bis 250 == 256 * 250 * 250 = 16M
Bei ihm: Prescale 1024, Timer matched nach 125 Ticks, Zähler läuft bis 125 == 1024 * 125 * 125 =16M
Seine ISR wird nur halb so oft pro Sekunde aufgerufen, verbraucht also weniger Prozessorzeit.
Wichtiger ist der Unterschied mit CTC Mode und Timer vorladen. Bei deiner Art bist du in Teilen von der Ausführungszeit der ISR abhängig. Speziell bei kleinen Prescale Werten ergeben sich dadurch signifikante Abweichungen.
Anders der CTC Mode. Der Timer läuft praktisch komplett in HW, inklusive Zurücksetzen. In der ISR änderst du nichts am Timer.
Leider wird deine Art in allen Tutorials, Foren und auch in der Bascomhilfe immer als erstes gezeigt und scheint auch besser verständlich zu sein. Aber ich würde dir raten, grundsätzlich darauf zu verzichten.
Der CTC Modus funktioniert in Bascom so:
Config Timer2 = Timer, Prescale = 1024, Clear_Timer=1, Compare = Toggle
Compare2 = 124 '125 Ticks, weil der Timer bei 0 anfängt (deshalb 125 - 1), du kannst auch OCR2 = 124 schreiben
On Compare2 Timer_Isr
Enable Compare2
Allerdings glaube ich nicht, dass dadurch mehrere Sekunden pro Minute zu erklären sind.
Zeig doch mal dein ganzes Programm.
Ich denke das Problem sind hier die Begrifflichkeiten.Was bedeutet ctc bei orc2 = 125-1?
Und was genau meinst du mit timer2_comp interrupt?
CTC bedeutet Clear Timer at Comparematch und heisst, wenn das entsprechende TCNT Register den Wert des Comparematchregisters erreicht wird es in der Hardware sofort wieder auf 0 gesetzt. Beispiel Comp 2 Register hat den Wert 127, TCNT2 erreicht 127 und wird sofort auf 0 gesetzt.
zu 2. So ein Timer kann nicht nur bei einem Überlauf einen Interrupt produzieren, sondern auch wenn das TCNT Register den Wert eines Comparematchregisters erreicht. Dadurch hat man bei der Wahl der Prescaler mehr Möglichkeiten den gewünschten Teilerfaktor zu erreichen.
Grundsätzlich bevorzuge ich große Prescaler, weil sich damit normalerweise eher seltener Interruptaufrufe ergeben.
Wenn dein 16 Bit Timer frei läuft kannst Du sogar dort noch deine Uhr mit einbauen.
Du gibst dort den Comparematch Interrupt frei und zählst zum Comparematchregister innerhalb dieses Interrupts den Wert für den nächsten Zeitabschnitt dazu.
Dadurch kommt es immer wieder zu festen Zyklen zu einem Comparematch Interrupt.
Zusätzlich würde ich Dir empfehlen eine zusätzliche Vergleichs- " Uhr " wie eine Real Time Clock ( RTC ) oder DCF 77 als Vergleich zu benutzen, weil sonst Deine Uhr nach längerer Zeit falsch gehen wird. Die Zeitbasis ist ja vom Controllerquarz abhängig, der auch nich zu 100% genau ist.
Hallo,
erstml danke für die zahlreichen Antworten.
bessere Grade den Code aus, doch leider nimmt er die Zeile:
On Compare2 ISR_von_timer2 nicht an (error 117)
Kann ich anstelle von compare2 auch timer2 schreiben?
Gruß
Dominik
Geändert von Dominik009 (20.12.2013 um 12:39 Uhr)
Jo, ich hab nen mega32 und Bascom 1.11.9.0
Lesezeichen