Forum: Compiler & IDEs Timer0 und Timer2 richtig "nachladen"?


von tobiTob (Gast)


Lesenswert?

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...

von Rolf Magnus (Gast)


Lesenswert?

Am besten benuntzt du den CTC-Modus, sofern der Timer den unterstützt. 
Dann brauchst du das gar nicht.

von tobiTob (Gast)


Lesenswert?

??? 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...

von Gast (Gast)


Lesenswert?

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)

von Rolf Magnus (Gast)


Lesenswert?

> ??? 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.

von tobiTob (Gast)


Lesenswert?

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...

von Johannes M. (johnny-m)


Lesenswert?

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.

von Werner B. (Gast)


Lesenswert?

> 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.

von Johannes M. (johnny-m)


Lesenswert?

@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.

von Rolf Magnus (Gast)


Lesenswert?

> 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.

von Johannes M. (johnny-m)


Lesenswert?

@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.

von tobiTob (Gast)


Lesenswert?

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...

von tobiTob (Gast)


Lesenswert?

Achja, Nachtrag... es sind einige Int's aktiv, Timer0, Timer2 und der 
UART...

Gruß Tobi...

von Rolf Magnus (Gast)


Lesenswert?

> 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
Noch kein Account? Hier anmelden.