www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik [ATmega32] Verlassen der Schleife verlässt alle Schleifen


Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich versteh nicht warum, aber sobald er die innerste while Schleife 
durchlaufen hat, verlässt er automatisch alle anderen Schleifen auch. 
Als wäre irgendwo ein riesen break; versteckt. Die vorherige wird aber 
noch bis zum Ende durchlaufen. Also in der for () wird PORTC noch auf 0 
geschalten, und die 1. while Schleife noch 1x X erhöht. Aber er 
durchläuft while kein weiteres mal. Ich versteh nicht, warum nicht 
wieder normal die vorherigen Schleifen weiterlaufen, sondern beendet 
werden. gcc meldet keine Fehler und übertragen kann ich es normal.

Der Code dient jetzt nur zum Testen einiger 7-Segmentanzeigen. Im code[] 
Array sind die verschiedenen Segmentcodes gespeichert.
Es soll:
- eine Zahl anzeigen (while1)
- die innereste while 20x durchlaufen lassen
- in der 1. while die nächste Zahl anzeigen
- wieder innerste while, usw.
- das ganze 2x; dafür die for()

i, x und y sind deklariert als int.
for (i=0; i<2;i++) {


char code[] = {0xF9, 0x88, 0xB5, 0x9D, 0xCC, 0x5D, 0x7D, 0x89, 0xFD, 0xDD, 0x00, 0x3D, 0x23, 0x37, 0x6B, 0x79, 0x63, 0x69, 0x7D};
while (x < strlen(code)) {
PORTC = code[x];
while (y < 20) { // läuft korrekt durch
PORTD = 0x20;
_delay_ms(5);
PORTD = 0x40;
_delay_ms(5);
PORTD = 0x10;
_delay_ms(5);
PORTD = 0x80;
_delay_ms(5);
PORTD = 0x08;
_delay_ms(5);
y++;
  }
x++; // wird beim verlassen der 2. while() 1x ausgeführt und verlässt dann while()
 }
PORTC = 0x00; // wird genauso 1x ausgeführt und verlässt die for()
}

Autor: Skua (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
x = 0;
y = 0;

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alle 3 Zählvariablen sind am Anfang als 0 deklariert.

int i = 0;
int x = 0;
int y = 0;

Und solange sie kleiner als die Schleifenprüfung sind, müsste es ja 
immer laufen.

Autor: Skua (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Am Anfang reicht nicht du must vor jedem Durchlauf der x Schleife x auf 
0 setzen dito fuer y.

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie wäre es denn erstmal mit einer ordentlichen Formatierung des Codes?
Einrückungen
for (i=0; i<2;i++)
{
  char code[] = { 0xF9, 0x88, 0xB5, 0x9D, 0xCC, 0x5D, 0x7D, 0x89,
                  0xFD, 0xDD, 0x00, 0x3D, 0x23, 0x37, 0x6B, 0x79,
                  0x63, 0x69, 0x7D };
  while ( x < strlen(code) )
  {
    PORTC = code[x];
    while (y < 20)
    { // läuft korrekt durch
      PORTD = 0x20;
      _delay_ms(5);
      PORTD = 0x40;
      _delay_ms(5);
      PORTD = 0x10;
      _delay_ms(5);
      PORTD = 0x80;
      _delay_ms(5);
      PORTD = 0x08;
      _delay_ms(5);
      y++;
    }
    x++; // wird beim verlassen der 2. while() 
         // 1x ausgeführt und verlässt dann while()
  }
  PORTC = 0x00; // wird genauso 1x ausgeführt und verlässt die for()
}

Autor: Einer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hattu schön macht.

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Problem ist dass, wie Skua gesagt hat, die Variablen der inneren 
Schleifen einmal hochlaufen und dann auf ihrem Wert der Größe als die 
Bedingung der While Schleife ist Hängenbleiben. Die for Schleife läuft 
zwar Ordnungsgemäß durch aber nach dem ersten Durchlauf werden ja die 
beiden while Schleifen nicht mehr ausgeführt. du musst es also so 
machen:

for()
{
  while(x)
  {
   while(y)
     {
     }
  y=0;
  }
x=0;
}

Autor: JensM (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zusätzlich ist nicht definiert was die Funktion strlen(code) 
zurückliefert.

strlen sucht nach einem 0x00 als Endekennung eines Strings.
Dies ist im char[] nicht definiert und was nach dem Array kommt kann 
niemand sagen.

In diesem Fall wäre es besser mit sizeof() zu arbeiten, da dies der 
Compiler schon zur Compilierung auflösen kann und nicht zur Laufzeit
bei jedem Schleifendurchlauf berechnet werden muss.

Ich mache sowas gerne in folgender Form:

while (x < (sizeof(code) / sizeof(char))) {

Das kann der Compiler komplett auflösen und wenn sich z.B.
Datentypen ändern (nicht in diesem Fall, aber wenn statt char Strukturen 
vorhanden sind) muss keine Anpassung gemacht werden.

Autor: Bernhard M. (boregard)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
JensM wrote:
> Zusätzlich ist nicht definiert was die Funktion strlen(code)
> zurückliefert.
>
> strlen sucht nach einem 0x00 als Endekennung eines Strings.
> Dies ist im char[] nicht definiert und was nach dem Array kommt kann
> niemand sagen.
>
ist doch definiert:
  char code[] = { 0xF9, 0x88, 0xB5, 0x9D, 0xCC, 0x5D, 0x7D, 0x89,
                  0xFD, 0xDD, 0x00, <-----!!!
> In diesem Fall wäre es besser mit sizeof() zu arbeiten, da dies der
> Compiler schon zur Compilierung auflösen kann und nicht zur Laufzeit
> bei jedem Schleifendurchlauf berechnet werden muss.
>
> Ich mache sowas gerne in folgender Form:
>
> while (x < (sizeof(code) / sizeof(char))) {
>
> Das kann der Compiler komplett auflösen und wenn sich z.B.
> Datentypen ändern (nicht in diesem Fall, aber wenn statt char Strukturen
> vorhanden sind) muss keine Anpassung gemacht werden.

aber ansonsten hast Du vollkommen recht, zumal bei der 0x00 mitten im 
String dieser nicht vollständig abgearbeitet wird...

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jetzt funktionierts :-D Ich bin wohl noch zuviel PHP verwöhnt.

Aber das mit dem 0x00 im Array ist/war mir neu. Lerne ich wieder was 
dazu.

Thx an alle.

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.