Atemga8 Timer1 im CTC Modus - Frequenz?

Gast #2576537
Lesenswert?

Hallo,

ich habe einen Atmega8 und versuche gerade zu verstehen, wie der Timer1 
im CTC Modus arbeitet.
Habe also Folgendes eingestellt:

TCCR1B |= ((0<<CS12)|(1<<CS11)|(0<<CS10));
TCCR1B = (1<<WGM12);
TIMSK = (1<<OCIE1A);
OCR1A = 400;
sei();

Ich habe also den Vorteile auf 8 gestellt, der externe Takt ist ein 
Quartz mit 16,0 MHz.
OCR1A habe ich mal auf 400 gesetzt. In der ISR Routine 
(TIMER1_COMPA_vect)
setze ich einen Portpin kurz auf high dann wieder auf low.
Wenn ich an dem Portpin die Frequenz messe, dann erhalte ich 3,125 kHz 
bzw. 320us.
Nun meine Frage wie kann ich diese Frequenz berechnen?
Also ich möchte wissen, wie anhand des Taktes, des Vorteiles und des 
Vergleichswertes in OCR1A sich die Frequenz am Portpin berechnet.

Danke!
Gast #2576543
Lesenswert?

Mit der Frequenz 16000000 durch 8 durch (400+1) wird deine ISR 
aufgerufen, d.h. mit ca. 4988 Hz bzw. ca. 200 µs.

Deine abweichende Messung könnte daran liegen:
> setze ich einen Portpin kurz auf high dann wieder auf low.

Warum toggelst du nicht einfach den Pin?
Gast #2576711
Lesenswert?

Hallo Krapao und Sauger,

ja danke fällt mir auf, ist aber nur, weil ich den Code hier für den 
Thread angepasst habe.
In meinem Programm sind

TCCR1B |= ((0<<CS12)|(1<<CS11)|(0<<CS10));

und

TCCR1B = (1<<WGM12);

in getrennten Funktionen untergebracht, die Funktion mit

TCCR1B = (1<<WGM12);

wird zuerst aufgerufen, ich denke das ist in Ordnung dann!

>Warum toggelst du nicht einfach den Pin?

Dadurch halbiert sich ja meine gewünschte Frequenz.
Gast #2576737
Lesenswert?

> Dadurch halbiert sich ja meine gewünschte Frequenz.

Das ist richtig, zeigt dir aber, ob der Timer wie gedacht ("versuche 
gerade zu verstehen, wie der Timer1 im CTC Modus") arbeitet.

Bei deiner Methode hängt es von dem "kurz" und der Art der 
Frequenzmessung bzw. dem Messgerät ab, ob du vernünftige werte bekommst.

Für eine Anwendung mit Ausgabe einer Frequenz auf einem Pin würde man eh 
besser ISR-los mit Hardware-PWM arbeiten.
Gast #2576747
Lesenswert?

> ja danke fällt mir auf, ist aber nur, weil ich den Code hier für den
> Thread angepasst habe.

Mach das besser nicht. Im harmlosen Fall bekommst du Fehler gezeigt und 
erklärt, die du in deinem eigetliche Code nicht hast. Und worst-case 
verärgerst du potentielle Helfer.
Gast #2576770
Lesenswert?

Hallo Krapao,

ja hast recht, war ein Copy und Paste Fehler, sorry!

Ich brauche in der ISR einen Puls für einen Schrittmotortreiber. Die 
Treiberplatine braucht 'nur' Pulse an einem Eingang und erzeugt daraus 
autom. die Schrittfolge für den Motor.
Den Puls erzeuge ich jetzt in der ISR mit:

PORTB &= ~(1 << PB0); // Einschalten
_delay_us(100);
PORTB |= (1 << PB0); // Ausschalten

Komme damit laut Oszilloskop auf eine Frequenz von 4.96 kHz (202us) bei
OCR1A von 399.
Gast #2577305
Lesenswert?

Also in etwa der Erwartungswert

> Mit der Frequenz 16000000 durch 8 durch (400+1) wird deine ISR
> aufgerufen, d.h. mit ca. 4988 Hz bzw. ca. 200 µs.

Weisst du schon, warum du beim Threadstart so weit daneben warst?

>> Wenn ich an dem Portpin die Frequenz messe, dann erhalte ich 3,125 kHz
>> bzw. 320us.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren