Forum: Compiler & IDEs ATmega8 16Bit Timer/Counter; brauche Hilfe zu den Registern!


von Steffen (Gast)


Lesenswert?

Hallo,
bin gerade dabei ein Programm für den 16Bit Timer/Counter zu schreiben.

Dabei sollen externe Pulse gezählt und bei erreichen eines vorgegebenen
Wertes, eine Routine abgearbeitet werden.

Ich brauch nur Hilfe bei den Registern, ich verliere die Übersicht.

TCCR1A: Da brauch ich nichts einstellen??
TCCR1B: (1<<CS12) | (1<<CS11) --> Externe "Clock Source" an Pin T1
(fallende Flanke)
Wo liegt der Unterschied zwischen ICP1 (Input Capture Pin 1) und Pin
T1?

OCR1AH, OCR1AL: Muss ich in das Register den Vergleichswert schreiben?

TIMSK: (1<<OCIE1A) --> Output Compare A Match Interrupt Enable

Stimmt das so oder hab ich mich bei den Registern vertan?

von Jörg Wunsch (Gast)


Lesenswert?

> Dabei sollen externe Pulse gezählt und bei erreichen eines
> vorgegebenen Wertes, eine Routine abgearbeitet werden.

Das heißt, du willst einen `compare match' programmieren und dann
wahrscheinlich am besten einen Interrupt auslösen, wenn der
entsprechende Zählerstand erreicht ist (alternativ: im Hauptprogramm
auf das entsprechende Interrupt-Flag pollen).

> Wo liegt der Unterschied zwischen ICP1 (Input Capture Pin 1) und Pin
> T1?

T1 ist der externe Takteingang (den du für dein Projekt brauchst).

Input capture brauchst do wohl in deiner Konstellation nicht: bei
einer definierbaren Flanke am ICP1 wird der aktuelle Zählerstand TCNT1
in einem Register (ICR1) zwischengespeichert und bedarfsweise noch ein
Interrupt ausgelöst.  Damit kann man Zeitabstände messen, ohne dass
die Interruptreaktionszeit selbst in die Messung eingeht.

> OCR1AH, OCR1AL: Muss ich in das Register den Vergleichswert
> schreiben?

Ja.

> TIMSK: (1<<OCIE1A) --> Output Compare A Match Interrupt Enable

Je nachdem, ob du mit Interrupt oder Polling arbeiten willst.  Wenn du
pollen willst, dann OCF1A im TIFR durch Schreiben einer 1 löschen:

TIFR = (1 << OCF1A);

(Ja, genau so.  Nicht mit |= oder sowas.  Warum, steht in der avr-libc
FAQ.)

Danach dein OCR1A programmieren und so lange warten, bis das Bit
wieder 1 wird.

von Thorsten (Gast)


Lesenswert?

TIFR = (1 << OCF1A);

(Ja, genau so.  Nicht mit |= oder sowas.  Warum, steht in der avr-libc
FAQ.)


Würde zwar den in den FAQ 24 genannten SBI-Befehl statt dem OUT-Befehl
erzeugen und somit länger dauern (ist das der grund?), aber gehen würde
es doch auch, oder? "There is no need to perform a read-modify-write
cycle ..."

von Werner B. (Gast)


Lesenswert?

@Thorsten

> länger dauern
nein, aber andere gesetzte interrupt flags würden durch schreibern
einer "1" (sie sind ja gesetzt, also "1") unabsichtlich gelöscht.

von Thorsten (Gast)


Lesenswert?

Oh Mann, na klar. Das ist ja gerade der Witz mit dem "verODERn". 1
ODER 0 = 1. Und schon wird´s gelöscht.  Ein bischen Laufzeitperformance
wäre auch sicherlich keinen Eintrag in den FAQ´s wert gewesen. Wieder
viel gelernt heute. Danke!

von Tobi78 (Gast)


Lesenswert?

Wie sieht denn der Befehl aus, mit dem ich auf das Interrupt-Ereignis
pollen kann? Das Auslösen einer Interrupt Routine ist kein Problem,
aber das mit dem Pollen würde mich interessieren.
Danke.

von Thomas L. (tom)


Lesenswert?

ähmm ... nur mal blöd gefragt ...

warum willst du das irq event pollen? der vorteil eines IRQs ist ja
gerade dass man nicht pollen muss, sondern praktisch mit der nase
darauf gestossen wird.

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.