Hallo Zusammen. Ach Mensch, wieder ein Beitrag über Intrerrupts :) Ich hoffe jemand könnte sich trotzdem kurz die Zeit nehmen, mir zu helfen, stehe nämlich gerade recht auf dem Schlauch! Also folgendes: Ich habe einen 5.24288MHz Quarz. Ich löse damit alle 100ms einen Interrupt aus und zwar benutze ich den 16-Bit Timer und einen Prescaler von 8. Das klappt bis jetzt auch alles wunderbar. Da ich ein bisschen spät dran bin mit der Entprellung (habe das ganze bis jetzt vor mich hingeschoben) möchte ich gerne die Entprellung auch in einer Interrupt Routine lösen. Den Code dazu habe ich auch schon (einfache State-Machine), allerdings ist 100ms Entprellzeit einfach zu lang. Deshalb hätte ich eigentlich gerne einen Interrupt alle 10ms. Einen Quarz habe ich nicht gefunden, bei dem der die ganze Geschichte schön aufgeht, darum möchte ich fragen: Wie und wo kann ich angeben, wann der Interrupt stattfinden soll? Ich habe bis jetzt einfach immer mit dem Overflow gearbeitet aber eigentlich will ich ja, dass der Interrupt schon früher auslöst. Wie würdet ihr das lösen? Gruss Humphrey
Hi
>Wie würdet ihr das lösen?
Timer im CTC-Mode initialisieren.
MfG Spess
spess53 schrieb: > Timer im CTC-Mode initialisieren. Hm.. habe das noch nie gemächt, wäre sehr froh um ein wenig Hilfestellung! Ich habe mir das mal im Datenblatt der ATMEGA16 rausgesucht, Seite 112 Table 47. Ich habe es jetzt nicht ganz durchschaut, in welches Register diese Bits kommen? Oder haben die etwa ein eigenes Register? Gruss Gordon
Ah, der Beitrag ist aber gut verständlich geschrieben. Vielen Dank! Ich denke es wird das einfachste sein, wenn ich einen 8Mhz Quarz nehme, Prescaler von 8 und den Timer1 bis 9999 (10'000 - 1) zählen lasse? Jetzt muss ich das nur noch irgendwie mit der Initialisierung hinkriegen :P Melde mich dann nochmal, wenn ich mich da etwas schläuer gemacht habe. Gruss Humphrey
Hi >Hm.. habe das noch nie gemächt, wäre sehr froh um ein wenig >Hilfestellung! Dann wird es langsam Zeit. >Ich habe mir das mal im Datenblatt der ATMEGA16 rausgesucht, Seite 112 >Table 47. Ich habe es jetzt nicht ganz durchschaut, in welches Register >diese Bits kommen? Oder haben die etwa ein eigenes Register? Dann sieh dir die Beschreibung der Register TCCR1A und TCCR1B an. Die Beschreibung von CTC und die Berechnung findest du unter 'Modes of Operation'. Wenn du keine genaue 10ms brauchst geht auch ein 8-Bit-Timer im Overflow. MfG Spess
Humphrey schrieb: > Ah, der Beitrag ist aber gut verständlich geschrieben. Vielen Dank! > Ich denke es wird das einfachste sein, wenn ich einen 8Mhz Quarz nehme, > Prescaler von 8 und den Timer1 bis 9999 (10'000 - 1) zählen lasse? Hä? CTC Modus und ein bischen rechnen? (ums rechnen wirst du auf Dauer nicht herumkommen. Also gewöhn dich besser jetzt schon daran. Das ist täglich Brot, die Timereinstellungen ausrechnen zu können. Wenn du erst mal verstanden hast, was da abgeht, ist das doch trivial. Oder bist du auch einer von den Programmierern, die nur dann arbeiten können, wenn man ihnen ihr Problem ganz konkret mit ihren Zahlen vorkaut?)
spess53 schrieb: > Wenn du keine genaue 10ms brauchst geht auch ein 8-Bit-Timer im > Overflow. Doch, muss schon ziemlich genau sein (Uhr). Karl Heinz Buchegger schrieb: > Hä? > CTC Modus und ein bischen rechnen? Habe ich doch gerade? 8Mhz / 8 = 1Mhz. Im 1Mhz Takt zählt er 100 * auf 10'000 (resp. 9999) -> 100 Interrupts pro Sekunde -> alle 10ms ein Interrupt. Oder sehe ich das falsch? Gruss Humphrey
Humphrey schrieb: > spess53 schrieb: >> Wenn du keine genaue 10ms brauchst geht auch ein 8-Bit-Timer im >> Overflow. > > Doch, muss schon ziemlich genau sein (Uhr). > > Karl Heinz Buchegger schrieb: >> Hä? >> CTC Modus und ein bischen rechnen? > > Habe ich doch gerade? 8Mhz / 8 = 1Mhz. Im 1Mhz Takt zählt er 100 * auf > 10'000 (resp. 9999) -> 100 Interrupts pro Sekunde -> alle 10ms ein > Interrupt. > Und warum willst du da jetzt deinen Quarz wechseln? > Oder sehe ich das falsch? Für eine Uhr siehst du das sowieso falsch. Denn auch dein 8Mhz Quarz macht nicht 8000000 Schwingungen in der Sekunde sondern ein paar 100 mehr oder weniger. D.h. da kommst du sowieso nicht drummherum die genaue(!) Quarzfrequenz festzustellen (und mit einem Vorteiler von 1 zu arbeiten. Jede Schwingung zählt) d.h. dein 8 Mhz Quarz ist genausogut wie dein 5.irgendwas Mhz Quarz AVR - Die genaue Sekunde / RTC
Karl Heinz Buchegger schrieb: > d.h. dein 8 Mhz Quarz ist genausogut wie dein 5.irgendwas Mhz Quarz Das weiss ich, und mit meinem 5.xxx Quarz habe ich pro Tag ca. 2 Sekunden Abweichung, was mir absolut genügt. Für die 2. Version ist sowieso ein RTC vorgesehen -> mir geht es noch nicht um die absolute Genauigkeit. Karl Heinz Buchegger schrieb: > Und warum willst du da jetzt deinen Quarz wechseln Naja, warum nicht? Ich muss ca. 10m laufen um einen 8MHz Quarz zu holen, dann noch ca. 20 Sekunden für's einlöten.. geht einfach schneller. Gruss Humphrey
Humphrey schrieb: > Karl Heinz Buchegger schrieb: >> d.h. dein 8 Mhz Quarz ist genausogut wie dein 5.irgendwas Mhz Quarz > > Das weiss ich, und mit meinem 5.xxx Quarz habe ich pro Tag ca. 2 > Sekunden Abweichung, was mir absolut genügt. Für die 2. Version ist > sowieso ein RTC vorgesehen -> mir geht es noch nicht um die absolute > Genauigkeit. > > Karl Heinz Buchegger schrieb: >> Und warum willst du da jetzt deinen Quarz wechseln > > Naja, warum nicht? Ich muss ca. 10m laufen um einen 8MHz Quarz zu holen, > dann noch ca. 20 Sekunden für's einlöten.. geht einfach schneller. Wetten nicht?
10 ms sind 100 ISR AUfrufe in der Sekunde Prescaler auf 1 5242880 / 100 -> 524288 CTC Modus ein. OCR Register auf 52428 10 ISR Aufruf abzählen. Fertig. Hat keine 20 Sekunden gedauert.
Danach lässt du deine Uhr (wie im Link beschrieben) ein paar Tage laufen, stellst die Abweichung fest und rechnest dir die tatsächliche QUarzfrequenz aus. Die Korrektur machst du bei jedem 10 ISR Aufruf, indem du den durch Manipulation des OCR1A Registers um die enstprechende Anzahl Takte länger machst. Fertig ist die genau gehende Uhr.
Karl Heinz Buchegger schrieb: > OCR Register auf 52428 Öhm, muss ehrlich sagen, dass ich auch die Zahl auch gekommen bin. Dachte aber das liegt ausserhalb des Wertebereichs vom 16-Bit Timer (warum auch immer). Und dann hatte ich bereits keine Lust mehr mir über Prescaler Gedanken zu machen :P Hattest natürlich recht, sorry. Auf alle Fälle läuft das ganze jetzt (sieht soweit gut aus) aber muss ich nicht noch von den 52'428 eins abzählen? Gruss Humphrey
Karl Heinz Buchegger schrieb: > Danach lässt du deine Uhr (wie im Link beschrieben) ein paar Tage > laufen, stellst die Abweichung fest und rechnest dir die tatsächliche > QUarzfrequenz aus. Ja, das mache ich dann noch. Dauertest ist sowieso noch vorgesehen :) Gruss Humphrey
Humphrey schrieb: > Karl Heinz Buchegger schrieb: >> OCR Register auf 52428 > > Öhm, muss ehrlich sagen, dass ich auch die Zahl auch gekommen bin. > Dachte aber das liegt ausserhalb des Wertebereichs vom 16-Bit Timer > (warum auch immer). Und dann hatte ich bereits keine Lust mehr mir über > Prescaler Gedanken zu machen :P > > Hattest natürlich recht, sorry. > > Auf alle Fälle läuft das ganze jetzt (sieht soweit gut aus) aber muss > ich nicht noch von den 52'428 eins abzählen? kannst du machen. Der genaue Wert wäre ja 52427.8, was aber aus naheliegenden Gründen nicht geht :-) Aber es sagt ja keiner, dass alle CTC Zyklen gleich lang sein müssen. Kennt man erst mal die genaue Quarzfrequenz, kann man ja in der ISR EINEN Zyklus einlegen, in dem man mal mit einem etwas größeren/kleinern OCR1A Wert operiert. ISR( ... ) { cnt++; if( cnt == 10 ) { ... OCR1A = ....; // ein Zyklus ein bischen anders um die über // 9 Zklen akkumulierten Fehler auszugleichen } else OCR1A = 52428; } Wie gesagt. Auch dieser QUarz macht keine exakten 5242880 Schwingungen
Karl Heinz Buchegger schrieb: > Aber es sagt ja keiner, dass alle CTC Zyklen gleich lang sein müssen. > Kennt man erst mal die genaue Quarzfrequenz, kann man ja in der ISR > EINEN Zyklus einlegen, in dem man mal mit einem etwas größeren/kleinern > OCR1A Wert operiert. Ja, das wäre natürlich auch noch 'ne Option. Auf alle Fälle vielen Dank für deine Hilfe, hätte nicht gedacht, dass es so schnell geht :D Mache noch einen Dauertest so 2, 3 Wochen und dann stell ich das noch um. Sollte dann genügend genau sein. Wenn ich die Uhr von meinem HTC Handy Anschaue, ist die um weiten ungenauer :P Einen schönen Tag, wünsche ich noch. Gruss Humphrey
Und einfach noch für die Nachwelt, falls das mal irgendwer braucht:
1 | int main () |
2 | |
3 | {
|
4 | TIMSK = (1<<OCIE1A); // den Output Compare Interrupt des Timers freigeben |
5 | sei(); // Globale Interrupts erlauben |
6 | TCCR1B = (1<<WGM12) | (1<<CS10); // Vorteiler 1, CTC Modus |
7 | OCR1A = 52428; //Zählen bis 52428 |
8 | |
9 | while (1) |
10 | |
11 | {
|
12 | |
13 | //Programm hier
|
14 | |
15 | }
|
16 | |
17 | }
|
18 | |
19 | ISR (TIMER1_COMPA_vect) |
20 | {
|
21 | |
22 | //Interrupt Routine hier
|
23 | |
24 | }
|
Gruss Humphrey
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.