Arduino Mega 3x 16 Bit PWM

Hallo,

ich versuche meinen ‘alten’ Arduino Mega 1280 dazu zu bewegen 3x 16 Bit PWM’s zu erzeugen. Laut Datenblatt sollte das über Timer 1, 3,5,4 machbar sein. Meine Idee: Mal wieder LED. Am liebsten würde ich auch von Pin 13 weg. Das geflacker beim Initialisieren nervft schon ziemlich.

// globale Variablen
unsigned int MaxCount = 65535;            // bis zu diesem Wert zählt der Counter, dann wieder auf 0
unsigned int PWMCount = 0;                // aktueller Wert für PWM
unsigned int i = 0;

void setup(void)
{
        TCCR1B = 0;
        TCCR1A = 0;        //Kein Prescaler (16 MHz)

        TCCR3B = 0;
        TCCR3A = 0;
        TCCR3B |= (1<<CS10);                    //Kein Prescaler (16 MHz)

        TCCR4B = 0;
        TCCR4A = 0;
        TCCR4B |= (1<<CS10);                    //Kein Prescaler (16 MHz)

        TCCR5B = 0;
        TCCR5A = 0;
        TCCR5B |= (1<<CS10);                    //Kein Prescaler (16 MHz)

// 2c. Den Timer in den Fast PWM Mode, Mode 15 schalten
TCCR1A |= (1<<WGM11) | (1<<WGM10);
TCCR1B |= (1<<WGM12) | (1<<WGM13);

TCCR3A |= (1<<WGM31) | (1<<WGM30);
TCCR3B |= (1<<WGM32) | (1<<WGM33);

TCCR4A |= (1<<WGM41) | (1<<WGM40);
TCCR4B |= (1<<WGM42) | (1<<WGM43);

TCCR5A |= (1<<WGM51) | (1<<WGM50);
TCCR5B |= (1<<WGM52) | (1<<WGM53);


// 3. bei Mode 15: TOP über OCRXA setzen
OCR1A = MaxCount;              
OCR3A = MaxCount;              
OCR4A = MaxCount;              
OCR5A = MaxCount;              

// 4. Compare Output mode einstellen:  invertiert oder nicht invertiert
//  TCCR1A |= (1<<COM1C0) | (1<<COM1C1);  // invertiert
TCCR1A |= (1<<COM1C1);                 // nicht invertiert
TCCR3A |= (1<<COM3C1);                 // nicht invertiert
TCCR4A |= (1<<COM4C1);                 // nicht invertiert
TCCR5A |= (1<<COM5C1);                 // nicht invertiert

// 5. In diesen Registern wird der gewünschte PWM-Wert abgelegt. Erlaubter Bereich: 0 bis 255, 511, 1023, TOP.
OCR1C = PWMCount;
OCR3C = PWMCount;
OCR4C = PWMCount;
OCR5C = PWMCount;


// 6. Pin OC1C / Port B, Bit7 / Arduino Pin 13 als Ausgang konfigurieren. Erst jetzt liegt das PWM-Signal am Pin an! 
 //DDRB |= (1<<PB7);  // Bit 7 als Ausgang
DDRB = B11111111;

 i = 0;

}

void loop()
{
      OCR1C = i;
      OCR3C = i;
      OCR4C = i;
      OCR5C = i;
      i++;
      delay(1);
}

Allerdings geht nur Pin 13 (Led), Warum funktioniert das nicht mit Pin 12, 11 ???. Wo ist den mein Denkfehler

Gruß Michael

PS: Das Beispiel stammt aus der Timer1 Library

Hallo Michael,
willkommen im Forum.

Möglicherweise liegt es daran, dass die Ausgänge OC3C, OC4C und OC5C nicht wie OC1C auf Port B liegen (siehe Pinbelegung im Datenbuch oder Schaltplan ATMega 1280). Daher müssen wahrscheinlich die Ausgänge OC3C (Port E, Bit5), OC4C (Port H, Bit 5) und OC5C (Port L, Bit 5) als Ausgänge definiert werden (in Schritt 6 des Programms).

DDRE |= (1<<PE5);  // Bit 5 als Ausgang
DDRH |= (1<<PH5);  // Bit 5 als Ausgang
DDRL |= (1<<PL5);  // Bit 5 als Ausgang

Auf meinem ATMega 2560 ist allerdings der Ausgang von Timer 5 garnicht auf der Stiftleiste herausgeführt. Er kann daher nicht als Ausgang benutzt werden. Ansonsten liegen die Ausgänge nicht auf den Arduino-Pins 11 und 12 sondern auf Pin 3 und Pin 8.

Alle Angaben für ATMega 2560, ist hoffentlich bein ATMega 1280 auch so.

Weiterhin müsstest du eigentlich bei Timer 1 am Anfang von setup() das Bit CS10 setzen.
Und der guten Ordnung halber bei Timer 3, 4 und 5 die Bits CS30, CS40 und CS50 statt CS10.
Da aber alle die gleiche Bitposition (Bit 0) sind, dürfte es trotzdem klappen.

Viel Erfolg.

Gruß Wolfgang

Hallo Wolfgang,

ich hatte gedacht die OC3C, OC4C und OC5C liegen alle auf Port B. Ich schaue mir das nochmals an. Danke für Deine Antwort

Gruß Michael

Hallo Wolfgang,

danke für Deine Hilfe. Wirklich super erklärt. Timer 5 ist draussen. So funktioniert’s

// globale Variablen
unsigned int MaxCount = 65535;            // bis zu diesem Wert zählt der Counter, dann wieder auf 0
unsigned int PWMCount = 0;                // aktueller Wert für PWM
unsigned int i = 0;

void setup(void)
{
  TCCR1B = 0;
  TCCR1A = 0;       
  TCCR1B |= (1<<CS10);                    //Kein Prescaler (16 MHz)

  TCCR3B = 0;
  TCCR3A = 0;
  TCCR3B |= (1<<CS30);                    //Kein Prescaler (16 MHz)

  TCCR4B = 0;
  TCCR4A = 0;
  TCCR4B |= (1<<CS40);                    //Kein Prescaler (16 MHz)

  // 2c. Den Timer in den Fast PWM Mode, Mode 15 schalten
  TCCR1A |= (1<<WGM11) | (1<<WGM10);
  TCCR1B |= (1<<WGM12) | (1<<WGM13);
  
  TCCR3A |= (1<<WGM31) | (1<<WGM30);
  TCCR3B |= (1<<WGM32) | (1<<WGM33);
  
  TCCR4A |= (1<<WGM41) | (1<<WGM40);
  TCCR4B |= (1<<WGM42) | (1<<WGM43);
  
  // 3. bei Mode 15: TOP über OCRXA setzen
  OCR1A = MaxCount;              
  OCR3A = MaxCount;              
  OCR4A = MaxCount;              
  
  // 4. Compare Output mode einstellen:  invertiert oder nicht invertiert
  //  TCCR1A |= (1<<COM1C0) | (1<<COM1C1);  // invertiert
  TCCR1A |= (1<<COM1C1);                 // nicht invertiert
  TCCR3A |= (1<<COM3C1);                 // nicht invertiert
  TCCR4A |= (1<<COM4C1);                 // nicht invertiert
  
  // 5. In diesen Registern wird der gewünschte PWM-Wert abgelegt. Erlaubter Bereich: 0 bis 255, 511, 1023, TOP.
  OCR1C = PWMCount;
  OCR3C = PWMCount;
  OCR4C = PWMCount;
  
  // 6. Pin OC1C / Port B, Bit7 / Arduino Pin 13 als Ausgang konfigurieren. Erst jetzt liegt das PWM-Signal am Pin an! 
  DDRB |= (1<<PB7);  // Bit 7 als Ausgang
  DDRE |= (1<<PE5);  // Bit 5 als Ausgang
  DDRH |= (1<<PH5);  // Bit 5 als Ausgang
  
  i = 0;
}

void loop()
{
  OCR1C = i;
  OCR3C = i;
  OCR4C = i;

  i++;
  delay(1);
}

Gruß Michael