Hallo Lieben User, ich habe mal eine Frage zum ATmega8 Timer. Ich möchte die Geschwindigkeit des Timerinterrupts über die Uart ändern. Klingt zunächst einfach, jedoch komme ich an dem Punkt der Berechnung der Zeit bzw der Frequenz nicht weiter und welchen Modus ich da am besten nutze. Ich möchte beispielsweise über die Uart eine 5 für 5kHz senden und anschliessend soll mir ein Rechtecksignal mit der Frequenz generiert werden. Aber im Moment fehlt mir einfach der Groschen für die Verknüpfung von Quarz und Timer. Wie ist das bei PWM? Ist da die Frequenz immer konstant und das Tastverhältnis kann nur geändert werden? Oder kann ich mit dem Mega8 eine PWM mit DutyC. 50% erzeugen aber die Länge der High und Lowpegel ändern? Für jeden Tip bedanke ich mich recht herzlich. Schönen Abend Jürgen
MoinMoin, nimm den Timer-Overflow-Interrupt und verändere den Preloadwert dynamisch, wie du es möchtest... Uwe
Vielen Dank Uwe... kannst du mir das vielleicht ein wenig näher erläutern ? Bin im Bereich Timer nicht sehr weit und arbeite gerade nach und nach das Tutorial und das Datenblatt durch. Vielleicht kannst du mir das in 2 Takten :-) erklären? Danke und Gruss Jürgen
@ JumboJ (Gast) >kannst du mir das vielleicht ein wenig näher erläutern ? Bin im Bereich >Timer nicht sehr weit und arbeite gerade nach und nach das Tutorial und >das Datenblatt durch. Dann tu das erstmal. Stichwort CTC-Modus. MFg Falk
Genau, CTC-Modus ist besser. Spart den Software-Reload (der sich schon mal was verzögern kann, wenn sich das Programm gerade in einem anderen Interrupt befindet oder Interrupts generell gerade gesperrt sind. CTC läuft exakt.
Bei 5 KHz für den CTC-Mode den Wert für das doppelte (hier 10 KHZ) berechnen und den Ausgang auf Toggel stellen. Dann hat man automatisch ein Rechteck mit der gewünschten Frequenz (bzw. der machbaren Näherung) mit 50 % Duty. gruß hans
ISR (TIMER2_COMP_vect) { PORTD^=(1<<PD7); } int main (void) { //Atmega8 TCCR2 |= (1<<WGM21) | (1<<COM21) | (1<<CS20); TIMSK |= (1<< OCIE2); DDRB = 0xFF; DDRD = 0xFF; PORTD = 0x00; sei(); while (1) { } cli(); return 0; } Wie schnell sollte jetzt mein Signal sein? ich bekomm irgendwas mit 7,8kHz, ist das korrekt? Danke und LG
Hallo, keine Ahnung, hab jetzt nicht alles abgesucht, ob Du irgendwo geschrieben hast, wie schnell Dein AVR getaktet ist... Trotzdem ein paar Fragen zum Nachdenken: wenn Du ein Rechtecksignal mit einer Frequenz erzeugen willst und dazu den Timer 2 im CTC-Mode laufen lässt mit WGM21 = 1 warum setzt Du dann COM21 = 1 (Clear OC2 on Compare Match) und nicht gleich COM20 = 1 (Toggle OC2 on Compare Match)? Dann würde Dein Signal fix und fertig an OC2 ausgegeben werden, dann wäre keinerlei Eingriff nötig, auch kein Interrupt. Weiter: wenn schon Interrupt, Du benutzt OCIE2, also Interrupt bei Compare Match. Auf welchem Wert steht denn bei Dir das Compare-Register (OCR2)? Das bestimmt ja im CTC-Mode, wann der Interrupt ausgelöst wird, nämlich dann, wenn der Zähler den Wert von OCR2 erreicht... Gruß aus Berlin Michael
Vielen Dank Michael, warst mir eine Große Hilfe, auch wenns nicht mein Beitrag war :-) Aber eine Frage hätte ich noch an der Stelle, Prozessor ist mit 3686400 definiert, dann sollten 7200Hz am OC2 korrekt sein, wenn OCR2 auf 255 gesetzt ist??? Oder wie berechne ich das bei CTC? Besten Dank Flo
Hallo, 3686400/256 = 14400 / 2 = 7200... Ich müßte jetzt selbst das genaue Verhalten nachschlagen, meiner Meinung nach wir im Takt den Erreichen des Compare geschaltet, das wäre dann bei Vorteiler 1 mit 255+1=256 richtig. Steht aber irgendwo im Datenblatt asl Diagramm oder so... Gruß aus Berlin Michael
es läuft so auch alles, aber irgendwie komme ich gerade mit dem debugger nicht ganz klar, wenn ich das unten stehende Programm simuliere, dann zählt TCNT2 irgendwie nur bis 0x0F bzw springt einfach nur von 0x07 auf 0x0F ???? und jedesmal wenn die 0x0F gelöscht wird also nur noch 0x07 gesetzt ist, dann springt OC2 um. Ich verstehe nicht warum TCNT2 nicht bis OCR2 zählt. Anscheinend ja schon im Taget, aber warum sehe ich das im AVR studio nicht? #define F_CPU 3686400 #define M_CPU Atmega8 #include <avr/io.h> #include <stdint.h> #include <avr/interrupt.h> ISR (TIMER2_COMP_vect) { } int main (void) { //Atmega8 3686400 TCCR2 |= (1<<WGM21) | (1<<COM20) | (1<<CS20); TIMSK |= (1<< OCIE2); DDRB = 0xFF; OCR2=255; sei(); //Interrupts ON while (1) { } cli(); return 0; } Danke und gruss
Keiner eine Idee warum der Debugger beim AVR-Studio zickt und auf dem Mega alles funktioniert? gruss Flo
>Keiner eine Idee warum der Debugger beim AVR-Studio zickt und auf dem >Mega alles funktioniert? Der Simulator ist nicht perfekt. Atmel veröffentlicht aber irgendwo (vermutlich im AVRStudio) die Fehler des Simulators.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.