Mega 2560 Timer Pwm 2 ausgaänge?

Moin zusammen ich hätte da ein Anliegen.

Und zwar würde ich gerne mit einem oder mehreren Timern eine PWM mit 7khz ausgeben die an zwei Pins ausgegeben wird und zwar einmal invertiert.

Ich habe jetzt etwas rumprobiert und an OC1A Pin 11 bekomme ich die 7khz mit Fast-PWM mode 15 auch ausgegeben. An OC1B Pin 12 bleibt jedoch leider alles bei 0. Im datenblatt habe ich nun gelesen das sobald COM1A1/0 auf toggle gesetzt wird die anderen ausgänge nicht mehr für den Timer deklariert sind.

Gibt es eine Hardware/Timer basierte möglichkeit eine PWM 2mal an jeweils seperaten pins aus zu geben wobei ein Pin die invertierte PWM führt?

Schonmal vielen Dank im vorraus, anbei mein test skript für die Timer einstellung.

void setup() {
  // put your setup code here, to run once:

TCCR1A = (1<<COM1A0)|(1<<COM1B0)|(1<<WGM11)|(1<<WGM10);             // TCCRxA (x = Timernumber) Register -> COM1A1 / COM1A0 / COM1B1 / COM1B0 / COM1C1 / COMC1C0 / WGM11 / WGM10
TCCR1B =  (1<<WGM13)|(1<<WGM12)|(1<<CS10);                         // TCCRxB *                 Register -> ICNC1  / ICES1  /   --   / WGM13  / WGM12  /  CS12   / CS11  / CS10     
                                                                  // CSxx = Prescaler     WGMxx = Timermode   COMxA/COMxB/COMxC = Verhalten von Outputpin einstellen
                                                                 // Frequenz = 7kHz ~ 142,8us     clockfreq = 16Mhz ~ 62,5ns       (142,8 *10^-6) / 62,5 *10^-9)/2 =~ 1143 -> OCR1A für Topwert
  OCR1A = 1132;     //1143 ~6,9kHz                               // OCRnA = Ouputcompare Timer zählt zu diesem wert dann reset   OCRnB = Dutycycle
  OCR1B = 1132;
      
  //DDRB = _BV(PB5) | _BV(PB6);
    DDRB |= (1 << PB5);
    //DDRB &= ~(1 << PB5);
    DDRB |= (1 << PB6);
    //DDRB &= ~(1 << PB6);
  
}

void loop() {
 
}

Mir scheint, Du verwechselst zwei Einschränkungen. Die Frequenz kann für jeden Timer nur 1 mal eingestellt werden, über OCRxA oder (besser) ICRx. Damit wird TOP festgelegt, wann der Timer zurückgesetzt werden soll. Danach kann für jeden Timer Kanal (A, B und beim Mega noch C) das Tastverhältnis (duty cycle) über das OCRxc eingestellt werden, mit Werten von 0 bis TOP.

Wenn noch Bibliotheken eingesetzt werden, dann empfiehlt sich für eigene Experimente ein höherer Timer (4/5), weil Bibliotheken bevorzugt die niedrigen Timer für ihre Zwecke benutzen.

Ich möchte doch garkeine unterschiedlichen Frequnezen haben…die Frequenz soll bei beiden ausgängen gleich sein.

Nochmal, ich möchte mit einem Timer eine PWM generieren und diese auf zwei Pins separat ausgeben eine davon soll invertiert laufen das heist OC1A ist 5V dann ist OC1B 0V und anders rum.

Das ich hierzu auch Timer 4 benutzen kann ist mir klar dazu ist aber auch nur eine kleine Änderung nötig.

Mein Problem ist das ich wenn ich eine PWM mit egal welchem Timer ausgebe und den Channel A Toggle der Cannel B und C keine Pwm ausgeben wollen. Wenn ich die COM1A1/0 register setze so das er OC1A setzt bei Top wert und COM1B1/0 bei Bottom um eine invertierte ausgabe zu bekommen, schalten die einmalig auf High und bleiben dann auf 5V.

um eine invertierte ausgabe zu bekommen,

Du kannst die Polarität der Pins in den Registern umschalten.
Benötigst also kein Vertauschen der Grenzwerte/Umschaltwerte.

Wenn ich die COM1A1/0 register setze so das er OC1A setzt bei Top wert und COM1B1/0 bei Bottom um eine invertierte ausgabe zu bekommen,

Das ist also überflüssig.

Wenn OCRxA für die Einstellung der Frequenz benutzt wird, kann auf diesem Kanal keine PWM ausgegeben werden, das geht nur bei ICRx für die Frequenzeinstellung.

BOTTOM ist nicht einstellbar, ist immer 0.

Eine Umschaltung der Ausgänge bei TOP oder BOTTOM ist nicht möglich, da bleiben die Ausgänge immer auf 0 oder 1, entsprechend duty cycle 0% und 100%.

Hallo,

hier hatte ich einmal die Basics am Bsp. erklärt.

Durchlesen, anwenden, verstehen, abändern.

Wenn du dann im Manual die Bedeutung der COM Bits anschaust, siehst du in der Tabelle welches Bit für nicht invertiert (Clear) und welche Bits für invertiert (SET) im Register gesetzt sein muss.
Empfehlen würde ich einen Phase Correct Mode.
Dann gibts bei DutyCycle 0 bzw. @TOP keine Narrow Spikes.
TOP hier wie schon gesagt wurde mittels ICRn.
Den Timer starten würde ich erst, wenn alle anderen Bits gesetzt sind.
Desweiteren musst du alle Timerregister vor eigener Verwendung löschen bzw. dafür sorgen das nur deine Config in den Registern steht. Die sind vom Arduino Framework vorbelegt.
Die Pins auf Ausgang schalten kannste mit pinMode. Mach es dir nicht unnötig schwer.

@combie
kannst du das mit dem invertieren näher erläutern bzw. mir nen anhaltspunkt geben wo ich dazu was finde ? wäre sehr nice.

Habe jetzt mit CTC Mode 4 auf beiden channels eine 7khz PWM, jetzt fehlt also nurnoch die invertierung einer davon.

Da musst Du einen PWM-Mode nutzen, und dann kannst Du das mit den 'Compare Output Mode' einstellen:
COM.PNG
Die unteren beiden sind dein Freund.

COM.PNG

Die tabelle kenne ich, habe ich bereits versucht.
Die Unteren beiden geben aber keine PWM aus die schalten den Ausgang permament auf High oder bleiben auf Low bei mir. Nur toggle funktioniert.

Nimm mal die Tomaten von den Augen, in der Tabelle gibt es zwei Zeilen für inverting und non-inverting mode. Wie MicroBahner richtig herausgefunden hat: es sind die beiden unteren Zeilen :slight_smile:

Hallo,

mal im Ernst, es liegen alle Information auf dem goldenen Teller.
Warum du jetzt auf den CTC Mode gewechselt bist verstehe ich nicht.
CTC ist jedenfalls kein PWM Mode. Die COM Bits haben keine Wirkung.
Lies einmal nochmal den Thread von oben angefangen in Ruhe durch.

treeshort:
Die Unteren beiden geben aber keine PWM aus die schalten den Ausgang permament auf High oder bleiben auf Low bei mir. Nur toggle funktioniert.

Lies was ich geschrieben habe:

MicroBahner:
Da musst Du einen PWM-Mode nutzen,

Und lies die Textzeile direkt oberhalb der der Tabelle: Fast PWM. Wie auch Doc_Arduino schreibt: Dein Problem ist der CTC-Mode. Mit dem kannst Du kein PWM erzeugen.