AVR-C- for-Schleifen verschachteln

OP #3064311
Lesenswert?
• ▲
▼
Hallo,
leider bekomme ich es nicht hin, 2 for-Schleifen abwechseld laufen zu 
lassen.

------------------------------------
int16_t main(void)
{
DDRA = 0b00000000;
DDRB = 0b11111111;
PORTB = 0b11111111; // alle LEDs aus (=STK500)
uint8_t led=0;

while(1)
{
for(uint16_t loop=20;loop<=60;loop+=10) //for"1", schneller werdend
 {
 for(;led<=7;)        //for "2", Lauflicht von LED0-7
  {
  clrPort(&PORTB,led); //LEDx ein (=STK500)
  warte_ms(loop);      //warte "loop" in [ms]
  setPort(&PORTB,led); //LEDx aus (=STK500)
  led++;
  }
 for(;led>=0;led--)   //for"3", Lauflicht von LED6-0
  {
  clrPort(&PORTB,led); //LEDx ein (=STK500)
  warte_ms(loop);       //warte "loop" in [ms]
  setPort(&PORTB,led); //LEDx aus (=STK500)
  }
}}return 0;}
-------------------------------------

Fehler: Nachdem for"3" korrekt durchlaufen ist, fängt for"2" nicht 
automatisch wieder von LED0-7 an.
Gast #3064346
Lesenswert?
• ▲
▼
In for"3" :
Wenn led = 0 ist wird versucht einer abzuziehen, led = -1.
Led ist ein uint8_t, Wertebereich von 0 - 255.

Also entweder einen int benutzen oder for(;led>=1;led--).

Wenn ich mich nicht irre.
Gast #3064386
Lesenswert?
• ▲
▼
uint8_t schrieb:
> oder for(;led>=1;led--).

Warum nicht das hinschreiben, was man wirklich will:

Es ist ganz sinnvoll. wenn man für eine while-Bedingung auch eine 
while-Schleife hinschreibt, und an Stelle von <= nur < in der 
Abbruchbedingung benutzt.
1
while(led < 8 )
2
{
3
  ...
4
  led++
5
}
6

7
led-= 2;
8

9
while(led > 0)
10
{
11
  ...
12
  --led;
13
}

Die "8" mit "<" in der Abbruchbedingung hilft, die Zeile "led -=2" nicht 
zu vergessen, wenn die Kommentare
> Lauflicht von LED0-7
und
> Lauflicht von LED6-0
tatsächlich ernst gemeint waren.

Oliver
#3064396
Lesenswert?
• ▲
▼
Oliver schrieb:

> zu vergessen, wenn die Kommentare
>> Lauflicht von LED0-7
> und
>> Lauflicht von LED6-0
> tatsächlich ernst gemeint waren.

.... was durchaus möglich ist, weil ja die erste bzw. die letzte LED 
etwas anders zu behandeln sind. Meistens will man ja nicht, dass die 
dazwischenliegenden LED, sagen wir mal, jeweils 1 Sekunde brennt und die 
erste bzw. letzte LED dann 2 Sekunden, weil sie 1 Sekunde für die eine 
Lauflichtrichtung und 1 Sekunde für die andere Lauflichtrichtung brennt. 
Das führt dann zu einem optischen Effekt, dass das Lauflicht an den 
Endpunkten innezuhalten scheint, ehe es dann wieder weitergeht, obwohl 
alle LED in beiden Lauflichtrichtung getrennt betrachtet, exakt gleich 
lang brennen :-)
OP #3064404
Lesenswert?
• ▲
▼
uint8_t schrieb:
> In for"3" :
> Wenn led = 0 ist wird versucht einer abzuziehen
for(;led>=0;led--)
Ich meine, wenn led=0 erreicht ist, bricht die Schleife sofort ab, ohne 
noch ein mal "led--" zu berechnen.

Εrnst B✶ schrieb:
> Wenn du die Compiler-Warnings einschaltet, meckert er sowas an.
Der Compiler zeigt keine Warnungen an!


Es sieht folgend aus;
(1) for"1" läuft
(2) for"2" läuft fehlerfrei, LED0-7
(3) for"3" läuft fehlerfrei, LED6-0
--statt jetzt zurück zu for"2" springen,
(4) LED0 leuchtet dauernd für ca.3Sek
(5) alles LEDs aus für ca.3Sek
(6) sprung zu Punkt (3)
#3064408
Lesenswert?
• ▲
▼
__Son´s Bersi__ schrieb:
> uint8_t schrieb:
>> In for"3" :
>> Wenn led = 0 ist wird versucht einer abzuziehen
> for(;led>=0;led--)
> Ich meine, wenn led=0 erreicht ist, bricht die Schleife sofort ab, ohne
> noch ein mal "led--" zu berechnen.

Nö.
Warum soll sie?

Deine Bedingung in der for lautet:   led >= 0

Da steht größer-gleich. Und genau das passiert auch. Solange led größer 
gleich 0 ist, wird die Schleife wiederholt.

Dein Pech, dass ein unsigned Wert per Definition immer größer oder 
gleich 0 ist, weil er ja als unsigned Wert nicht negativ werden KANN!


> (4) LED0 leuchtet dauernd für ca.3Sek
> (5) alles LEDs aus für ca.3Sek

Ja. so lange dauert es bis led dann weiter durchgezählt hat

   2, 1, 0, 255, 254, 253, 252, 251, .... , 3, 2, 1, 0, 255, 254, ....

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.