ATxmega32A4

Hallo,

habe eine Frage zu folgendem Mikrocontroller (ATxmega32A4) besitzt dieser Mikrocontroller 16 PWM Ausgänge und wie lässt sich es anhand des Datenblatts rausfinden, welche Pins die PWM fähigen Pins sind ?

http://www.microchip.com/wwwproducts/en/ATxmega32A4

Google ist dein Freund. ;)

In Google "ATxmega32A4 pinout" eingeben und schon siehst du es.

Also die Pins, die mit OC gekennzeichnet sind besitzen PWM fähige Pins richtig?

Haben Sie eine Empfehlung für einen Mikrocontroller mit 8 PWM fähigen Pins?

Wenn du einen Standard Arduino willst wäre der Atmega2560 eine Option

Oder vielleicht der M0: https://www.arduino.cc/en/Main/ArduinoBoardM0 Gleiches Bauformat wie der UNO aber ein ARM Prozessor (aber Vorsicht: 3,3V)

Serenifly:
Wenn du einen Standard Arduino willst wäre der Atmega2560 eine Option

Oder vielleicht der M0:
https://www.arduino.cc/en/Main/ArduinoBoardM0
Gleiches Bauformat wie der UNO aber ein ARM Prozessor (aber Vorsicht: 3,3V)

Vielen Dank ersteinmal für den Hinweis.
Kennst du vielleicht noch einen anderen Mikrocontroller, der 8 PWM Pins hätte und mit einer Versorgungsspannung von 5V betrieben wird?

Lies dir die Beschreibung genau durch. Als Versorgungsspannung kannst du ruhig 5V nehmen. Das ist wie bei anderen Arduinos ein Spannungsregler drauf. Aber die Ausgangs- und Eingangsspannung ist 3,3V. Das kann je nach Peripherie problematisch sein.

Serenifly: Lies dir die Beschreibung genau durch. Als Versorgungsspannung kannst du ruhig 5V nehmen. Das ist wie bei anderen Arduinos ein Spannungsregler drauf. Aber die Ausgangs- und Eingangsspannung ist 3,3V. Das kann je nach Peripherie problematisch sein.

Das mit der Versorgungsspannung habe ich gesehen für mein Projekt brauche ich einen Mikrocontroller, der über 8 PWM fähige Pins verfügt. Deswegen meine Frage, ob du villeicht einen anderen Mikrocontroller kennst, der über 8 PWM fähige Pins verfügt. Möchte den Mikrocontroller gerne über die Arduino IDE programmieren und auf eine geätzte Platine auflöten, dass ganze soll eine Motorsteuerung werden, die mittels PWM mir die 4 Motoren steuert, deswegen bräuchte ich einen Mikrocontroller, der über 8 PWM Pins verfügt da meine Motortreiber (DRV8833) je 2 PWM Pins benötigen. Die Ausgangs- und Eingangsspannung für die Peripherie sollte dabei 5V betragen, da ich die Schaltung soweit schon auf 5V ausgelegt habe.

Es gibt doch I2C-PWM-Bausteine. Da kannst du den PWM-Ausgang per I2C erweitern. Sieh mal nach PCA9685.

Würde das in einem Fall auch gehen, da die Motoren in der Drehzahl ja unabhängig voneinander gesteuert werden sollen und ich ja eigentlich bei der Erweiterung mit dem PCA9685 einen PWM-Ausgang nehmen würde, der den Gleichen PWM-Wert (z.B. 255) hätte.

Habe gelesen, dass es auch die Möglichkeit gibt digitale Pins per Software als PWM Pins zu benutzen würde dies in meinem Fall nür einen Pin, der mir fehlen würde sinn machen oder wäre es besser doch einen Mikrocontroller zu nehmen, der 8PWM Ausgänge hat, da die Software PWM ja mehr Anspruch hat als die Hardware PWM und so den Mikrocontroller verlangsamen würde.

Welche Mikrocontroller stehen den noch zur Auswahl, die mindesten 8PWM Ausgänge oder mehr besitzen?

Marvin97:
Würde das in einem Fall auch gehen, da die Motoren in der Drehzahl ja unabhängig voneinander gesteuert werden sollen und ich ja eigentlich bei der Erweiterung mit dem PCA9685 einen PWM-Ausgang nehmen würde, der den Gleichen PWM-Wert (z.B. 255) hätte.

Warum soll das nicht gehen ? Darum wird der PCA9685 ja gebaut.

Welche Mikrocontroller stehen den noch zur Auswahl, die mindesten 8PWM Ausgänge oder mehr besitzen?

Das wurde dir doch schon geschrieben.
Und Google ist dein Freund.
Einfach mal googeln.

HotSystems: Warum soll das nicht gehen ? Darum wird der PCA9685 ja gebaut.

Das wurde dir doch schon geschrieben. Und Google ist dein Freund. Einfach mal googeln.

Ja dachte der PCA9685 wäre dafür da digitale Ausgänge als PWM zu nutzen, also wäre es möglich, dass der eine PWM Ausgang z.B. den Wert 255 hat und durch den PCA9685 eine Erweiterung entsteht, sprich aus 6 PWM Ausgänge können 8 PWM Ausgänge werden und diese unterschiedliche PWM-Werte haben?

Ok, ich habe den bisher noch nicht eingesetzt, kann aber das Datenblatt lesen. Das solltest du auch machen. Der Baustein macht aus I2C 16 eigenständige PWM-Kanäle. Den Rest bitte selbst lesen.

Marvin97: Ja dachte der PCA9685 wäre dafür da digitale Ausgänge als PWM zu nutzen, also wäre es möglich, dass der eine PWM Ausgang z.B. den Wert 255 hat und durch den PCA9685 eine Erweiterung entsteht, sprich aus 6 PWM Ausgänge können 8 PWM Ausgänge werden und diese unterschiedliche PWM-Werte haben?

Wenn man Ausgänge multiplext zb mit einem CD4067 dann ist immer nur 1, der ausgesuchte, Ausgang aktiv. Darum ist es nicht sinnvol Ausgänge multipexen. Anders ist es mit Eingänge; da ist es sinnvoll einen Multiplexer zubenutzen. Versteh einen Multiplexer als einen mehrstufigen Schalter der einen von mehreren Kontakten auf Common schaltet. Die anderen hängen in der Luft.

Der PCA9685 ist ein Baustein der hat 16 PWM Ausgänge und wird vom Arduino über I2C gesteuert. Du solltest das Datenblatt lesen.

Grüße Uwe

Oder man macht sich eine ISR-Routine mit ca. 10KHz:

byte PWM1, PWM2, PWM3, PWM4, PWM5, PWM6, PWM7, PWM8;
byte PWMSoll1, PWMSoll2, PWMSoll3, PWMSoll4,
     PWMSoll5, PWMSoll6, PWMSoll7, PWMSoll8;

void setup(){

}

ISR (TIMER1_COMPA_vect){
  PWM1++;
  if(PWM1>PWMSoll1) PWMPin1=hi; else PWMPin1=low;
  PWM2++;
  if(PWM2>PWMSoll2) PWMPin2=hi; else PWMPin2=low;
  PWM3++;
  if(PWM3>PWMSoll3) PWMPin3=hi; else PWMPin3=low;
  PWM4++;
  if(PWM4>PWMSoll4) PWMPin4=hi; else PWMPin4=low;
  PWM5++;
  if(PWM5>PWMSoll5) PWMPin5=hi; else PWMPin5=low;
  PWM6++;
  if(PWM6>PWMSoll6) PWMPin6=hi; else PWMPin6=low;
  PWM7++;
  if(PWM7>PWMSoll7) PWMPin7=hi; else PWMPin7=low;
  PWM8++;
  if(PWM8>PWMSoll8) PWMPin8=hi; else PWMPin8=low;
}

Das ist natürlich kein fertiger Code, er dient nur zur Veranschaulichung wie leicht man sich PWM selber machen könnte. Jedes hochzählen und dann vergleichen und setzen dauert aber grob 20 Takte, also bei 8 PWMs dann ca 160 Takte. Bei 10KHz sind das dann ca. 10% Rechenleistung, wenn man es mit 20KHz versucht dann 20%. Bei 10KHz bekommen die Motoren dann ca. 40 mal pro Sekunde (10000/256) ein low- und hi-Signal und man hat 256 Stufen. Man kann die effektive Herz-Zahl (0 - 1 Signal) bei gleicher Interruptfrequenz auf 80 verdoppeln wenn man statt PWMn++ (erhöhen um 1) PWMn+=2 schreibt reduziert aber die Auflösung auf 128 Stufen.

MfG Andi

EDIT: Es wäre auch möglich, die effektive PWM-Frequenz mit anderen Aditionswerten zu erhöhen wie z. B. 129. Dadurch wird ein permanenter hi/low-Wechsel herbeigeführt im 10KHz-Bereich. Oder man addiert 3 oder 5 dazu was den hi/low-Wechsel verdrei- oder verfünffacht. Je nachdem, was die Motoren abkönnen und wie sie darauf reagieren.

Da ich bald 4 Motoren in einem Quadcopter steuern will ließ mir das hier mit Soft-PWM keine Ruhe mehr und habe das von mir vorher gepostete mit den beiden LEDs auf einem A-STAR 32U4 ausprobiert.
Es ist sogar einfacher als gedacht:

#define greenLEDDDR DDRD
#define greenLEDPort PORTD
#define greenLED 1<<5
#define yellowLEDDDR DDRC
#define yellowLEDPort PORTC
#define yellowLED 1<<7
byte PWM,
     PWMSoll1=2, PWMSoll2=2;
#define PWMAdd 35

void setup() {
  // put your setup code here, to run once:
  greenLEDDDR|=greenLED;
  yellowLEDDDR|=yellowLED;

  TCCR0A = 0;                     //Controlregister für Timer 0 zurücksetzen
  TCCR0B = 0;
  TCNT0 = 0;                      //Timer 0 mit 0 starten
  OCR0A=62;                      //Timer 0 Output Compare Match A auf 250 setzen für 1ms
  TCCR0A = (1<<WGM01);            //CTC-Mode aktivieren
  TCCR0B = (1<<CS01)|(1<<CS00);//|(1<<WGM12);   //64 als Prescale-Wert setzen, 250 Takte = 1ms
  TIMSK0 = (1<<OCIE0A);           //Output Compare A Interrupt aktivieren

}

void loop() {
  // put your main code here, to run repeatedly:

  for(byte n=0;n<255;n++){
    PWMSoll1=n;
    PWMSoll2=0-n;
    pause(2*4);
  }
  for(byte n=255;n>0;n--){
    PWMSoll1=n;
    PWMSoll2=0-n;
    pause(2*4);
  }
}

void pause(int wait){
  byte t=TCNT0;
  while(t==TCNT0);
  while(wait>0){
    if(t==TCNT0){
      wait--;
      while(t==TCNT0);
    }
  }
}

#define greenLEDOff greenLEDPort|=greenLED
#define greenLEDOn greenLEDPort&=~greenLED
#define yellowLEDOff yellowLEDPort&=~yellowLED
#define yellowLEDOn yellowLEDPort|=yellowLED

ISR (TIMER0_COMPA_vect){
  byte p=PWM+=PWMAdd;
  if(p>=PWMSoll1) greenLEDOff; else greenLEDOn;
  if(p>=PWMSoll2) yellowLEDOff; else yellowLEDOn;

}

Der Timer 0 in Verbindung mit OCR0A wird nur zum Aufruf der ISR benutzt mit ca. 4KHz.
Also 4000 mal pro Sekunde werden die Ports für die LEDs des Boards auf hi oder low gesetzt.
Theoretisch ergibt sich bei 256 Stufen 4000/256=15,6 volle Zyklen.
Aber mit einem Additionswert von 35 wird die Ausgabe der hi/low-Werte erheblich beschleunigt da dadurch das PWM-Signal nicht in einem Zyklus erst nur hi und dann low sondern diese zerstückelt ausgegeben werden.
Bei 4KHz ab einem Soll-Wert von 3 ist so gut wie kein Flimmern bei den LEDs zu erkennen.
Wers ausprobieren will sollte aber zuerst sehen, an welchen Port-Pins sich die Board-LEDs befinden und die Variablen mit greenLED und yellowLED vorher anpassen.

MfG
Andi