Hallo zusammen, ich möchte gerne in einer fest eingestellten Zeit eine AD Wandlung vornehmen und infolge dieses Wertes das Tastverhältnis eines PWM Signal mit einer def. Frequenz von 100Hz erzeugen. Das ganze soll also eine Samplerate von 10S/s haben. Ich benutze einen ATMega8 mit 4MHz Takt. Ich habe mir also einen Timer genommen und die Samplerate eingestellt. Das heißt alle 0,1s wird eine Interruptroutine ausgeführt und die AD Wandlung vorgenommen. Soweit ist das ganze nicht so schwer. Nun will ich ja aber das PWM mit einer festen Frequenz von 100Hz generieren. Die genaue Frequenz kann ich aber mit der PWM Funktion der eingebauten Timer nicht realisieren(habs nicht hinbekommen).Darum nehme ich also einen zweiten Timer der beim Überlauf immer einen komplimentären Zustand an dem Ausgabepin erzeugt. Da ich aber für beide Timer die Interrupt Routine verwende kommmen manchmal ganz komische Sachen am Ausgang heraus auch wenn ich das Eingangssignal nicht verändere. Ich schätze die Interrupts überschneiden sich. Kann man dieses Phänomen unterdrücken oder funzt das mit der hier beschriebenen Methode nicht ??? Vielen Dank schonmal Grüße Tom
Warum solltest Du die 100 Hz nicht in Hardware erzeugen können? Ich hab's selbst noch nicht gemacht, aber wenn ich mir die Beschreibung durchlese, kannst Du den TOP-Wert mittels OCR1A auf 39999 festsetzen und den PWM-Wert mit OCR1B einstellen. Damit hättest Du eine Taktteilung durch 40000, was 100 Hz in der Ausgabe macht (operation mode 15).
Hallo Jörg, ich hab mich einmal etwas näher mit der Hardwaremöglichkeit beschäftigt. Das stimmt das man ein PWM Siganl auf die Weise mit einer festen Frequenz erzeugen kann. In der Beschreibung steht, dass wenn man eine feste Frequenz erzeugen will, das TOP value in ICR1 schreiben soll(Mode14)und der Vergleichswert in OCR1A. So habe ich das wenigstens verstanden und folgendermaßen implementiert. #include <avr/io.h> #include <inttypes.h> DDRB|(1<<PB1); TCCR1B=(1<<WGM13)|(1<<WGM12)|(1<<CS10); TCCR1A=(1<<WGM11)|(1<<COM1A0); ICR1=39999; OCR1A=20000; int main(void) { while(1) ; } Aber es tut sich am Port OC1/PB1 garnichts. Habe ich vielleicht noch eine Kleinigkeit übersehen??? Grüße Tom
//36kHz Träger TCCR1A = _BV(COM1A1) | _BV(COM1A0) | _BV(WGM11); TCCR1B = _BV(WGM12) | _BV(WGM13) | _BV(CS10); OCR1A = 111; ICR1 = 222; Nur zur Anregung, ist für einen ATMega8 mit 8MHz und arbeitet. Der Pin muss nicht als Ausgang definiert werden, die Ausgabe erfolgt auf OC1A.
@mike: >> Der Pin muss nicht als Ausgang definiert werden, die Ausgabe >> erfolgt auf OC1A. Das ist aber ein Irrtum, wenn der Pin nicht als Ausgang definiert wird kommt kein Signal heraus. grüße leo
Genau da sehe ich auch Toms Fehler liegen: DDRB|(1<<PB1); Das ist ein ziemlich unnützes Statement (gibt das denn keine Warnung?). Gemeint war sicher: DDRB |= (1 << PB1);
Hallo zusammen, also ich denke auch dass der Pin schon als Ausgang definiert werden muss. Wie auch immer schaden kann es denke ich nichts. Allerdings ist mir der Fehler bei genauerem hinsehen auch aufgefallen, aber ich habe keine Fehlermeldung bekommen.(DDRB oder gleich muss es natuerlich heissen.) @Mike: Kannst du damit auch das Tastverhaeltnis aendern. Ich habe das auch hinbekommen dass ich die richtige Frequenz an OC1A bekomme allerdings konnte ich das TV nicht veraendern(es war immer 50%). Gruesse Tom
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.