mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik PWM an OC1A und OC1B


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Dennis (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

ich möchte an einem Atmega328P mehere PWMs erzeugen. Komischerweise 
funktioniert in meinem code nur die erste for Schleife. Die zweite hat 
keine Funktion. Sobald ich aber die erste auskommentiere funktioniert 
die zweite. Dachte es hängt vielleicht mit der Funktion _delay_ms 
zusammen. dies ist aber nicht der Fall. Den PWM erzeuge ich im Mode 5 (8 
Bit).
Kann mir jemand weiterhelfen.
void mfc_init (void)
{
  PWM_MFC1_PIN;
  PWM_MFC2_PIN;
  PWM_MFC3_PIN;
  PWM_MFC4_PIN;
  PWM_MFC5_PIN;
  
  /*** Timer 1 ***/  
  TCCR1A = 0x00;
  TCCR1B = 0x00;
  
  reg_help  = TCCR1A;
  reg_help |= (1<<WGM10);                    //Mode 5                
  //reg_help |= ((1<<WGM11) | (1<<WGM10));
  TCCR1A    = reg_help;
  
  reg_help  = TCCR1B;
  //reg_help |= ((1<<WGM13) | (1<<WGM12) | (1<<CS10));
  //reg_help |= ((1<<WGM12) | (1<<CS10));
  reg_help |= ((1<<WGM12) | (1<<CS11) | (1<<CS10));      //Mode 5, prescale 64
  TCCR1B    = reg_help;
  
  //ICR1H = 0x7F;  
  //ICR1L = 0x8C;  
  //OCR1AH = 0x3F;
  //OCR1AL = 0xC6;
  
  //OCR1AH = 0x00;  //PWM 50:50                       
  //OCR1AL = 0x7F;
  OCR1AH = 0x00;
  OCR1AL = 0xFF;
  
  OCR1BH = 0x00;
  OCR1BL = 0x3F;
  
  TCCR1A |= (1<<COM1A1);
  TCCR1A |= (1<<COM1B1);
}

void mfc_test (void)
{  
  unsigned int ui_i;
  unsigned char uc_i;
  
      
  for (uc_i = 0x00; uc_i <= 0xFF; uc_i++)
  {
    //OCR1AH = ((unsigned char) (ui_i >> 8));
    //OCR1AL = ((unsigned char) (ui_i & 0x00FF));
    OCR1AL = uc_i;
    //OCR1BL = uc_i;    
    //_delay_ms(25);
    for (ui_i = 0x0000; ui_i <= 0x7FFF; ui_i++);
        
  }
  
  
  for (uc_i = 0x00; uc_i <= 0xFF; uc_i++)
  {
    OCR1BL = uc_i;
    for (ui_i = 0x0000; ui_i <= 0x7FFF; ui_i++);
    //_delay_ms(25);
  }
                  
}

int main (void)
{
  mfc_init();


  while(1)
  {
    mfc_test();
  }
}


Autor: Wolfgang (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dennis schrieb:
> for (ui_i = 0x0000; ui_i <= 0x7FFF; ui_i++);
> ...
> for (ui_i = 0x0000; ui_i <= 0x7FFF; ui_i++);

Bist du dir sicher, dass dein Compiler das nicht wegoptimiert?

Autor: Matthias S. (Firma: matzetronics) (mschoeldgen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das läuft alles so schnell durch, das du davon ohne Oszilloskop gar 
nichts mitkriegst. Bau also die _delay_ms() wieder ein.

: Bearbeitet durch User
Autor: fop (Gast)
Datum:

Bewertung
2 lesenswert
nicht lesenswert
unsigned char uc_i;

Das gibt oft nur eine 8 Bit breite Variable. Also eine, die Werte von 0 
bis 255 aufnehmen kann.
Damit ist die Bedingung
uc_i <= 0xFF
 quasi immer erfüllt. Deine Schleife läuft also länger als Du denkst. Um 
genau zu sein : ewig.

Autor: ich (Gast)
Datum:

Bewertung
-2 lesenswert
nicht lesenswert
fop schrieb:
> Das gibt oft nur eine 8 Bit breite Variable. Also eine, die Werte von 0
> bis 255 aufnehmen kann.
> Damit ist die Bedingunguc_i <= 0xFF quasi immer erfüllt. Deine Schleife
> läuft also länger als Du denkst. Um
> genau zu sein : ewig.

0xFF passt aber auch in 8 Bit...

Autor: Dennis (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Wolfgang schrieb:
> Dennis schrieb:
>> for (ui_i = 0x0000; ui_i <= 0x7FFF; ui_i++);
>> ...
>> for (ui_i = 0x0000; ui_i <= 0x7FFF; ui_i++);
>
> Bist du dir sicher, dass dein Compiler das nicht wegoptimiert?

Bin mir Sicher. Es läuft ja. Aber eben immer nur eine der beiden for 
Schleifen. Wenn is z.B "//OCR1BL = uc_i;" wieder einkommentiere sehe ich 
wie beide Ausgänge von 0x00 - 0xFF durchlaufen. Habe sicherheitshalber 
aber auch die optimierung auf "none" gesetzt.

Matthias S. schrieb:
> Das läuft alles so schnell durch, das du davon ohne Oszilloskop gar
> nichts mitkriegst. Bau also die _delay_ms() wieder ein.

Ich habe ein Oszi dran. Ich kann sehr schön sehen wie die PWM von 0x00 - 
0xFF durchlaufen wird.

fop schrieb:
> unsigned char uc_i;
> Das gibt oft nur eine 8 Bit breite Variable. Also eine, die Werte von 0
> bis 255 aufnehmen kann.
> Damit ist die Bedingunguc_i <= 0xFF quasi immer erfüllt. Deine Schleife
> läuft also länger als Du denkst. Um
> genau zu sein : ewig.

Wie gesagt, es geht ja.

Autor: Maxim B. (max182)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dennis schrieb:
> reg_help  = TCCR1A;
>   reg_help |= (1<<WGM10);                    //Mode 5
>   //reg_help |= ((1<<WGM11) | (1<<WGM10));
>   TCCR1A    = reg_help;
>
>   reg_help  = TCCR1B;
>   //reg_help |= ((1<<WGM13) | (1<<WGM12) | (1<<CS10));
>   //reg_help |= ((1<<WGM12) | (1<<CS10));
>   reg_help |= ((1<<WGM12) | (1<<CS11) | (1<<CS10));      //Mode 5,
> prescale 64
>   TCCR1B    = reg_help;

Ja, ich verstehe diese Tänze nicht...
Könntest du doch nicht einfach schreiben:
TCCR1A |= (1<<WGM10);
TCCR1B |= ((1<<WGM12) | (1<<CS11) | (1<<CS10)); 
 ?

Autor: fop (Gast)
Datum:

Bewertung
2 lesenswert
nicht lesenswert
ich schrieb:
> 0xFF passt aber auch in 8 Bit...

Aber 8 Bit sind immer kleiner oder gleich 0xFF.

Autor: Dennis (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Maxim B. schrieb:
>
> Ja, ich verstehe diese Tänze nicht...
> Könntest du doch nicht einfach schreiben:TCCR1A |= (1<<WGM10);
> TCCR1B |= ((1<<WGM12) | (1<<CS11) | (1<<CS10));  ?

Für mein Problem nicht relevant...

Autor: Maxim B. (max182)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Dennis schrieb:
> Für mein Problem nicht relevant...

Aber deine Schreibweise ist relevant.
Kuck mal weiter: überall gleiche Styl!

Ich würde dir empfehlen, ein bißchen über C-Sprache zu lesen.

Du schreibst auf C so, als ob du Assembler hättest.

Compiler ist kein Narr, er sieht, daß etwas nicht stimmt, und wirkt 
verrückt.

Um Problem besser zu verstehen, kannst du compilierte asm ankucken. Ich 
glaube nach deinem Styl, gerade mit asm hast du kein Problem.

: Bearbeitet durch User
Autor: Dennis (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Maxim B. schrieb:
> Dennis schrieb:
>> Für mein Problem nicht relevant...
>
> Aber deine Schreibweise ist relevant.
> Kuck mal weiter: überall gleiche Styl!
>
> Ich würde dir empfehlen, ein bißchen über C-Sprache zu lesen.
>
> Du schreibst auf C so, als ob du Assembler hättest.
>
> Compiler ist kein Narr, er sieht, daß etwas nicht stimmt, und wirkt
> verrückt.
>
> Um Problem besser zu verstehen, kannst du compilierte asm ankucken. Ich
> glaube nach deinem Styl, gerade mit asm hast du kein Problem.

Also, jetzt habe ich besagte zuweisung direkt gemacht. Siehe da, kein 
Unterschied... Und wo ist "überal gleiche Styl". Deine Vorschläge helfen 
mir nicht weiter.

Autor: S. Landolt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Liegt es vielleicht daran, dass OC1A/B nicht als Ausgänge definiert 
wurden? Mir ist unklar, warum derzeit überhaupt irgendetwas zu sehen 
ist.

Autor: Maxim B. (max182)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dennis schrieb:
> Deine Vorschläge helfen
> mir nicht weiter.

Auch Vorschlag, ein C-Buch zu lesen?

Bitte begreife: je verständlicher und durchsichtiger dein Code, um so 
weniger wahrscheinlich, daß du Fehler schreibst.

Hast du schon Ergebnis in asm gekuckt?
void mfc_test (void)
{  
  unsigned int ui_i;
  unsigned char uc_i;
  
      
  for (uc_i = 0x00; uc_i <= 0xFF; uc_i++)
  {
    //OCR1AH = ((unsigned char) (ui_i >> 8));
    //OCR1AL = ((unsigned char) (ui_i & 0x00FF));
    OCR1AL = uc_i;
    //OCR1BL = uc_i;    
    //_delay_ms(25);
    for (ui_i = 0x0000; ui_i <= 0x7FFF; ui_i++);
        
  }
  
  
  for (uc_i = 0x00; uc_i <= 0xFF; uc_i++)
  {
    OCR1BL = uc_i;
    for (ui_i = 0x0000; ui_i <= 0x7FFF; ui_i++);
    //_delay_ms(25);
  }
                  
}
Kannst du bitte sagen:
1. warum willst du OSR-Register mal gesamt und mal byteweise schreiben? 
Welche Gründe hast du dafür?
2. kannst du mit einfachen Worten beschreiben, was deine Funktion machen 
sollte?

: Bearbeitet durch User
Autor: Martin H. (horo)
Datum:

Bewertung
2 lesenswert
nicht lesenswert
Die Lösung kam bereits viel weiter oben, nochmal zum Nachdenken an 
Dennis.

1. Welche Werte kann ui_c annehmen?
2. Wann bricht die Schleife ab?
3. Wie oft wird mach_irgend_was() ausgeführt?
   
  for (unsigned char uc_i = 0x00; uc_i <= 0xFF; uc_i++) {
    mach_irgend_was();
  }

Autor: Dennis (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
S. Landolt schrieb:
> Liegt es vielleicht daran, dass OC1A/B nicht als Ausgänge
> definiert
> wurden? Mir ist unklar, warum derzeit überhaupt irgendetwas zu sehen
> ist.

Entschuldige, da habe ich defines benutzt.
/********************************* MFC ******************************************************************************************************/
#define PWM_MFC1_PIN    DDRD |= (1<<DDD3);PORTD |= (1<<PORTD3)    
#define PWM_MFC1_HI      TCCR2A &= ~(1<<COM2B1);PORTD |= (1<<PORTD3)  
#define PWM_MFC1_LO      TCCR2A &= ~(1<<COM2B1);PORTD &= ~(1<<PORTD3)
#define PWM_MFC1_NORM    TCCR2A |= (1<<COM2B1)            
#define PWM_MFC1_TOGGLE    PIND |= (1<<PIND3)              

#define PWM_MFC2_PIN    DDRD |= (1<<DDD5);PORTD |= (1<<PORTD5)    
#define PWM_MFC2_HI      TCCR0A &= ~(1<<COM0B1);PORTD |= (1<<PORTD5)  
#define PWM_MFC2_LO      TCCR0A &= ~(1<<COM0B1);PORTD &= ~(1<<PORTD5)
#define PWM_MFC2_NORM    TCCR0A |= (1<<COM0B1)            
#define PWM_MFC2_TOGGLE    PIND |= (1<<PIND5)              

#define PWM_MFC3_PIN    DDRD |= (1<<DDD6);PORTD |= (1<<PORTD6)    
#define PWM_MFC3_HI      TCCR0A &= ~(1<<COM0A1);PORTD |= (1<<PORTD6)              
#define PWM_MFC3_LO      TCCR0A &= ~(1<<COM0A1);PORTD &= ~(1<<PORTD6)                
#define PWM_MFC3_NORM    TCCR0A |= (1<<COM0B1)                    
#define PWM_MFC3_TOGGLE    PIND |= (1<<PIND5)                                      

#define PWM_MFC4_PIN    DDRB |= (1<<DDB1);PORTB |= (1<<PORTB1)    
#define PWM_MFC4_HI      TCCR1A &= ~(1<<COM1A1);PORTB |= (1<<PORTB1)  
#define PWM_MFC4_LO      TCCR1A &= ~(1<<COM1A1);PORTB &= ~(1<<PORTB1)
#define PWM_MFC4_NORM    TCCR1A |= (1<<COM1A1)            
#define PWM_MFC4_TOGGLE    PINB |= (1<<PINB1)              

#define PWM_MFC5_PIN    DDRB |= (1<<DDB2);PORTB |= (1<<PORTB2)    
#define PWM_MFC5_HI      TCCR1A &= ~(1<<COM1B1);PORTB |= (1<<PORTB2)  
#define PWM_MFC5_LO      TCCR1A &= ~(1<<COM1B1);PORTB &= ~(1<<PORTB2)
#define PWM_MFC5_NORM    TCCR1A |= (1<<COM1B1)            
#define PWM_MFC5_TOGGLE    PINB |= (1<<PINB1)            
/********************************************************************************************************************************************/

Die Ausgänge funktionieren.

Autor: Dennis (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
fop schrieb:
> unsigned char uc_i;
> Das gibt oft nur eine 8 Bit breite Variable. Also eine, die Werte von 0
> bis 255 aufnehmen kann.
> Damit ist die Bedingunguc_i <= 0xFF quasi immer erfüllt. Deine Schleife
> läuft also länger als Du denkst. Um
> genau zu sein : ewig.



Martin H. schrieb:
> Die Lösung kam bereits viel weiter oben, nochmal zum Nachdenken an
> Dennis.
>
> 1. Welche Werte kann ui_c annehmen?
> 2. Wann bricht die Schleife ab?
> 3. Wie oft wird mach_irgend_was() ausgeführt?
>
>   for (unsigned char uc_i = 0x00; uc_i <= 0xFF; uc_i++) {
>     mach_irgend_was();
>   }

Ich honk, vielen Dank euch beiden!

Autor: Jack (Gast)
Datum:

Bewertung
3 lesenswert
nicht lesenswert
Dennis schrieb:
> Ich honk, vielen Dank euch beiden!

Was gemerkt? Deine Einstellung/Arroganz beeinflusst wesentlich die 
Problemlösung. Du hast es in deiner unendlichen Weisheit drei Mal 
vorgezogen die Hinweise auf das Problem zu ignorieren.

Sogar jetzt ist deine Antwort noch Arrogant. Statt allen zu danken, 
welche dir ehrlich versucht haben zu helfen, kommt diese selektive 
Danksagung.

Autor: Dennis (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke euch allen.
Beonders dem Jack!

Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
2 lesenswert
nicht lesenswert
> #define PWM_MFC1_PIN    DDRD |= (1<<DDD3);PORTD |= (1<<PORTD3)

So schreibt man kein Makros. Diese gehen bei bestimmten Konstellationen 
voll in die Hose.

Die obige Formulierung funktioniert schon bei:
    if (i_want_pwm)
        PWM_MFC1_PIN;
nicht mehr.

Dann wird nämlich vom Makro lediglich das erste Statement links vom 
Semikolen bedingt ausgeführt und das zweite unbedingt.

Also wird daraus aus Sicht des Compilers:
    if (i_want_pwm)
        DDRD |= (1<<DDD3);         // bedingt
    PORTD |= (1<<PORTD3)           // unbedingt.

... was bestimmt nicht beabsichtigt ist. Beim nächsten Projekt werden 
diese Makros einfach kopiert und man wundert sich dann, dass das 
Programm nicht das tut, was es tun soll.

Eine kleinere Verbesserung wäre, das Semikolon im Makro durch ein Komma 
zu ersetzen. Dann werden beide Kommandos bedingt ausgeführt, da sie als 
ein Statement gezählt werden.

Optimale Lösung wären:

   a) geschweifte Klammern im Makro
   b) Erweiterung auf do { ... } while.

Aber die Komma-Variante wäre hier schon hilfreich.

Autor: Maxim B. (max182)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Frank M. schrieb:
> Eine kleinere Verbesserung wäre, das Semikolon im Makro durch ein Komma
> zu ersetzen. Dann werden beide Kommandos bedingt ausgeführt, da sie als
> ein Statement gezählt werden.

Bei einigen Programmierer wird noch do{...}while(0); in Gebrauch. Dabei 
wird nach jedem Befehl "\" benutzt, etwa so:
#define KNOPF_INIT()  do{KN_PLUS_DDR &= ~(1<<KN_PLUS);\
      KN_MINUS_DDR &= ~(1<<KN_MINUS);\
      KN_M_DDR &= ~(1<<KN_M);\
      KN_F_DDR &= ~(1<<KN_F);\
      DRKN_DDR &= ~(1<<DRKN);\
      KN_PLUS_PORT |= (1<<KN_PLUS);\
      KN_MINUS_PORT |= (1<<KN_MINUS);\
      KN_M_PORT |= (1<<KN_M);\
      KN_F_PORT |= (1<<KN_F);\
      DRKN_PORT |= (1<<DRKN);}while(0);

Mir selber scheint aber die Lösung mit inline besser:
static inline void knopf_init(void){
  KN_PLUS_DDR &= ~(1<<KN_PLUS);
  KN_MINUS_DDR &= ~(1<<KN_MINUS);
  KN_M_DDR &= ~(1<<KN_M);
  KN_F_DDR &= ~(1<<KN_F);
  DRKN_DDR &= ~(1<<DRKN);
  KN_PLUS_PORT |= (1<<KN_PLUS);
  KN_MINUS_PORT |= (1<<KN_MINUS);
  KN_M_PORT |= (1<<KN_M);
  KN_F_PORT |= (1<<KN_F);
  DRKN_PORT |= (1<<DRKN);
}

Besser aus zwei Gründen:
1. es wird dem Compiler überlassen, ob er "static inline" wahrnimmt oder 
aus guten Gründen als normale Funktion übersetzt.
2. in Simulator wird Funktion Befehl nach Befehl sichtbar, während Macro 
als einen einzigen Befehl durchgeführt. So ist es leicher Fehler zu 
finden.

: Bearbeitet durch User
Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Maxim B. schrieb:
> Bei einigen Programmierer wird noch do{...}while(0); in Gebrauch.

Schrieb ich doch oben als "Optimale Lösung".

> Dabei
> wird nach jedem Befehl "\" benutzt, etwa so:
> #define KNOPF_INIT() do{KN_PLUS_DDR &= ~(1<<KN_PLUS);\
>       KN_MINUS_DDR &= ~(1<<KN_MINUS);\
>       KN_M_DDR &= ~(1<<KN_M);\
>       KN_F_DDR &= ~(1<<KN_F);\
>       DRKN_DDR &= ~(1<<DRKN);\
>       KN_PLUS_PORT |= (1<<KN_PLUS);\
>       KN_MINUS_PORT |= (1<<KN_MINUS);\
>       KN_M_PORT |= (1<<KN_M);\
>       KN_F_PORT |= (1<<KN_F);\
>       DRKN_PORT |= (1<<DRKN);}while(0);

Und schon isses wieder falsch. :(

Am Ende des Makros muss das Semikolon weg. Denn man wendet das Makro 
dann so an:
   KNOPF_INIT();              // Hier das Semikolon, nicht ins Makro!
> Mir selber scheint aber die Lösung mit inline besser:

Vollkommen ACK.

: Bearbeitet durch Moderator
Autor: Maxim B. (max182)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Frank M. schrieb:
> Am Ende des Makros muss das Semikolon weg. Denn man wendet das Makro
> dann so an:   KNOPF_INIT();              // Hier das Semikolon, nicht
> ins Makro!

Geschmackssache. Wird Semikolon in Macro, so wird Macro ohne Semikolon 
in Programm verwendet. So sieht man sofort: das ist Macro und keine 
Funktion.

Ich habe ein bißchen experimentiert mit solchen Macro. Am Ende aber 
alles auf static inline - Funktionen geändert.
Ich glaube, Macro sind für andere Gebrauch besser: um Ausgänge nach 
Bedarf anders definieren. Werden Macro als Funktionen verwendet, wird 
ganze Text weniger verständlich. Aber Ziel der Sprache von Anfang an 
gerade war, Texte verständlicher und dadurch möglichst fehlerfrei zu 
schreiben.

Aber alles Geschmackssache. Wie sagte ein Pianist: Sie dürfen auch mit 
Ihrer Nase Klavier spielen. Hauptsache Ergebnis stimmt...

: Bearbeitet durch User
Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
2 lesenswert
nicht lesenswert
Maxim B. schrieb:
> Geschmackssache.

Nein. Fehlerträchtig. Man sollte immer sicherstellen, dass Makros sich 
wie Funktionen verhalten - zumindest von der Syntax her.

Ein simples Beispiel:

Die stdio-Funktion getchar() ist in vielen UNIX-Varianten ein simples 
Makro und keine Funktion. Der Komfort ist hier aber, dass Du das als 
Programmierer überhaupt nicht wissen musst.

Autor: Maxim B. (max182)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, ich muß noch vieles lernen... Vielen Dank für Ihre Anweisung!

Also, nach while(0) von nun an schreibe ich nie mehr Semikolon!
Dann hat es auch wenig Sinn, an Regeln zu halten, solche Macros immer 
mit Großbuchstaben zu schreiben - das sollte ja wie eine Funktion 
aussehen.

: Bearbeitet durch User

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.