Hallo allerseits (jetzt hoffentlich im richtigen Forum?)! Ich experimentiere hier gerade mit dem 16-Bit Timer und einem LED-Lauflicht herum. Leider scheint mein Verständnis von diesem Timer vollkommen falsch zu sein. Zu meiner Schaltung: Am ATMega16 hängt ein 11,0592MHZ Quarz (wie in den meisten Tutorials) und ein LED Lauflicht mit 8 LEDs. In meinem Programm habe ich den Timer nun mit einem Prescaler von 256 versehen (d.h. Bit CS12 gesetzt). Das OutputCompare Register steht zur Zeit auf "OCR1A = 0x0002". Das ganze löst dann ein Interrupt aus, welches wiederum einen Zähler erhöht. Wenn der bei 1000 angekommen ist, schalte ich das Lauflicht um 1 weiter. Was ich also gerne hätte ist, dass das OutputCompareMatch genau jede Millisekunde ausgelöst wird, so dass das Licht jede Sekunde um 1 weitergeht. Allerdings läuft das ganze UNENDLICH langsam. Anstatt jede Sekunde dauert es fast 20 Sekunden, bis die LED weiterspringt. Ich habe auch schon mit allen möglichen Werten für das CompareRegister und den Prescaler rumprobiert, aber es will einfach nicht. Meine Rechnung: Wenn der Quarz 11,0592MHZ hat, und der Prescaler bei 256 liegt, läuft das ganze noch mit 43.200HZ. Da mein Compare Register auf 2 steht, müsste eigentlich 22.000 pro Sekunde "interrupted" werden, richtig (das ergäbe zwar keinen MilliSekundentakt, aber trotzdem was ganz schnelles)? Aber warum ist das ganze dann soooooo langsam? PS: Wie kann man eigentlich feststellen, ob der AVR überhaupt den Quarz nutzt? ABer selbst wenn nicht: müsste es dann nicht trotzdem schnell genug laufen?
>Wie kann man eigentlich feststellen, ob der AVR überhaupt den Quarz >nutzt? Indem man über einen Timer eine LED blinken lässt :-) Das aber am besten mit einem erprobten Beispielcode. Oliver
Falk wrote: > Hallo allerseits (jetzt hoffentlich im richtigen Forum?)! Nicht wirklich. µC & Elektronik wäre angebrachter gewesen... > Ich experimentiere hier gerade mit dem 16-Bit Timer und einem > LED-Lauflicht herum. > Leider scheint mein Verständnis von diesem Timer vollkommen falsch zu > sein. Das lässt sich möglicherweise ändern... > Zu meiner Schaltung: Am ATMega16 hängt ein 11,0592MHZ Quarz (wie in den > meisten Tutorials) und ein LED Lauflicht mit 8 LEDs. > > In meinem Programm habe ich den Timer nun mit einem Prescaler von 256 > versehen (d.h. Bit CS12 gesetzt). > Das OutputCompare Register steht zur Zeit auf "OCR1A = 0x0002". Schön. Und wo ist dieses Programm? > Das ganze löst dann ein Interrupt aus, welches wiederum einen Zähler > erhöht. Wenn der bei 1000 angekommen ist, schalte ich das Lauflicht um 1 > weiter. > Was ich also gerne hätte ist, dass das OutputCompareMatch genau jede > Millisekunde ausgelöst wird, so dass das Licht jede Sekunde um 1 > weitergeht. Wenn Du eh nur nen Sekundentakt brauchst, den kannste mit dem 16-Bit-Timer auch direkt erzeugen. > Allerdings läuft das ganze UNENDLICH langsam. Anstatt jede Sekunde > dauert es fast 20 Sekunden, bis die LED weiterspringt. Ich habe auch > schon mit allen möglichen Werten für das CompareRegister und den > Prescaler rumprobiert, aber es will einfach nicht. > > Meine Rechnung: > Wenn der Quarz 11,0592MHZ hat, und der Prescaler bei 256 liegt, läuft > das ganze noch mit 43.200HZ. > Da mein Compare Register auf 2 steht, müsste eigentlich 22.000 pro > Sekunde "interrupted" werden, richtig (das ergäbe zwar keinen > MilliSekundentakt, aber trotzdem was ganz schnelles)? > Aber warum ist das ganze dann soooooo langsam? Nicht ganz.
(f_COMP ist die Frequenz, mit der das Compare-Ereignis auftritt) Du hast also bei OCRnX = 2 einen Teiler von 3. Um die Frequenz zu halbieren, müsstest Du eine 1 in OCR1A schreiben. EDIT: Zum Verständnis: Wenn ein Compare-Ereignis auftritt (also Übereinstimmung der Werte in TCNTn und OCRnX), dann wird das Compare-Flag (das u.a. zum Auslösen des dazugehörigen Interrupt genutzt werden kann) erst mit dem folgenden Timer-Takt gesetzt. Das führt zu dem "OCRnX + 1" in der Berechnung. Wäre das nicht der Fall, dann könnte man sich vorstellen, dass eine Null im Compare-Register den µC vor gewisse Probleme stellen würde... > PS: > Wie kann man eigentlich feststellen, ob der AVR überhaupt den Quarz > nutzt? > ABer selbst wenn nicht: müsste es dann nicht trotzdem schnell genug > laufen? Indem man entweder kontrolliert, ob man die Fusebits korrekt gesetzt hat oder indem man mit einem Oszilloskop überprüft, ob der Oszillator mit dem externen Quarz oder wasauchimmer läuft oder indem man einen sichtbaren Vorgang mit bekannter Periode programmiert (LED blinken). Ich tippe mal, dass der µC mit internem RC-Oszillator, 1 MHz läuft (Werkseinstellung!). Das macht zusammen mit Deinem Rechenfehler in OCR1A ungefähr einen Faktor von 17, was mit den ca. 20 s anstatt einer Sekunde übereinstimmen würde. Ansonsten ist es meist sehr hilfreich, den Programmcode anzuhängen. Sonst kann man an vielen Stellen nur raten, was Du da wirklich gemacht hast.
Wenn du schon im GCC-Forum postest, wie wäre es mit etwas Code? ;) und ich hab (deshalb) ein paar fragen: - in welchem Modus läuft der Timer -- normal-mode?, dann muss der Timer erstmal durchlaufen, bevor es wieder einen Intrrupt gibt, das ist ein 16-Bit timer, es kann also etwas dauern -- du willst wahrscheinlich CTC, d.h. der Timer soll jedes mal, wenn ein OC-interrupt eintritt, wieder von vorne anfangen. - Um den Quarz zu nutzen musst du auf "Crystal Oscillator" fuse'n, NICHT "external clock" oder "external RC-Oscillator", ich weiß aber nicht womit du programmierst (für den AVRDude 'geistern ' hier im Forum zwei Java-GUIs herum) Probier bei dem Timer mal: Prescaler 1, Mode 4 (CTC mit OCR1A als TOP-wert), setz OCR1A auf 11060 und nimm den Outputcompare interrupt 1A (wieso 11060: 0.001s *11059200Hz [Hz == 1/s] ) hth. Jörg
...Ach ja, was Jörg schon andeutete, ist natürlich auch korrekt: Der Timer muss, damit das funktioniert, natürlich im CTC-Modus laufen...
Ooh, da war ich ja recht langsam beim Tippen... Hoffentlich funktionieren heute die Glaskugeln ;) scnr --Jörg
OK, hier der Code. Und ein Bild der Fuses aus PonyProg (an die ich micht mehr rantraue, seitdem ich einen AVR gehimmelt hab) ;-) http://img260.imageshack.us/my.php?image=fusesth3.jpg
Uah, fehler beim Erstellen der .c Datei. Die am besten mit Wordpad öffnen, oder diese hier benutzen. Sorry!
Hast du einen Quarz oder einen Quarzoszillator? So wie die Fuses da stehen, wird ein Quarz nicht benutzt -> Der Mega32 läuft mit 1 Mhz Bei einem Quarz sind bei CKSEL0 bis CKSEL3 in PonyProg keine Häkchen gesetzt.
"Hast du einen Quarz oder einen Quarzoszillator?" Hä? Ich dachte Quarz wäre Quarz... was ich habe ist ein recht kleines Gehäuse mit 2 Füßchen. Oben steht 11,0592MHZ drauf.
Falk wrote: > "Hast du einen Quarz oder einen Quarzoszillator?" > Hä? Ich dachte Quarz wäre Quarz... was ich habe ist ein recht kleines > Gehäuse mit 2 Füßchen. Oben steht 11,0592MHZ drauf. OK. Das ist ein Quarz. Na dann: Deine Fuses stehen nicht richtig für einen Quarz. Dein Mega32 läuft mit 1 Mhz.
Aha! :-) Muss ich dann also alle Häkchen bei CKSEL in PonyProg aus machen?
In PonyProg sind bei einem Quarz bei den Einstellungen CKSEL0, CKSEL1, CKSEL2, CKSEL3 keine Häkchen gesetzt. Dies entspricht in ATMEL Notation einer Einstellung 1111 und die ist laut Datenblatt für Quarze (External Crystal) vorgesehen.
Bei CKOPT könntest du auch noch ein Häkchen machen. CKOPT - Häkchen -> CKOPT = 0 Das wiederrum bedeutet, dass der interne Verstärker auf volle Leistung gestellt wird, sozusagen.
Und ganz wichtig! Bevor du die Fuses umstellst: Im Dialog die Fuses vorher einlesen lassen!
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.