Fast PWM 1MHz

Gast #6683504
Lesenswert?

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:

}
Gast #6683556
Lesenswert?

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.
Gast #6683597
Lesenswert?

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.
Gast #6683637
Lesenswert?

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.
Gast #6683842
Lesenswert?

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
Angehängte Dateien:
Gast #6684381
Lesenswert?

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.
Gast #6684407
Lesenswert?

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.
Gast #6684431
Lesenswert?

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...
Gast #6684580
Lesenswert?

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. ;-)

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