Forum: Mikrocontroller und Digitale Elektronik Atemga8 Timer1 im CTC Modus - Frequenz?


von MrBurns (Gast)


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!

von Krapao (Gast)


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?

von Sauger (Gast)


Lesenswert?

Moin,

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

fällt dir was auf?

MfG

von Krapao (Gast)


Lesenswert?

Hehe, dann kommt der Prescaler 8 von wo anders. Da is' er :)

von MrBurns (Gast)


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.

von Krapao (Gast)


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.

von Krapao (Gast)


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.

von MrBurns (Gast)


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.

von Krapao (Gast)


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.

von Stefan E. (sternst)


Lesenswert?

Vermutlich ist schlicht ein anderer Quarz verbaut, als angenommen. 
Nämlich halt 10 MHz statt 16 MHz.

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.