mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AVR: 16-bit-Counter Verwendung so ok?


Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ich möchte ein Interrupt in bestimmten Intervallen haben (z.B. alle 
60ms), dazu berechne ich mir (zur Laufzeit) welchen Prescaler ich 
brauche, und wie weit der 16-bit Counter laufen soll (mega16).
Den Wert wie weit der Counter laufen sol, lade ich in ein 
Compare-Register.
Soweit klappt das auch, nur kann ich beim mega16 wohl nicht sagen, er 
soll bei einem CompareMatch den Counter wieder auf 0 setzen, wohl weil 
es zwei Compare-Register gibt.

Da hab ich mir folgendes ausgedacht (C-Code, geht aber ums Prinzip):
uint16_t intervall = xxx; // interrupt immer wenn der counter xxx mal gezählt hat

void timer_init(/*...*/) {
    /* der ganze andere initalisierungskrempel */
    // set compare value
    OCR1A = 0;
}

ISR(TIMER1_COMPA_vect) {
    // wirte new comparevalue
    OCR1A += intervall;
}

Anstatt den Counter jedes mal auf 0 zu setzen, schreibe ich als einen 
neuen Compare-Wert.

Geht das so?

Gruß
Thomas

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thomas wrote:
> Soweit klappt das auch, nur kann ich beim mega16 wohl nicht sagen, er
> soll bei einem CompareMatch den Counter wieder auf 0 setzen, wohl weil
> es zwei Compare-Register gibt.

Doch, das geht, und zwar mit OCR1A im CTC Modus.

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
geht so, aber es gibt den CTC-Mode, da brauchst du gar nichts nachladen. 
Beim Compare-Ereignis wird der Zähler per Hardware wieder auf 0 gesetzt. 
Empfiehlt sich eigentlich immer für solche Aufgaben, kleinere 
Interruptlaufzeit, keine Jitter, wenn der MC gerade mal in einer anderen 
ISR beschäftigt ist.

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für den Tip, dachte zunächst das geht nicht, weil es kein eigenes 
Bit gibt, wo man das setzen kann, aber hab nun mal gesucht.

Kannst du mir bitte noch sagen ob das hier dann stimmt so:
TCCR1A = (1<<WGM12);

Er setzt dann den Counter wieder auf 0, wenn es ein Compare Match mit 
OCR1A oder OCR1B gibt - richtig? Muss ich dann OCR1B auf einen 
größeren Wert als OCR1A setzen? Könnte ich ja einfach auf 0xffff 
stellen.

Danke schonmal

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thomas wrote:
> Er setzt dann den Counter wieder auf 0, wenn es ein Compare Match mit
> OCR1A oder OCR1B gibt - richtig?

falsch.

< Muss ich dann OCR1B auf einen
> größeren Wert als OCR1A setzen? Könnte ich ja einfach auf 0xffff
> stellen.

Bitte schau noch mal ins Datenblatt.
Dort gibt es eine Tabelle über die einzelnen Modi des Timers1.
In dieser Tabelle steht auch, welches Register (wenn überhaupt)
den Max-Wert des Timers liefert.

Autor: AVRFan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Kannst du mir bitte noch sagen ob das hier dann stimmt so:
>TCCR1A = (1<<WGM12);

Ja, das ist der CTC Mode mit OCR1A als Match-Register.

>Er setzt dann den Counter wieder auf 0, wenn es ein Compare Match mit
>OCR1A oder OCR1B gibt - richtig?

Nein, nur OCR1A.  OCR1B hat im CTC Mode keine Bedeutung.

>Muss ich dann OCR1B auf einen größeren Wert als OCR1A setzen? Könnte ich ja 
>einfach auf 0xffff stellen.

Der Wert von OCR1B ist völlig egal, weil dieses Register im CTC Mode 
nicht ausgewertet wird.

All diese Informationen findest Du übrigens auch im Datenblatt.

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok Entschuldigung, dachte da gibts gar nicht viel Möglichkeiten und habe 
wirklich nicht nachgeschaut.

PS: Grund der anfänglichen Verwirrung war, dass in dem GCC-Tutorial mit 
CTC1 gearbeitet wird, und das nun wohl WGM13,WGM12,WGM11,WGM10 geht.

Gruß & Danke
Thomas

Autor: AVRFan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>dass in dem GCC-Tutorial mit
>CTC1 gearbeitet wird, und das nun wohl WGM13,WGM12,WGM11,WGM10 geht.

Ah, verstehe.  Ja, die Bit-Namen CTC1 sowie PWM11 und PWM10 sind 
veraltet, aber aus Kompatibilitätsgründen weiterhin definiert.  Für neue 
Anwendungen sollte man nur mit WGM13, WGM12, WGM11, WGM10 arbeiten.

Autor: ren (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Um einen repetitiven timer interrupt zu bekommen kann man's einfacher 
haben. Nur den Timer mit Overflow-Zahl laden und den Overflow interrupt 
enablen, den Rest braucht man dazu nicht. siehe auch
http://www.ibrtses.com/embedded/avrasmuartint.html

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ren wrote:
> Um einen repetitiven timer interrupt zu bekommen kann man's einfacher
> haben.

Was ist an einem Timer Preload einfacher?
Ausser der ständigen Schererei, dass du nicht weist wieviele
Takte vom Auslösen des Interrupts bis zum Aufruf der ISR
vergangen sind; dass du ständig alle Takte vom Beginn der
ISR bis zum eigentlichen Reload zählen musst und im Reload
Wert berücksichtigen musst.

Alles Dinge, die im CTC Modus keinen Menschen interessieren
und auch nicht zu interessieren brauchen, weil die Hardware
das Rücksetzen des Timers ganz von alleine macht. Und zwar
auf den Takt genau!

Das einzige was anders ist: Es wird ein anderer Interrupt
aufgerufen, die Initialisierungssequenz ist ein klein
wenig anders und man muss nicht grossartig rumrechnen
um den Preload Wert zu kriegen. Ich will alle 200 Takte
einen Interrupt, also schreib ich diesen Wert (OK: 199)
in das OCR Register. Fertig!

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl-Heinz, nicht aufregen. Es gibt immer welche, die das Rad neu 
erfinden :-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.