Forum: Compiler & IDEs Zwei verschatelte FOR-Anweisungen falsch übersetzt?


von Andreas Klafft (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Leute,
irgendwie bin ich entweder zu doof, oder meine Compilerkombination hat 
'nen Schuss. Folgendes Miniprogramm wird anscheinend nicht richtig 
übersetzt:
1
#define MCU    atmega168
2
3
#include  <avr/io.h>
4
5
int main( void )
6
{
7
8
uint8_t PulsWidth;  // PWM-Counter
9
uint8_t amplitude;
10
uint8_t MStep;  // Schrittzähler
11
12
amplitude = 50;
13
14
DDRD |= (1 << DDD0) | (1 << DDD1) |(1 << DDD2) |(1 << DDD3);
15
while(1){
16
17
18
  for( MStep = 1 ; MStep <= 4 ; MStep++ )
19
{    for( PulsWidth = 1 ; PulsWidth <= 255 ; PulsWidth++ ){
20
      if (PulsWidth <= 100){
21
        switch (MStep){
22
        case 1:
23
          PORTD = 0x09;
24
          break;
25
        case 2:
26
          PORTD = 0x05;
27
          break;
28
        case 3:
29
          PORTD = 0x06;
30
          break;
31
        case 4:
32
          PORTD = 0x0A;
33
          break;
34
        default:
35
          break;
36
        }
37
38
      } else {
39
        PORTD = 0x00;
40
      }
41
42
    } // Next PulsWidth
43
44
  } // Next MStep
45
}
46
return(0);
47
}
Die innere Schleife wird richtig übersetzt und funktioniert auch. Die 
Äußere will einfach nicht so, wie ich mir das gedacht habe. Auch die 
*.lss Datei wirft nur Schwachsinn raus. Habe sie mal angehängt. Hier mal 
ein paar Fakten zur Software:

OS: SUSE 12.1
IDE: Eclipse Indigo 3.7.1
Plugin: 2.4.0 beta2
Toolchain: 3.2.3.314 von Atmel
MCU: Atmega168, 20MHz

Ich habe da auch schon die Versionen aus dem AVR-Repo von Suse verwendet 
und andere Experimente gemacht, wie z.B. auf while-Schleifen umgestellt.
Kann mir jemand einen Hinweis geben, was ich hier falsch mache?

Gruß Andreas.

Ihr habt mir immer geholfen .....

von Sauger (Gast)


Lesenswert?

Mahlzeit,

Andreas Klafft schrieb:
> Äußere will einfach nicht so, wie ich mir das gedacht habe.

wir können deine Gedanken aus der Ferne leider nicht lesen. Beschreibe 
was Du vorhast.

MfG

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Andreas Klafft schrieb:

> Folgendes Miniprogramm wird anscheinend nicht richtig übersetzt:
>
> for (MStep = 1; MStep <= 4; MStep++)
> {
>     for (PulsWidth = 1; PulsWidth <= 255; PulsWidth++)

Das ist eine Endlosschleife, die der Compiler optimiert.
Er kommt also nie mehr in die äussere Schleife "zurück"
und MStep ist also immer 1, was weitere Optimierung in der
inneren Schleife ermöglicht :-)

> Auch die *.lss Datei wirft nur Schwachsinn raus.

Garbage in — garbage out ;-)

Vielleicht willst du sowas?

> for (PulsWidth = 1; PulsWidth != 0; PulsWidth++)

von Andreas B. (andreasb)


Lesenswert?

Hallo Andreas


Die innere Schleife ist eine Endlosschleife...
1
uint8_t PulsWidth;  // PWM-Counter
2
for( PulsWidth = 1 ; PulsWidth <= 255 ; PulsWidth++ )

ggf. solltest du "PulsWidth < 255" verwenden, oder täusche ich mich da?





mfg Andreas

von Andreas K. (lowrider)


Lesenswert?

Die innere Schleife zählt von 0 bis 255. Dabei schaltet er die Ausgänge 
von PORTD nach einem bestimmten Bitmuster ein. Das Bitmuster ist 
abhängig von dem Zustand der Äußeren Schleife, also MStep. Wird ein 
bestimmter Wert erreicht, hier 100 soll PORTD komplett auf 0 stehen.
Ist die innere Schleife fertig durchlaufen soll MStep um eins 
inkrementiert werden. Das passiert schon mal nicht. MStep bleibt immer 
auf dem Wert 1 stehen anstatt von 1 bis 4 zu Zählen.

Das ganze soll eine Stepperansteuerung werden. Über die Bits 0..3 wird 
das Bitmuster für den Stepper ausgegeben Das sind die 4 verschiedenen 
Zustände, um den Stepper weiterzuschalten.
Die innere Schleife benutze ich als PWM-Signal, um die Spannung bei 
geringer Stepfrequenz abzusenken. Damit die eistungsstufe oder der Motor 
nicht überlastet werden.

von g457 (Gast)


Lesenswert?

wie Andreas schon schrub: mit

> uint8_t PulsWidth;  // PWM-Counter
  ^^^^^^^
wird

>    for( PulsWidth = 1 ; PulsWidth <= 255 ; PulsWidth++ )
                                    ^^^^^^
zur Endlosschleife.

HTH

von Andreas K. (lowrider)


Lesenswert?

Ich sach, manchmal kommt man auf die einfachsten Sachen nicht. Hab den 
max-Wert mal auf 250 herabgesetzt und schon läuft's.

Danke für die schnelle Hilfe.

Gruß Andreas

PS: Bin zwar noch C-Anfänger, sowas sollte aber nicht passiert: Asche 
über mein Haupt.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Es ist selten verkehrt, dem Compiler die Optionen -Wall und -Wextra
mitzugeben. In diesem Fall hätte er dich folgendermaßen zur Lösung
deines Problems geführt:
1
test.c:19:1: warning: comparison is always true due to limited range of data type [-Wtype-limits]

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Yalu X. schrieb:
> Es ist selten verkehrt, dem Compiler die Optionen -Wall und -Wextra
> mitzugeben.

Wozu denn Warnungen??

Es gibt doch Internet-Foren, die direkt Problemlösungen liefern :-P

von human resource (Gast)


Lesenswert?

Johann L. schrieb:
> Es gibt doch Internet-Foren, die direkt Problemlösungen liefern

Genau, und wenn es dich stört, überliest die Beiträge einfach. Man 
sollte ruhig öfter mit Menschen kommunizieren, sonst -> Nerd.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

human resource schrieb:

> Man sollte ruhig öfter mit Menschen kommunizieren...

Hab ich doch: 
Beitrag "Re: Zwei verschatelte FOR-Anweisungen falsch übersetzt?"

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.