Hallo zusammen, ich möchte an meinem Arduino uno bzw ATmega328p ein 1MHz Rechtecksignal ausgeben und dachte ich mach das am besten über ein PWM. Leider hab ich keine Erfahrung mit PWM und irgendwie kommt mir mein Code etwas wenig vor. Habe ich was vergessen oder sollte das so funktionieren? Und was kommt in meine main Schleife? void setup() { // put your setup code here, to run once: DDRB |= (1<<DDB1); // Set Pin B1 as Output (OC1A) TCCR1A = (1<<COM1A0)|(1<<WGM11); // toggle on compare match TCCR1B = (1<<WGM12)|(1<<WGM13)|(1<<CS10); // no prescaler ICR1 = 15; // 1MHz Freq } void loop() { // put your main code here, to run repeatedly: }
Ich glaube ehrlich gesagt nicht, dass man aus nem Atmega328 ne 1MHz PWM herausbekommt.
Jannik schrieb: > oder sollte das so funktionieren? Sollte es, jedenfalls fast: 16MHz Clock vorausgesetzt muss ICR1 auf 7, denn schließlich wird getoggelt und eine Schwingung besteht aus 2 mal toggeln. > Und was kommt in meine main Schleife? Wenn nichts weiteres getan werden soll: Nix.
Jannik schrieb: > sollte das so funktionieren? Nicht ganz. Jannik schrieb: > // toggle on compare match Das gilt für non-PWM. Guck dir die nächste Tabelle an. Und setze das OCR1A-Register für den Dity-Cycle. Dann passt das. Jannik schrieb: > Und was > kommt in meine main Schleife? Erstmal gar nichts außer einer leeren while-Schleife, damit es auch eine Schleife ist. Das Ganze kannst du natürlich auch mit Timer 0 oder 2 machen, dann sparst du dir den 16-Bit-Timer für höhere Aufgaben. Du nimmst dann OCRA als Top-Register und OCRB für den Duty-Cycle. BEN schrieb: > Die maximale Frequenz bei 8 Bit ist > 16.000.000/256 Und du mußt noch viel lernen.
Jannik schrieb: > ich möchte an meinem Arduino uno bzw ATmega328p ein 1MHz Rechtecksignal > ausgeben und dachte ich mach das am besten über ein PWM. Leider hab ich > keine Erfahrung mit PWM und irgendwie kommt mir mein Code etwas wenig > vor. Habe ich was vergessen oder sollte das so funktionieren? Du hast was vergessen. Nämlich: OCR1A = 7; > Und was > kommt in meine main Schleife? Nix, sie muss nur da sein.
Danke für eure Antworten! @BEN im Anhang ist die Formel die ich verwendet habe. Ich bin draufgekommen, dass das ganze auch über den CTC Mode machbar sein sollte. Würde mir der Code ebenfalls ein 1MHz Signal ausgeben?
1 | TCCR1A = 0; |
2 | TCCR1B = 0; |
3 | |
4 | TCCR1A |= 1 << COM1A0; // Toggle OC1A on compare match |
5 | TCCR1B |= 1 << WGM12; // Set WGM=4: CTC, TOP in OCR1A |
6 | OCR1A = 7; // TOP = 7, Frequency = 1 MHz (2 MHz but toggling) |
7 | TCCR1B |= 1 << CS10; // Start clock at 16 MHz |
Hallo, richtig, für ein 50/50 Rechtecksignal reicht der CTC Mode aus. Getoggelt wird bei halber Periodendauer. - OC Pin auf Ausgang setzen - Timer konfigurieren - Timer starten - gucken was passiert
:
Bearbeitet durch User
Jannik schrieb: > Ich bin draufgekommen, dass das ganze auch über den CTC Mode machbar > sein sollte. Würde mir der Code ebenfalls ein 1MHz Signal ausgeben? Was heißt "ebenfalls"? Dein Originalcode tat das schließlich nicht. Erst meine Ergänzung bringt ihn dazu. Ansonsten kann man das natürlich auch per CTC abwickeln. Ich habe aber keine Lust mehr, deine Implementierung im Detail zu analysieren. Steht doch eigentlich alles im Datenblatt.
c-hater schrieb: > Du hast was vergessen. Nämlich: > > OCR1A = 7; Nö, hat er nicht, lies das DB, er konfiguriert Mode 14 mit ICR1 als Top und, Zitat: Table 16-2. Compare Output Mode, Fast PWM WGM13:0 = 14 or 15: Toggle OC1A on Compare Match Er war schon richtig, nur der Wert für ICR1 war falsch und das schrieb ich bereits. c-hater schrieb: > Was heißt "ebenfalls"? Dein Originalcode tat das schließlich nicht. Erst > meine Ergänzung bringt ihn dazu Du solltest gründlicher recherchieren, sonst wirst Du genau so eine Schmarrnschleuder wie stefanus, bloß lauter.
MWS schrieb: > Nö, hat er nicht, lies das DB, er konfiguriert Mode 14 mit ICR1 als Top > und, Zitat: > Table 16-2. Compare Output Mode, Fast PWM > WGM13:0 = 14 or 15: Toggle OC1A on Compare Match Stimmt, das hatte ich übersehen. Er hat da nicht wirklichen einen PWM-Mode konfiguriert, auch wenn der WGM-Mode das nahelegt, sondern effektiv einen CTC-Modus. Für den wirklichen PWM-Modus hätte er statt COM1A0 COM1A1 setzen müssen. Dann hätte das mit OCR1A = 7 auch funktioniert... Naja, umso weniger erstaunlich ist es natürlich, dass auch ein echter CTC-Modus funktioniert, wenn man den Teiler entsprechend des Toggling-Verhaltens festlegt...
Die Auflösung ist halt mies. Da der Timer nur noch bis 7 zählt, bleiben einem nur PWMs mit max. 8 Stufen.
:
Bearbeitet durch User
Matthias S. schrieb: > Die Auflösung ist halt mies. Nachdem im Beispiel beim Comparematch getoggelt wird, ist die Auflösung völlig unerheblich.
Matthias S. schrieb: > bleiben einem nur PWMs mit max. 8 Stufen. Also ich bekomme zwischen 0 und DC 15 Stufen. Da bin ich bestimmt nicht der einzige. Aber du bist wahrscheinlich der einzige, der nur 8 schafft.
Wenn ich stabile 1 MHz ausgeben möchte, nutze ich keine PWM, sondern ein Teilerverhältnis, das hoffenlich mit meiner Quarzfrequenz (2*N * 1MHz wären in die engere Wahl zu ziehen) funktioniert. Probier doch mal N zu bestimmen! Ist wirklich machbar: Da gibt's nicht soooooooo viele Möglichkeiten. ;-)
Und eine PWM mit einem Duty-Cycle von 50% ist nicht stabil oder kränkt den Controller in seiner Ehre? Interessant.
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.