Forum: Mikrocontroller und Digitale Elektronik STM32 verweigert schleifen?!


von Flo (Gast)


Lesenswert?

Hallo zusammen,
ich scheine wohl die seltsamstem Fehler mit meinem
STM32 zu haben.

so versuche ich eine dämlich schleife
1
int =0;
2
3
for (i=0; ende == 1; i++)
4
{
5
      if (i == 5)
6
        {
7
         GPIO_SetBits(GPIOE,GPIO_Pin_5);
8
         ende = 1;
9
        }
10
}

das ist eine einfach blöde schleife in der main()
an der der compiler auch nichts auszusetzen hat,
aber es tut sich nichts!

mach ich eine einfach abfrage außerhalb einer schleife z.B.
1
int i = 5;
2
3
if (i == 5)
4
    {
5
    GPIO_SetBits(GPIOE,GPIO_Pin_5);
6
    }

funktionierst tadellos

was kann denn sein?
ich verstehs einfach nicht
von Oliver J. (skriptkiddy)


Lesenswert?

Hat ende vielleicht schon den Wert 1?
von (prx) A. K. (prx)


Lesenswert?

Bitte den echten Code, nicht etwas Nachempfundenes. Denn
  int =0;
steht da bestimmt nicht.
von (prx) A. K. (prx)


Lesenswert?

Steht da vielleicht so etwas wie:

int ende=0;
i=0;
while (ende == 1) ...

denn genau das ist die for-Schleife.
von Guest (Gast)


Lesenswert?

> for (i=0; ende == 1; i++)

Meinten Sie: for (i=0; ende != 1; i++) ?
von Flo (Gast)


Lesenswert?

also das ist meine main momentan,
unwichtige sachen habe ich auskommentiert und hier nicht reingesetzt!

das da unten geht zum beispiel auch nicht, warum auch immer

achja, und ihr könnt mich dutzen ;)
1
int main(void)
2
{ 
3
#ifdef DEBUG debug();
4
#endif
5
6
int ende = 0;
7
int i =0;
8
9
/*
10
 CCR1_Val =&CCR1;
11
 CCR2_Val =&CCR2;
12
 CCR3_Val =&CCR3;
13
 CCR4_Val =&CCR4;
14
 GPSKorrektur = &GPSK;
15
*/
16
17
RCC_Configuration();
18
NVIC_Configuration();
19
//NVIC1();
20
GPIO_Configuration();
21
//TIM_OUT_Configuration(CCR1_Val, CCR2_Val, CCR3_Val, CCR4_Val);
22
//TIM_IN_Configuration();
23
UART_Configuration();
24
25
26
27
28
29
30
while (1) 
31
  {
32
   
33
  for (i=0; ende == 1; i++)
34
    {
35
        if (i == 5)
36
          {
37
           GPIO_SetBits(GPIOE,GPIO_Pin_5);
38
           ende = 1;
39
          }
40
    }
41
  }   
42
}
von Guest (Gast)


Lesenswert?

Wie gesagt, mit ende!=1 wird es funktionieren.
von Flo (Gast)


Lesenswert?

oh mann, das war wohl einwenig zuviel desguten heute -_-

hab einen richtig fetten denkfehler gehabt,
wenn etwas ungleich ist, dann ist es ja wahr -_-
schön das man sich mit sowas dann 3std auseinandersetzt

danke für den hinweis
von Max (Gast)


Lesenswert?

Hmm? Glaub morgen denkst nochmal drüber nach.
Wenn eine Bedingung erfüllt ist (sie führt nicht zum Widerspruch), dann 
ist sie wahr.


Es scheint mir eher, dass du hier Schleifenbedingung und 
Abbruchbedingung durcheinander bringst. Bei for (<a>;<b>;<c>) steht b 
für die Bedingung, die nötig ist um die Schleife zu wiederholen, nicht 
jedoch um auszutreten.
von Icke (Gast)


Lesenswert?

Schleifen kann man ganz einfach mit einem break verlassen :-)
von High Performer (Gast)


Lesenswert?

>  for (i=0; ende == 1; i++)
>    {
>        if (i == 5)
>          {
>           GPIO_SetBits(GPIOE,GPIO_Pin_5);
>           ende = 1;
>          }
>    }

Programmierer, die mir solchen Code abliefern, bekommen im Allgemeinen 
die Höchststrafe ;-) Gründe: Der Code ist so kompliziert wie nur 
möglich. Eine For-Schleife mit Abbruchbedingung, die auch noch vom 
Schleifenzähler abhängt im Schleifenrumpf. Was soll das? Aber scheinbar 
ist der Programmierer ja bereits selbst über dieses Konstrukt 
gestolpert.

Just my 2 cents.
von Flo (Gast)


Lesenswert?

huch, da haben ja welche noch geantwortet :)

bin da ein laie,
entwickel noch das feingefühl dafür,
ich sollte mir nochmal die unterlagen rausholen,
weil ich schön regelmäßig dran hängen bleibe :P
von Joe-C (Gast)


Lesenswert?

Moin,

Ich gehe mal davon aus, das mit "funktionieren Schleife" und ähnlichem 
gemeint ist, dass der Pin5 am GPIOE auf High geht.
Das würde ja nur passieren, wenn i==5 ist. Deshalb soll i in der 
Schleife ja nach oben gezählt werden (mit i++).
1
for (i=0; ende == 1; i++)
2
{
3
  if (i == 5) {
4
    GPIO_SetBits(GPIOE,GPIO_Pin_5);
5
    ende = 1;
6
  }
7
}
Da müsste folgendes Passieren:
- Start der Schleife i wird auf 0 gesetzt
- if bedingung (i==5) nicht erfüllt, da i==0
- Schleife wird beendet, da die Wiederholbedingung ende==1 nicht erfüllt 
ist

Dass es so nicht geht, wurde ja schon beschrieben. Nun zur nächten 
Variante...
1
for (i=0; ende != 1; i++)
2
{
3
  if (i == 5) {
4
    GPIO_SetBits(GPIOE,GPIO_Pin_5);
5
    ende = 1;
6
  }
7
}
Da müsste folgendes Passieren:
- Start der Schleife i wird auf 0 gesetzt
- if bedingung (i==5) nicht erfüllt, da i==0
- nächster schleifendurchlauf, i dann 1
- if bedingung (i==5) nicht erfüllt, da i==1
- nächster schleifendurchlauf, i dann 2
- if bedingung (i==5) nicht erfüllt, da i==2
- nächster schleifendurchlauf, i dann 3
- if bedingung (i==5) nicht erfüllt, da i==3
- nächster schleifendurchlauf, i dann 4
- if bedingung (i==5) nicht erfüllt, da i==4
- nächster schleifendurchlauf, i dann 5
- if bedingung (i==5) erfüllt, Set GPIOE_Pin5, ende dann 1
- Schleife wird beendet, da die Wiederholbedingung ende!=1 nicht erfüllt 
ist

Hier ein anderes Beispiel.
1
for (i=0; i < 6; i++)
2
{
3
  if (i == 2) {
4
    i++;
5
    continue; //schleifendurchlauf abbrechen und nächsten durchlauf starten
6
  }
7
  if (i == 5) {
8
    GPIO_SetBits(GPIOE,GPIO_Pin_5);
9
    break; //schleifendurchlauf abbrechen und schleife verlassen
10
  }
11
}
Da müsste folgendes Passieren:
- Start der Schleife i wird auf 0 gesetzt
- if bedingung (i==2) nicht erfüllt, da i==0
- if bedingung (i==5) nicht erfüllt, da i==0
- nächster schleifendurchlauf, i dann 1
- if bedingung (i==2) nicht erfüllt, da i==1
- if bedingung (i==5) nicht erfüllt, da i==1
- nächster schleifendurchlauf, i dann 2
- if bedingung (i==2) erfüllt, i dann 3, nächster schleifendurchlauf, i 
dann 4
- if bedingung (i==2) nicht erfüllt, da i==4
- if bedingung (i==5) nicht erfüllt, da i==4
- nächster schleifendurchlauf, i dann 5
- if bedingung (i==2) nicht erfüllt, da i==5
- if bedingung (i==5) erfüllt, Set GPIOE_Pin5, Schleife wird beendet
(obwohl die schleife weiter laufen werden würde, solange i<9 ist, wird i 
nicht höher als 5, da die Schleife mit break verlassen wurde. Einen 
Schleifendurchlauf mit i==3 gibt es hier auch nicht.)

Ich hoffe, es hilft weiter...

MFG
von Peter D. (peda)


Lesenswert?

High Performer schrieb:
> Programmierer, die mir solchen Code abliefern, bekommen im Allgemeinen
> die Höchststrafe ;-)

Sehe ich auch so.
Der besseren Verstehbarkeit und vor allem der geringeren 
Fehleranfälligkeit wegen, sollten alle 3 Ausdrücke im for die gleiche 
Variable benutzen.

Nur weil man einen 32Bit Boliden benutzt, muß man nicht unnütz mit 
Variablen um sich schmeißen.
Insbesondere Variablen, die 1000 Zeilen vorher gesetzt werden, verwirren 
Dich nur selbst.
Jede Variable muß einen triftigen Grund haben, warum Du sie erzeugst.

Kleiner Code ist oftmals auch einfacher zu verstehen.


Peter
von Flo (Gast)


Lesenswert?

Danke Joe-C für die ausführliche Erklärung.
Sowas hilft echt weiter :)
Werde mal meinen Quellcode dahingegen mal optimieren ;)

Peter, ich hätte auch den Code reingepostet,
der ist bloß inzwischen überdeminsional. :P
von Peter D. (peda)


Lesenswert?

Ich schreibe Schleifen gerne abwärts zählend, dann sehe ich sofort im 
ersten Ausdruck die Anzahl der Durchläufe.
Auch lege ich die Schleifenvariable im for an, dann weiß der Compiler, 
sie ist danach wieder ungültig.
1
  for( uint8_t i = 123; i; i-- ){
2
    // mache was
3
  }

Ich finde das am besten lesbar und am wenigsten fehleranfällig.


Peter
von Flo (Gast)


Lesenswert?

das habe ich auch schon versucht,

nur witzigerweise verweigert mein compiler das,
warum auch immer?!

so muss ich nach funktionsaufruf,
eine lokale variable erstellen,
mit der gearbeitet werden kann.


ich werds mal gleich nochmal ausprobieren,
und die fehlermeldung posten
von Flo (Gast)


Lesenswert?

meinte nicht das runterzählen,
sondern die variable innerhalb des for aufrufes zu initialisieren
von H.Joachim S. (crazyhorse)


Lesenswert?

Will mein Compiler auch nicht, nimmt nur Variablen, die direkt am Anfang 
der Funktion erzeugt werden.

void test (){
uint8_t i;
for (i=0;i<20; i++)
   {
   }
}
wird akzeptiert

void test (){

for (uint8_t i=0;i<20; i++)
   {
   }
}

das aber nicht.

Gibts da einen Standard? Oder kann das jeder Compilerbauer handhaben wie 
er will?
Ist kein wirkliches Problem, nur interessehalber.
von (prx) A. K. (prx)


Lesenswert?

H.joachim Seifert schrieb:

> Will mein Compiler auch nicht, nimmt nur Variablen, die direkt am Anfang
> der Funktion erzeugt werden.

Das geht auch erst mit C99 (oder C++). Kann sein, dass der Compiler das 
nicht kennt, kann sein, dass man das erst per Option freigeben muss.
von Flo (Gast)


Lesenswert?

also habe folgendes gemacht,
ich habe eine funktion erstellt
1
void delay(int g)
2
{  
3
  for (int r=0; r!= g; r++)
4
      {
5
        GPIO_SetBits(GPIOE,GPIO_Pin_4);
6
      }
7
  
8
        GPIO_ResetBits(GPIOE,GPIO_Pin_4);
9
}

beim Compilieren kommt folgende Fehlermeldung:

main.c(498): error:  #29: expected an expression
main.c(498): error:  #20: identifier "r" is undefined



die routine ist eigentlich klar,
mach solange weiter bis r g entspricht,
oder anders gesagt,
mach solange weiter wie r ungleich g ist.


aber folgendes akzeptiert der compiler
1
void delay(int g)
2
{
3
 int r=0;  
4
  for (; r!= g; r++)
5
      {
6
        GPIO_SetBits(GPIOE,GPIO_Pin_4);
7
      }
8
  
9
        GPIO_ResetBits(GPIOE,GPIO_Pin_4);
10
}

seltsam, oder?
von Flo (Gast)


Lesenswert?

ok, joachim, ich war zu langsam :P
siehe mein post :D
von Peter D. (peda)


Lesenswert?

Beim GCC muß man
--std=gnu99
angeben.

Braucht man aber eh für die atomic.h.


Peter
von (prx) A. K. (prx)


Lesenswert?

Sich über den Compiler zu mokieren, ohne darauf hinzuweisen um welchen 
es dabei überhaupt geht, ist unhöflich und bringt nichts.
von H.Joachim S. (crazyhorse)


Lesenswert?

@Flo:
Das ist dasselbe wie bei mir (ausser dass du bei der Deklaration direkt 
einen Wert (0) zuweist und nicht erst in der Schleife.
von Flo (Gast)


Lesenswert?

A.K.

wenn du mir, ohne mich vorher zu lynchen,
verräts wo man das nachschauen kann,
verrate ich es dir...

habe gerade in keil gesucht,
nichts dazu gefunden (compiler)
von (prx) A. K. (prx)


Lesenswert?

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.