mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik sei() verhindert Programmausführung


Autor: Stefan S. (novafly)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Morgen,
in meinem Projekt sollen verschiedene Zeiten mit dem Timer0 des Atmega32 
gehandelt werden. Nun ist es so, dass wenn ich die globale 
Interruptfreigabe aktiviere (sei();) mein Programm sich genau an dieser 
Stelle aufhängt - sprich, es wird nicht weiter ausgeführt.

Kommentiere ich sei(); aus, läuft das Programm ganz normal bis zum Ende. 
Die ISR ist meiner Ansicht nach korrekt, wobei hier lediglich drei 
Variablen hochgezählt werden. Die Deklaration der Variablen in der ISR 
sind alle volatile uint8_t !

Anbei einmal der Code der main:
#include "dogm163_spi.h"
#include "ADC_conf.h"
#include "mydefs.h"
#include "timer_config.h"


#include <avr/interrupt.h>


FILE lcd_str = FDEV_SETUP_STREAM(write_char, NULL, _FDEV_SETUP_WRITE);



//------- Interrupt Service Routine für Timer0 -----------------



ISR(TIMER0_COMP_vect)
{

  sysTime++;
  LCD_refreshTime++;
  LCD_startTime++;

}


int main()
{




// ------------------ Initialisierungen -------------------------

adc_init();        // ADC initialisieren
SPI_Init();        // SPI initialisieren


display_init();      // LCD initialisieren
set_contrast (11);    // LCD Kontrast setzen

stderr = &lcd_str;

  
// ------------------------- I/O Funktionen ---------------------


DDRD = 0x20;


//-------------------- Interruptparameter ------------------------



OCR0  = 125;            // Compare Register mit Wert für Interrupt bei 10ms blegen - 0% Fehler  
TIMSK |= (1<<OCIE0);        // Timer 0 Output Compare Interrupt freigeben
TCCR0 |=   (1<<CS00) | (1<<CS01);  // Mode: Normal, Timer 0 Takt: CLK / 64  
TIFR  |= (1<<OCF0);          // Output Compare Flag


// -------------------------- Hauptprogramm ---------------------

    
    // ------------------------ Startbildschirm --------------- 
        
      
      PORTD |= LCD_backLightOn;        // Hintergrundbeleuchtung ein
      
      clear_home();
      set_cursor(0);
      set_doubleheight (0);
      fprintf(stderr, "LDO V_Regulator");
      set_cursor(16);
      fprintf(stderr, "Version 1.0");

      
      _delay_ms(2000);

sei();              // globale Interruptfreigabe



    // --------------------- Temperaturmessung -----------------







    // ---------------- Grundmenue 1 -----------------------------
          
      mergVin = 5.5;         // Dummy fuer Anzeige  
          
      clear_home();
      set_doubleheight (0);
      set_cursor(0);
      vfprintf(stderr, "U_in: %0.2fV", &mergVin);
      set_cursor(16);
      vfprintf(stderr, "Kapaz: %0.2f mAh", &mergVin);
      set_cursor(33);
      vfprintf(stderr, "Temp1: %0.1f C", &mergVin);

}


Ich übersehe bestimmt irgendwas, komme aber seit ein paar Tagen nicht 
drauf. Vielleicht hat mir jemand von euch einen Tipp? :)

Danke im Voraus für die Hilfe!


Gruß
Stefan

Autor: Lehrmann Michael (ubimbo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan S. schrieb:
> Ich übersehe bestimmt irgendwas, komme aber seit ein paar Tagen nicht
> drauf. Vielleicht hat mir jemand von euch einen Tipp? :)

Ja. Die Endlosschleife fehlt ... Der AVR fährt ja ständig in den Reset 
(sobald das Hauptprogramm einmal durch ist). Trivialste Grundlage. 
Empfehlung: AVR-Tutorial machen!

Viel Erfolg

Autor: Charly B. (charly)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
i hab von C keine Ahnung (echte Programmierer meiden C :) )
aber laeuft es mit einer leeren Interruptroutine ?
was ist mit dem Stackpointer ???

vlG & viel erfolg
Charly

Autor: Stefan S. (novafly)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Michael,
dass die while(1) derzeit fehlt ist mir schon klar. Das hat aber den 
Grund, dass die erste LCD-Ausgabe einen Startbildschirm darstellt, 
welcher für 2sec nach dem Einschalten angezeigt wird. Anbei nochmals der 
Code, diesmal mit einer Wartezeit, welche mit der ISR generiert bzw. 
verglichen wird. Hier also nochmals der Codeabschnitt, welcher so nicht 
funktioniert (auf dem LCD wird überhaupt nichts angezeigt, die SPI wird 
bei Verwendung von "sei();" auch nicht initalisiert (Keine Zeichen auf 
dem LCD während der Initialisierung)

Anbei der zu verwendende Code:

[c]
#include "dogm163_spi.h"
#include "ADC_conf.h"
#include "mydefs.h"
#include "timer_config.h"


#include <avr/interrupt.h>


FILE lcd_str = FDEV_SETUP_STREAM(write_char, NULL, _FDEV_SETUP_WRITE);



//------- Interrupt Service Routine für Timer0 -----------------



ISR(TIMER0_COMP_vect)
{

  sysTime++;
  LCD_refreshTime++;
  LCD_startTime++;

}


int main()
{




// ------------------ Initialisierungen -------------------------

adc_init();        // ADC initialisieren
SPI_Init();        // SPI initialisieren


display_init();      // LCD initialisieren
set_contrast (11);    // LCD Kontrast setzen

stderr = &lcd_str;


// ------------------------- I/O Funktionen ---------------------


DDRD = 0x20;


//-------------------- Interruptparameter ------------------------



OCR0  = 125;            // Compare Register mit Wert für Interrupt bei 
10ms blegen - 0% Fehler
TIMSK |= (1<<OCIE0);        // Timer 0 Output Compare Interrupt 
freigeben
TCCR0 |=   (1<<CS00) | (1<<CS01);  // Mode: Normal, Timer 0 Takt: CLK / 
64
TIFR  |= (1<<OCF0);          // Output Compare Flag
sei();                // globale Interruptfreigabe




// -------------------------- Hauptprogramm ---------------------


    // ------------------------ Startbildschirm ---------------


      PORTD |= LCD_backLightOn;        // Hintergrundbeleuchtung ein

      clear_home();
      set_cursor(0);
      set_doubleheight (0);
      fprintf(stderr, "LDO V_Regulator");
      set_cursor(16);
      fprintf(stderr, "Version 1.0");


    while(LCD_startTime < LCD_startWait) { }  // Wartezeit 2sec

[c/]

die Zeile mit "_delay_ms()" aus dem ersten Code war nur zum Testen! 
Sorry, wenn das jetzt Verwirrung stiftet.

@ Charly:
die ISR ist ja nicht leer. In der Routine werden nur drei Variablen 
inkrementiert, welche dann wieder zur Überprüfung der 
Startbildschirmzeit hergenommen werden.


Viele Grüße
Stefan

Autor: Stefan S. (novafly)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Michael,
dass die while(1) derzeit fehlt ist mir schon klar. Das hat aber den 
Grund, dass die erste LCD-Ausgabe einen Startbildschirm darstellt, 
welcher für 2sec nach dem Einschalten angezeigt wird. Anbei nochmals der 
Code, diesmal mit einer Wartezeit, welche mit der ISR generiert bzw. 
verglichen wird. Hier also nochmals der Codeabschnitt, welcher so nicht 
funktioniert (auf dem LCD wird überhaupt nichts angezeigt, die SPI wird 
bei Verwendung von "sei();" auch nicht initalisiert (Keine Zeichen auf 
dem LCD während der Initialisierung)

Anbei der zu verwendende Code:
#include "dogm163_spi.h"
#include "ADC_conf.h"
#include "mydefs.h"
#include "timer_config.h"


#include <avr/interrupt.h>


FILE lcd_str = FDEV_SETUP_STREAM(write_char, NULL, _FDEV_SETUP_WRITE);



//------- Interrupt Service Routine für Timer0 -----------------



ISR(TIMER0_COMP_vect)
{

  sysTime++;
  LCD_refreshTime++;
  LCD_startTime++;

}


int main()
{




// ------------------ Initialisierungen -------------------------

adc_init();        // ADC initialisieren
SPI_Init();        // SPI initialisieren


display_init();      // LCD initialisieren
set_contrast (11);    // LCD Kontrast setzen

stderr = &lcd_str;

  
// ------------------------- I/O Funktionen ---------------------


DDRD = 0x20;


//-------------------- Interruptparameter ------------------------



OCR0  = 125;            // Compare Register mit Wert für Interrupt bei 10ms blegen - 0% Fehler  
TIMSK |= (1<<OCIE0);        // Timer 0 Output Compare Interrupt freigeben
TCCR0 |=   (1<<CS00) | (1<<CS01);  // Mode: Normal, Timer 0 Takt: CLK / 64  
TIFR  |= (1<<OCF0);          // Output Compare Flag
sei();                // globale Interruptfreigabe




// -------------------------- Hauptprogramm ---------------------

    
    // ------------------------ Startbildschirm --------------- 
        
      
      PORTD |= LCD_backLightOn;        // Hintergrundbeleuchtung ein
      
      clear_home();
      set_cursor(0);
      set_doubleheight (0);
      fprintf(stderr, "LDO V_Regulator");
      set_cursor(16);
      fprintf(stderr, "Version 1.0");

      
    while(LCD_startTime < LCD_startWait) { }  // Wartezeit 2sec


die Zeile mit "_delay_ms()" aus dem ersten Code war nur zum Testen! 
Sorry, wenn das jetzt Verwirrung stiftet.

Also nochmal das Problem zusammengefasst:

1) setze ich sei(); vor die LCD Ausgabe, wird mein Display nicht mehr 
initialisiert und es wird nichts angezeigt!

2) setze ich sei(); nach der LCD Ausgabe, funktioniert soweit die Init 
des LCDs und es wird auch der entspr. Text ausgegeben. Allerdings hängt 
er sich dann an der while-schleife auf....!


@ Charly:
die ISR ist ja nicht leer. In der Routine werden nur drei Variablen 
inkrementiert, welche dann wieder zur Überprüfung der 
Startbildschirmzeit hergenommen werden.


Viele Grüße
Stefan

Autor: Thomas K. (muetze1)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du die Variablen mit volatile gekennzeichnet? Ansonsten optimiert 
er dir deine while Schleife auf eine Endlosschleife, da sich die 
Variablen nicht innerhalb der While ändern können...

Autor: MitLeser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das
TCCR0 |=   (1<<CS00) | (1<<CS01);  // Mode: Normal, Timer 0 Takt: CLK / 
64
reicht nicht.
Es muss auch der Timer auf CTC-Mode eingestellt werden. siehe Datasheet!

Autor: Stefan S. (novafly)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Thomas,
die Variablen sind als "volatile" deklariert, da sonst die main ja nicht 
mitbekommt, dass sich diese ändern. Die Optimierung hab ich im 
AVR-Studio für die Tests ausgeschalten.

Das WGM01-Bit im TCCR0 hab ich tatsächlich vergessen zu setzen, macht 
aber leider auch keinen Unterschied bezüglich der nicht vorhanden 
Funktion :( Irgendwo spuckt mir die globale Interruptfreigabe rein und 
ich find es nicht. Nur alle Zeiten mit Delays aufzuziehen kommt nicht in 
Frage :)

Ich schreib den Code jetzt mal auf ein Minumum zusammen und deklariere 
alle verwendeten Variablen in der main.c (und nicht über Header). Ich 
weiß, dass das keinen Unterschied machen sollte, aber eventuell geht mir 
ja noch ein Licht auf ;)

Für weitere Ideen bin ich immer dankbar.


Viele Grüße
Stefan

Autor: Peter Diener (pdiener) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann es sein, dass der Overflow-Interrupt ausgelöst wird, wenn der Timer 
Compare auslöst? Das würde ich mal genau im Datenblatt nachlesen. Wenn 
für den Overlow-Interrupt kein gültiger Handler definiert ist, wird ein 
Reset ausgelöst.

Grüße,

Peter

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wird noch irgendein anderer Interrupt eingeschaltet? Wenn der bei sei() 
aufgibt, dann wird möglicherweise ein Interrupt ausgelöst, für den es 
keinen Handler gibt.

Autor: Peter Diener (pdiener) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bleibt die Programmausführung eigentlich bei sei() stehen, oder macht 
der Controller einen Reset?

Edit zu meinem vorherigen Post: Der Overflow-Interrupt ist ja nicht 
sichtbar bzw. absichtlich eingeschaltet.

Autor: sven (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würde keine LCD-Operation in der ISR ausführen!
Evtl. gibt es dort auch Delayschleifen welche Programausführung 
stören...

Autor: Peter Diener (pdiener) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Timer muss auf CTC gestellt werden, wie MitLeser bereits geschrieben 
hat. Nur dann ist OCR0 der TOP-Wert.
Also
TCCR0 |= (1<<CS00) | (1<<CS01) | (1<<WGM01);

Das würde aber nur ein falsches Timing erklären, nicht den genannten 
Effekt.
Ist der richtige Prozessor definiert?

Grüße,

Peter

Autor: Peter Diener (pdiener) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ich würde keine LCD-Operation in der ISR ausführen!
>Evtl. gibt es dort auch Delayschleifen welche Programausführung
>stören...

ISR(TIMER0_COMP_vect)
{
  sysTime++;
  LCD_refreshTime++;
  LCD_startTime++;
}

@sven: Welche LCD-Operationen denn? Das sind nur drei normale Variablen.

Autor: sven (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh, sorry,
beim Überfliegen sah ich 'LCD_refr...' und 'LCD_star...' und nahm an 
dass es Funktionen sind.

Autor: Stefan S. (novafly)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Huch... kaum ist man 10min beim Spülen schon wieder jede Menge Postings. 
Versuche mal alles zu beantworten...

@ Peter
Das Programm bleibt stehen, es gibt keinen Reset (würde man an der 
erneuten Init des SPI bzw. des Displays sehen). Der Overflow ist, wie du 
sagst, nicht aktiviert, daher dürfte auch kein Handler nötig sein. Zum 
Testen hab ich trotzdem einen leeren Handler geschrieben, bringt aber 
keine Veränderung.. :/

Es ist der korrekte Prozessertyp sowie die richtige Taktfrequenz 
eingetragen. Ich kann mir nur vorstellen, dass sei(); sich mit 
irgendeiner anderen Funktion in die Quere kommt. Ich hab das Programm 
Schritt für Schritt im Simulator ablaufen lassen. Er springt korrekt in 
jede Funktion, führt sie aus und kehrt nach main zurück. Bei sei(); ist 
dann Ende der Fahnenstange.

@ Sven
Ich muss sehen wie ich die ganzen LCD-Ausgaben (Menüs) später handle um 
möglichst wenig Zeit und Rechenleistung zu verbraten. Klar kann ich die 
erste Ausgabe auch in die ISR packen, aber es ist, wie gesagt, nur ein 
Startbildschirm, der ein einziges Mal aufgerufen werden soll.

Ich hab heute abend noch etwas Zeit. Werde die Interruptgeschicht ohne 
die adc_init und die Displaygeschichte probieren. Hab noch ein paar 
Status-LEDs auf meinem Projekt und werde die für die Ausgabe 
missbrauchen.

Danke euch für das rege Feedback. Werde weiter berichten....! :)

Gruß
Stefan

Autor: Charly B. (charly)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan S. schrieb:

> @ Charly:
> die ISR ist ja nicht leer. In der Routine werden nur drei Variablen
> inkrementiert, welche dann wieder zur Überprüfung der
> Startbildschirmzeit hergenommen werden.

ja das hab i schon gesehen, soviel ahnung hab i dann doch von C

ich meinte du sollst eine 'leere' ISR 'einbauen' dh.
an der ISR Adresse steht ein iret

kannste mal von der 'minimalversion' den hexfile posten ?

was ist mit den SP ?

vlG
Charly

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Schritt für Schritt im Simulator ablaufen lassen. Er springt korrekt in
> jede Funktion, führt sie aus und kehrt nach main zurück. Bei sei(); ist
> dann Ende der Fahnenstange.

Umso wichtier, dass du
* vollständigen Code postest.
  Und zwar auch die Funktionen, die du bisher nicht gezeigt hast.
  Also ADC_init, spi_init und all die anderen
* in deine main() eine Hauptschleife einbaust, in der sich die
  Programmausführung dann fängt.

Autor: Stefan S. (novafly)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Abend zusammen,
melde mich leider etwas später als geplant aber ich hab den Fehler 
gefunden!

Zuersteinmal lag es nicht an sei(); , sondern am 
Inititialisierungsaufruf für meinen ADC, also meine Mainfunktion 
"adc_init();) !

Dieser sieht wie folgt aus (ADC_config.h):
void adc_init(void)
{
  
  ADMUX =   (1<<REFS0);  // 5V externe Rev

  ADCSRA =  (1<<ADPS1) | 1<<ADPS2  // Frequenzteiler von 64
      | (1<<ADIE)       // Interrupt am Ende der Wandlung aktivieren
      | (1<<ADEN)        // ADC einschalten
      | (1<<ADSC);      // 1 Wandlung zur Init durchführen
  
}


Ich Hirsch führe am Schluss der Initialisierung eine einzige Wandlung 
des ADC0 durch, aber im Hauptprogramm warte ich nicht auf das Ende der 
Wandlung (Interruptflag bei Beendigung der Wandlung)!!

Das sieht man sehr schön hier bei den Initalisierungen (main.c):
int main()
{
  stderr = &lcd_str;    // Übergabe für LCD Ausgabe



  // ------------------ Initialisierungen -------------------------

  SPI_Init();        // SPI initialisieren
  display_init();      // LCD initialisieren
  set_contrast (11);    // LCD Kontrast setzen

  adc_init();        // ADC initialisieren


  
  // ------------------------- I/O Funktionen ---------------------

  DDRD |=0x20;


  //-------------------- Interruptparameter ------------------------


  TCCR0 |= (1<<CS02) | (1<<CS00) | (1<<WGM01);  // Mode: Normal, Timer 0 Takt: CLK / 64, CTS-Mode
  OCR0  = 125;                  // Compare Register mit Wert für Interrupt bei 10ms blegen - 0% Fehler  
  TIMSK |= (1<<OCIE0);              // Timer 0 Output Compare Interrupt freigeben
  sei();                      // globale Interruptfreigabe


    
    // ------------------------ Startbildschirm --------------- 
        
      
      PORTD |= LCD_backLightOn;        // Hintergrundbeleuchtung ein
      
      clear_home();
      set_cursor(0);
      set_doubleheight (0);
      fprintf(stderr, "LDO V_Regulator");
      set_cursor(16);
      fprintf(stderr, "Version 1.0");

    
    while(LCD_startTime < 188) { }      // Wartezeit 3s für Startbildschirm
    
   

    // --------------------- Temperaturmessung -----------------



Nehme ich die "Initialisierungswandlung" raus bzw. warte ich auf das 
entsprechende Flag nach der adc_init(); geht das ganze wunderbar! Was 
mir allerdings noch unklar ist, ist der Effekt, dass wenn ich sei(); an 
eine andere Position im Programmcode verschoben habe, das ganz bis 
dorthin "funktioniert" hat. Wohl ein unglückliches Zusammenspiel....... 
!?

Ich danke allen, die sich bei dem Thema beteiligt haben und wie 
Karl-Heinz gesagt hat: besser mal den ganzen Code posten! :)

Viele Grüße
Stefan

p.s die Codekommentare müssen noch angepasst werden, stimmen gerade 
nicht ganz zu den Registerzuständen....

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan S. schrieb:

> Dieser sieht wie folgt aus (ADC_config.h):
>
> [c]
> void adc_init(void)
> {
>
>   ADMUX =   (1<<REFS0);  // 5V externe Rev
>
>   ADCSRA =  (1<<ADPS1) | 1<<ADPS2  // Frequenzteiler von 64
>       | (1<<ADIE)       // Interrupt am Ende der Wandlung aktivieren

Man gibt NIEMALS einen Interrupt frei, für den man keine ISR hat.
NIEMALS!

Denn sobald mit einem sei die Interrupt Behandlung global freigegeben 
wird, wird die ISR aufgerufen. Ob du sie selber implementiert hast oder 
nicht.
Nur: für den Fall, dass du sie nicht selber implementiert hast, kommt 
die gcc-Default Routine zum Einsatz, welche macht: den Prozessor 
resetten.


> entsprechende Flag nach der adc_init(); geht das ganze wunderbar! Was
> mir allerdings noch unklar ist, ist der Effekt, dass wenn ich sei(); an
> eine andere Position im Programmcode verschoben habe, das ganz bis
> dorthin "funktioniert" hat. Wohl ein unglückliches Zusammenspiel.......
> !?

Nicht wirklich.
Ist alles erklärbar.

Und genau aus dem Grund hatte ich auch nach komplettem Code gefragt. Ich 
wollte den durchsuchen ob du irgendwo einen Interrupt freigibst für den 
du keine ISR hast. Denn wenn nach einem sei() seltsame Dinge passieren, 
hat man mit der Hypothese einer fehlenden ISR eine 95% 
Trefferwahrscheinlichkeit.

Autor: Stefan S. (novafly)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Karl-Heinz,
mir ist inzwischen schon klar was du meinst. Ich war gedanklich einfach 
auf der falschen Baustelle, nämlich ausschließlich bei den Timern in 
Verbindung mit der globalen Interruptfreigabe, unterwegs und hab die 
Geschichte mit der ADC Initialisierung vollkommen vergessen.

Wie gesagt, danke nochmals an alle, die sich der Sache angenommen haben 
:) Hoffe, es wird weiterhin keine solchen blöden Fehler geben ;)

Gruß
Stefan

Autor: Loonix (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan S. schrieb:
> Zuersteinmal lag es nicht an sei();

Deine Feststellung rundet dies schöne Beispiel für eine fehlgeschlagene 
Thread-Titel-Auswahl ab. Gerade eine der wichtigsten Funktionen der libc 
als Schuldigen auszumachen, tztztz...

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.