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


von Gast (Gast)


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.
1
for (i=0; i<2;i++) {
2
3
4
char code[] = {0xF9, 0x88, 0xB5, 0x9D, 0xCC, 0x5D, 0x7D, 0x89, 0xFD, 0xDD, 0x00, 0x3D, 0x23, 0x37, 0x6B, 0x79, 0x63, 0x69, 0x7D};
5
while (x < strlen(code)) {
6
PORTC = code[x];
7
while (y < 20) { // läuft korrekt durch
8
PORTD = 0x20;
9
_delay_ms(5);
10
PORTD = 0x40;
11
_delay_ms(5);
12
PORTD = 0x10;
13
_delay_ms(5);
14
PORTD = 0x80;
15
_delay_ms(5);
16
PORTD = 0x08;
17
_delay_ms(5);
18
y++;
19
  }
20
x++; // wird beim verlassen der 2. while() 1x ausgeführt und verlässt dann while()
21
 }
22
PORTC = 0x00; // wird genauso 1x ausgeführt und verlässt die for()
23
}

von Skua (Gast)


Lesenswert?

x = 0;
y = 0;

von Gast (Gast)


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.

von Skua (Gast)


Lesenswert?

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

von Matthias L. (Gast)


Lesenswert?

Wie wäre es denn erstmal mit einer ordentlichen Formatierung des Codes?
Einrückungen
1
for (i=0; i<2;i++)
2
{
3
  char code[] = { 0xF9, 0x88, 0xB5, 0x9D, 0xCC, 0x5D, 0x7D, 0x89,
4
                  0xFD, 0xDD, 0x00, 0x3D, 0x23, 0x37, 0x6B, 0x79,
5
                  0x63, 0x69, 0x7D };
6
  while ( x < strlen(code) )
7
  {
8
    PORTC = code[x];
9
    while (y < 20)
10
    { // läuft korrekt durch
11
      PORTD = 0x20;
12
      _delay_ms(5);
13
      PORTD = 0x40;
14
      _delay_ms(5);
15
      PORTD = 0x10;
16
      _delay_ms(5);
17
      PORTD = 0x80;
18
      _delay_ms(5);
19
      PORTD = 0x08;
20
      _delay_ms(5);
21
      y++;
22
    }
23
    x++; // wird beim verlassen der 2. while() 
24
         // 1x ausgeführt und verlässt dann while()
25
  }
26
  PORTC = 0x00; // wird genauso 1x ausgeführt und verlässt die for()
27
}

von Einer (Gast)


Lesenswert?

hattu schön macht.

von Martin (Gast)


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;
}

von JensM (Gast)


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.

von Bernhard M. (boregard)


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:
1
  char code[] = { 0xF9, 0x88, 0xB5, 0x9D, 0xCC, 0x5D, 0x7D, 0x89,
2
                  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...

von Gast (Gast)


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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.