Hallo, HW: ATmega 644 SW: AVRStudio mit GCC Plugin. Problem: volatile uint16_t waitcnt; ISR(TIMER0_OVF_vect) { TCNT0 = TCNT0-18; // Startwert für Timer0 laden if (waitcnt>0) waitcnt--; } Ist das ok oder gibt es dafür in C eine Besonderheit die man beachten muß? MfG Tobi...
Am besten benuntzt du den CTC-Modus, sofern der Timer den unterstützt. Dann brauchst du das gar nicht.
??? CTC Modus? Ähm was ist das? Ich denke schon das er das kann. Kann man da auch 2 verschiedene Zeiten festlegen? Ich brauche 2 unterschiedliche Zeiten die ich mit einen Flag umschalten kann. Gruß Tobi...
Bei CTC legst du den den TOP Wert (also wann das Rollover erfolgen soll) fest, und damit entfällt das lästige Nachladen, er macht's von alleine. Mit nem PWM Mode kannste während des Hochzählens 2 INTs auslösen, und bei Bedarf dann eben was drin ausführen (Stichwort Output Compare Match A &B)
> ??? CTC Modus? Ja. Ist im Datenblatt gut erklärt. > Ähm was ist das? Du stellst im CTC-Modus den Wert ein, bis zu dem er zählen soll. > Ich brauche 2 unterschiedliche Zeiten die ich mit einen Flag umschalten > kann. Du kannst den Wert jederzeit über ein I/O-Register verstellen.
Ich habe mich im Datenblatt mal umgesehen. Ok der ATmega644 macht das mit dem CTC Modus. Kann ich davon ausgehen das mein Weg auch korrekt ist oder ist der CTC Modus extra dafür entwickelt worden? Gruß Tobi...
Die AVR-Timer haben keine Möglichkeit zum Auto-Reload, den einige andere µCs implementiert haben. Der CTC-Modus ist deshalb als Ersatz dafür anzusehen. Geht aber eben nur mit Timern, die eine Compare-Einheit besitzen. Das Nachladen von Hand ist erstens nicht verzögerungsfrei und zweitens ungenau (in einer Hochsprache). In Assembler kann man zwar sehr genau die Zeit vom Setzen des Interrupt-Flags bis zum Timer-Reload bestimmen, aber in einer Hochsprache geht das nicht ohne Weiteres.
> In Assembler kann man zwar sehr > genau die Zeit vom Setzen des Interrupt-Flags bis zum Timer-Reload > bestimmen, aber in einer Hochsprache geht das nicht ohne Weiteres. Bitte nicht alles verallgemeinern. Wenn die Interrupts disabled sind während der Timer abläuft (z.B. ein anderer Interrupt wird grade verarbeitet) verzögert sich die ISR um diese Zeit. Da hier aber innerhalb der ISR explizit vom aktuellen Zählerwert ausgegangen wird hat das im Normalfall (Interrupts nicht zu lange gesperrt) keinen Einfluss. In "C" ist ist es relativ einfach aus dem erzeugten Assembler-Listing die Anzahl der Taktzyklen vom Eintritt in die bis zum erneuten setzen des Timer Registers zu ermitteln und man kann das berücksichtigen (muss man in reinem Assembler ja auch). Bei entsprechend großen Vorteiler kann man das sogar komplett ignorieren Aber nach der Beschreibung der Aufgabenstellung handelt es sich um PWM. Also warum nicht einen der PWM-Modes verwenden? Werner P.S. Tippfehler gehen in das Eigentum des Finders über - er darf sie behalten.
@Werner: Richtig, das hatte ich vergessen zu erwähnen: Eine genaue Angabe über die Verzögerung lässt sich nur dann machen, wenn kein anderer Interrupt dazwischenfunken kann. Aber um mit einem vom Compiler erzeugten Assembler-Listing klarzukommen, muss man sich auch erst mal mit Assembler befasst haben. Sonst kann man damit gar nichts anfangen. Und falls es sich wirklich um eine PWM-ähnliche Anwendung handelt, sollte man auch tatsächlich einen der PWM-Modi benutzen. Dafür sind die schließlich da.
> In Assembler kann man zwar sehr genau die Zeit vom Setzen des > Interrupt-Flags bis zum Timer-Reload bestimmen Ein paar Taktzyklen Variation sind da auch drin, denn beim Auftreten eines Interrupts wird der aktuelle Befehl noch fertig ausgeführt. Wenn man den Sleepmodus verwendet, kommt auch da noch eine zusätzliche Latenz dazu.
@Rolf: Richtig, das ist bei Interrupt-Verarbeitung aber generell einzukalkulieren. Im Falle der Ausgabe des Signals per Hardware über einen OCnx-Pin braucht man bei Verwendung von CTC oder PWM überhaupt keinen Interrupt-Handler mehr. Der Interrupt muss noch nicht mal freigegeben sein.
Es geht bei mir darum das ich den Zustand eines Pins ziemlich genau zu 2 verschiedenen Zeiten benötige. Entweder zur Zeit A oder B... die Umschaltung findet im Hauptprogramm statt. Ich sammel dies Information und regiere in meinen Hauptprogramm dann darauf. Ich habe 3 Jahre AVR asm Erfahrung, auch etwas komplexere Sachen. Also das Listing würde ich schon verstehen, nur war mir nicht klar ob man den Timer nun so wie ich es mache in C korrkt nachlädt. Diese CTC Sache ist für mich neu, ich werde damit mal eine LED' blinken lassen um zu verstehen wie das läuft. Danke Euch, Gruß Tobi...
Achja, Nachtrag... es sind einige Int's aktiv, Timer0, Timer2 und der UART... Gruß Tobi...
> Richtig, das ist bei Interrupt-Verarbeitung aber generell > einzukalkulieren. Kommt drauf an. Wenn ich eine Uhr basteln will, ist es mir wurscht, ob die Sekunden fünf Mikrosekunden früher oder später angezeigt werden. Für die Ganggenauigkeit muß die Zahl an Taktzyklen zwischen zwei Zähler-Resets aber stimmen.
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.