Mikrocontroller for-Schleife beenden?

Gast #5158595
Lesenswert?

Hallo Jungs und Mädels.
Ich fange gerade mit Mikrocontrollern an und habe einen Atmel-Ice mit 
der entsprechenden Software. Zum Einstieg habe ich mir noch ein Buch 
gekauft, aber irgendwie begreife ich es dennoch nicht. Mein Programm ist 
ein LED-Lauflicht mit 4 LEDs was in einer Schleife läuft. Wie beende ich 
denn diese Schleife nach z.B. 3 Durchläufen? Wenn das Programm sowieso 
merkwürdig oder sinnlos ist, dürft ihr mir gerne eine überarbeitete 
Version zeigen :)
Auf jeden Fall möchte ich keine Dauerschleife!


#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
  DDRD = 0xFF;
  while(1)
  {
    PORTD = (1<<PD0);
    _delay_ms (400);
    for(uint8_t i = 0;i<=2;i++)
    {
      PORTD = (PORTD << 1);
      _delay_ms(400);
    }
  }
}


MfG
Gast #5158616
Lesenswert?

Ach ja.. das hat dann aber das Problem, daß Deine main() endet. Unter 
Windows würde sich in dem Fall das Programm beenden, aber bei einem 
Mikrocontroller gibt es halt nichts, was "danach" passieren soll.

Typischerweise hast Du dann entweder einen Absturz, oder nach dem Aufruf 
von main() ist im Startup-Teil eine Endlosschleife, so daß danach nichts 
mehr passiert.
Gast #5158623
Lesenswert?

Stefanski schrieb:
> while(1)
>   {
>     PORTD = (1<<PD0);
>     _delay_ms (400);
>     for(uint8_t i = 0;i<=2;i++)
>     {
>       PORTD = (PORTD << 1);
>       _delay_ms(400);
>     }
>   }
1
  
2
while (1) {
3
  PORTD = 0x01;
4
  _delay_ms (400);
5
  for (uint8_t i = 0; i < 3; i++;) {
6
    PORTD <<= 1;
7
    _delay_ms (400);
8
  }
9
}
Gast #5158627
Lesenswert?

Stefanski schrieb:
> Also wäre dann 1 Controller hopps

Nein, Du müßtest ihn resetten, dann startet das nochmal. Da Controller 
aber normalerweise ohne Nutzereingriff Dinge lange tun sollen, macht man 
das in einer großen Endlosschleife.

Für Deine Anwendung wäre es natürlich möglich, das Lauflicht dreimal 
laufen zu lassen, sozusagen als Start-Anzeige, und danach andere Dinge 
aus der main() heraus zu starten.
#5158642
Lesenswert?

Stefanski schrieb:
> Ich fange gerade mit Mikrocontrollern an und habe einen Atmel-Ice mit
> der entsprechenden Software. Zum Einstieg habe ich mir noch ein Buch
> gekauft, aber irgendwie begreife ich es dennoch nicht. Mein Programm ist
> ein LED-Lauflicht mit 4 LEDs was in einer Schleife läuft. Wie beende ich
> denn diese Schleife nach z.B. 3 Durchläufen? Wenn das Programm sowieso
> merkwürdig oder sinnlos ist, dürft ihr mir gerne eine überarbeitete
> Version zeigen :)

Eine For-Schleife besteht aus drei Teilen: einer Initialisierung, einer 
Bedingung, einem "Nachgedanken" und dem Schleifenkörper.

Die Initialisierung findet statt, bevor der Schleifenkörper zum ersten 
Mal abgearbeitet wird. Dann wird die Bedingung geprüft, und wenn diese 
"wahr" ergibt, wird der Schleifenkörper und dann der "Nachgedanke" 
abgearbeitet. Danach springt die Ausführung wieder zu Prüfung der 
Bedingung zurück; wenn diese immer noch "wahr" ist, werden der 
Schleifenkörper und danach der "Nachgedanke" ausgeführt, bis die 
Bedingung "falsch" ergibt.

Deine For-Schleife sieht -- etwas anders geschrieben und kommentiert -- 
so aus:
1
for(
2
    uint8_t i = 0; /* Initialisierung */
3
    i <= 2;        /* Bedingung */
4
    i++            /* "Nachgedanke */
5
    ) {
6
                   /* Schleifenkörper */
7
}

Also wird die Variable i zunächst auf 0 initialisiert. Dann wird die 
Bedingung geprüft, und da i kleiner als 2 und die Bedingung damit 
erfüllt ist, wird erst der Schleifenkörper durchlaufen und danach der 
"Nachgedanke" ausgeführt, in dem i um 1 erhöht wird, am Ende also 1 ist. 
Dann folgt wieder die Prüfung der Bedingung, und da der Wert von i (1) 
natürlich kleiner als 2 ist: Schleifenkörper, "Nachgedanke", am Ende hat 
i den Wert 2 und die Bedingung wird erneut geprüft: i ist nicht kleiner, 
aber gleich 2, die Bedingung ist also erfüllt, Schleifenkörper, 
"Nachgedanke", am Ende ist i dann gleich 3 und die Bedingung wird wieder 
überprüft. Aber, huch: jetzt ist i = 3, also nicht mehr <= 2. Die 
Bedingung ist also falsch, deswegen wird die Schleife abgebrochen und 
mit dem Code nach der Schleife (nach der }) weitergemacht.

Ich hab' das mal so geschrieben, daß es auf einem PC läuft:
1
#include <stdio.h>
2

3
int main(void) {
4

5
    int i;
6
    for(i = 0; i <= 2; i++) {
7
        printf("in loop: i = %d\n", i);
8
    }
9
    printf("after loop: i = %d\n", i);
10
    return 0;
11
}

Ausgabe:
1
in loop: i = 0
2
in loop: i = 1
3
in loop: i = 2
4
after loop: i = 3

Kurz gesagt: wenn Du es richtig machst, beendet sich Deine for-Schleife 
von selbst, weil die Bedingung falsch wird.

Außerdem gibt es noch zwei Schlüsselworte: "break" springt sofort aus 
der Schleife heraus zum nachfolgenden Code, "continue" beendet das 
Abarbeiten des Schleifenkörpers und springt wieder zum Anfang der 
Schleife. Beide Schlüsselworte funktionieren auch mit anderen Schleifen 
und werden meist zusammen mit weiteren Bedingungen (if) benutzt.
1
#include <stdio.h>
2

3
int main(void) {
4

5
    int i;
6
    
7
    for(i = 0; i <= 2; i++) {
8
        printf("before if: i = %d\n", i);
9
        if( i == 1 ) {
10
            continue;
11
        }
12
        printf("after if: i = %d\n", i);
13
    }
14
    printf("after loop: i = %d\n", i);
15
    return 0;
16
}

Ausgabe:
1
before if: i = 0
2
after if: i = 0
3
before if: i = 1
4
before if: i = 2
5
after if: i = 2
6
after loop: i = 3

Du siehst: "i = 1" wird nur einmal ausgegeben, weil das "continue" in 
diesem Fall wieder zur Bedingungsprüfung springt. Wenn Du statt 
"continue" dort "break" schreiben würdest, sähe die Ausgabe so aus:
1
before if: i = 0
2
after if: i = 0
3
before if: i = 1
4
after loop: i = 1
Gast #5158645
Lesenswert?

Vorausgesetzt deine for-schleife selbst hat bislang getan, was sie soll:
1
#include <avr/io.h>
2
#include <util/delay.h>
3

4
int main(void)
5
{
6
  DDRD = 0xFF;
7
  PORTD = (1<<PD0);
8
  _delay_ms (400);
9
  for(uint8_t i = 0;i<=2;i++)
10
  {
11
    PORTD = (PORTD << 1);
12
    _delay_ms(400);
13
  }
14
  while(1)
15
  {
16
  }
17
}
Damit sollte das Programm einmal zum Start genau das machen, was du oben 
beschrieben hast und danach befindet sich der Controller in einer 
Endlosschleife, in der er einfach nichts macht.

Mikrocontroller sind keine Computer. Wenn man keine Sleepmodes 
verwendet, müssen die immer was "tun". Die leere while(1) Schleife ist 
ein bisschen vergleichbar mit dem Leerlaufprozess unter Windows.
Gast #5158653
Lesenswert?

Stefanski schrieb:
> Okay. Könntest du mir das als Programm schreiben?

Resetten heißt z.B. Spannungsquelle abziehen und neu anstecken, dann 
startet er neu. Oder auf den Resetknopf drücken.

Positiv gesehen bist Du soweit, daß Deine Toolchain läuft, Du das 
Programm runterladen kannst und daß es auf dem Controller läuft. Das 
sind die vorbereitenden Arbeiten, und jetzt geht die Entwicklung von dem 
los, was Du denn mit dem Controller tun möchtest.
Gast #5159123
Lesenswert?

Also eigentlich möchte ich eine IR-Fernbedienung basteln, um u.A. Platz 
zu sparen (im Inneren meines Objektes). Mein Ziel ist es, LEDs und einen 
Laser mit 2 Schaltern über IR zu schalten, anstatt mit Kabel, da das nur 
bedingt möglich ist.
Das wollte ich mit einem Mikrocontroller lösen und deshalb fange ich 
ganz am Anfang an, das Programmieren zu lernen. Finde es allerdings 
ziemlich kompliziert, selbst dieses doofe Lauflicht. Vielleicht sollte 
ich mir mal eine Liste erstellen/suchen, auf der die wichtigsten Befehle 
erklärt sind.
Mein Buch finde ich anstrengend, da es ständig heißt "dazu erfahren Sie 
später mehr"... aber ich will ja genau dann wissen, was ich tun muss, 
wenn ich es ins Programm schreibe. Naja...mal sehen wann oder ob ich das 
Alles verstehe.
Gast #5159466
Lesenswert?

Stefanski schrieb:
> Naja...mal sehen wann oder ob ich das Alles verstehe.

Ausdauer und selbst Fehler suchen ist angesagt und baut Wissen auf.

Kinderprogramme ins Internet zu posten ist vertane Zeit.

Ich weiß nicht mehr, wie viele Tage ich gebraucht habe, an meinem ersten 
6504-Board einen Schalter abzufragen und die zugehörige LED 
anzuschalten. Mangels Internet musste ich es mir selbst erarbeiten, 
geschadet hat es mir nicht.
Gast #5161971
Lesenswert?

>Mangels Internet musste ich es mir selbst erarbeiten,
>geschadet hat es mir nicht.

Puh, wenn ich an die Zeiten denke, Turbo Pascal aufm 286er und noch kein 
Internet. Frag dich mal, wo du jetzt sein würdest mit Internet damals ;)

Gruß J

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren