Forum: Compiler & IDEs While-Schleife beenden und Timer Frage


von Oldie (Gast)


Lesenswert?

Hallo, ich ahbe zwei Fragen: Wie beende ich die WhileSchleife in der 
WhileSchleife? Also, ich möchte, dass die LEDS bei 20 Sekunden aufhören 
zu blinken, das tun sie bei diesem Code nicht, ich gehe davon aus, dass 
es an der While schleife liegt, die nicght unterbrochen wird, und meien 
Frage ist einfach, wie man das tut.
1
 while(1)
2
  {
3
    if  (sekunde == 10)
4
    {
5
      PORTD |= LED2;
6
      while(1)
7
  {
8
    // LED1 und LED2 invertieren
9
    PORTD ^= LED1 | LED2;
10
 
11
    // 500ms lang warten
12
    long_delay(500);
13
  }
14
    }
15
    if  (sekunde == 20)
16
    {
17
      PORTD &= LED1;
18
    }
19
    
20
    if  (sekunde == 30)
21
    {
22
      PORTD |= LED2;
23
    }
24
    
25
    if  (sekunde == 40)
26
    {
27
      PORTD &= LED1;
28
    }
29
30
  }
31
}


Die andere Frage bezieht sich auf den Timer:
Wie kann ich beispielsweise 125 minuten darstellen?
125 einzutragen geht nicht, da der timer ja immer weider bei minute == 
60 auf 0 zurückspringt. Kann ich einfach stunde == 2 + minute == 1 
machen oder wie ist das zu regeln? Danke!
1
while(1)
2
  {
3
    if  (stunde == 2 + minute = 1) //sowas!
4
    {
5
      PORTD |= LED2;
6
      
7
    }
8
    if  (sekunde == 4)
9
    {
10
      PORTD &= LED1;
11
    }
12
    
13
    if  (sekunde == 5)
14
    {
15
      PORTD |= LED2;
16
    }
17
    
18
    if  (sekunde == 6)
19
    {
20
      PORTD &= LED1;
21
    }
22
23
  }
24
}
25
26
27
ISR(TIMER1_COMPA_vect)
28
{
29
  millisekunden++;
30
  if(millisekunden == 1000)
31
  {
32
    sekunde++;
33
    millisekunden = 0;
34
    if(sekunde == 60)
35
    {
36
      minute++;
37
      sekunde = 0;
38
    }
39
    if(minute == 60)
40
    {
41
      stunde++;
42
      minute = 0;
43
    }
44
    if(stunde == 24)
45
    {
46
      stunde = 0;
47
    }
48
  }
49
}

von Karl H. (kbuchegg)


Lesenswert?

Oldie schrieb:
> Hallo, ich ahbe zwei Fragen: Wie beende ich die WhileSchleife in der
> WhileSchleife? Also, ich möchte, dass die LEDS bei 20 Sekunden aufhören
> zu blinken, das tun sie bei diesem Code nicht, ich gehe davon aus, dass
> es an der While schleife liegt, die nicght unterbrochen wird, und meien
> Frage ist einfach, wie man das tut.

Keine derartige KOnstruktion verwenden, sonden sich was anderes 
überlegen.

zb könnte es eine Variable geben, die anzeigt, dass die LED im Zustand 
blinken sein soll. Bei 10 Sekunden wird die Variable auf TRUE gesetzt 
und bei 20 Sekunden wieder auf FALSE. In weiterer Folge fragt man dann 
zb geeignet ab, ob es Zeit ist die LED blinken zu lassen (abhängig von 
der Zeit) und lässt die dann eben nur dann tatsächlich blinken, wenn 
besagte Status-Variable dies zulässt.

Du musst weg von der Denkweise, dass du Dinge über gewisse Zeiträume 
hinweg machen sollst. Du musst hin zu der Denkweise:

Ich habe eine Arnbanduhr. Die ist jetzt gerade um 1 Sekunde 
weitergetickt. Was gibt es jetzt, genau in dieser Sekunde zu tun und 
warum gibt es das zu tun?
1 Sekunde später, wenn die Armbanduhr das nächste mal tickt, frage ich 
erneut: was genau gibt es jetzt, just in dieser Sekunde zu tun?


So baust du dein Programm auf. Deine LED blinkt nicht, weil du sie zb 
alle 2 Sekunden umschalten willst. Deine LED ist eingeschaltet, weil die 
Sekundennummer eine gerade Zahl ist und sie ist ausgeschaltet, weil die 
Sekundennummer eine ungerade Zahl ist. In Summe ergibt auch das ein 2 
Sekunden blinken. Aber die Herangehensweise ist eine völlig andere. Im 
letzteren Fall brauchst du nichts als die Nummer der aktuellen Sekunde 
um  zu entscheiden ob just in diesem Moment (mit dieser Sekundennummer) 
die LED ein oder aus sein soll, wodurch sich das Blinken ergibt.

von Oldie (Gast)


Lesenswert?

Karl Heinz schrieb:
> So baust du dein Programm auf. Deine LED blinkt nicht, weil du sie zb
> alle 2 Sekunden umschalten willst. Deine LED ist eingeschaltet, weil die
> Sekundennummer eine gerade Zahl ist und sie ist ausgeschaltet, weil die
> Sekundennummer eine ungerade Zahl ist. In Summe ergibt auch das ein 2
> Sekunden blinken. Aber die Herangehensweise ist eine völlig andere. Im
> letzteren Fall brauchst du nichts als die Nummer der aktuellen Sekunde
> um  zu entscheiden ob just in diesem Moment (mit dieser Sekundennummer)
> die LED ein oder aus sein soll, wodurch sich das Blinken ergibt.

Okay, wie sag ich, dass die LED ab stunde == 3 bei ungeraden sekunden 
ausgeschaltet werden soll und sonst den Zustand "an" hat?

und dann bliebe halt noch meine Frage mit dem Stunde == 3 + minute ==1

von Karl H. (kbuchegg)


Lesenswert?

> while(1)
>  {
>    if  (stunde == 2 + minute = 1) //sowas!
>    {5
>

Du musst wirklich und wahrhaftig endlich mal ein C-Buch durcharbeiten. 
Die Grundoperatoren und deren Verwendung sind absolute Grundlagen. Das 
ist sinnlos, sich das alles zusammenschnorren zu wollen. Du brauchst 
einen systematischen Ansatz. Ein Buch liefert dir den.
1
   if( stunde == 2 && minute == 5 )

oder aber: niemand zwingt dich, dass deine Uhr auch Stunden haben muss. 
Es ist nicht in Stein gemeisselt, dass die 'Uhr' in der Interruptroutine 
bei 60 Minuten die Minuten wieder auf 0 setzt und dafür dann die Stunden 
um 1 weiter zählt. WEnn du keine Stunden haben willst, dafür aber die 
Minuten bis weit in dein Tausenderbereich reinzählen willst - so sei es. 
Auf deinem µC bist du Gott. So wie du diese 'Welt' gestaltest, so ist 
sie.

von Karl H. (kbuchegg)


Lesenswert?

Oldie schrieb:

> und dann bliebe halt noch meine Frage mit dem Stunde == 3 + minute ==1

Du hast nicht wirklich verstanden, was ich mit der Statusvariablen 
gemeint habe. Oder?
1
int main()
2
{
3
  uint8_t isLedBlinking;
4
5
  ....
6
7
  while( 1 )
8
  {
9
    if( Stunde == 3 )
10
      isLedBlinking = 1;
11
    else
12
      isLedBlinking = 0;
13
14
15
    ...
16
17
18
    if( isLedBlinking )
19
    {
20
      if( Sekunde % 2 == 0 )
21
        PORT ... LED ausschalten
22
      else
23
        PORT ... LED einschalten
24
    }
25
    else
26
      PORT ... LED ausschalten
27
28
    ...
29
  }

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz schrieb:

> Du hast nicht wirklich verstanden, was ich mit der Statusvariablen
> gemeint habe. Oder?

Wobei diese Statusvariable schon die allgemeinere Form ist, die man zb 
dann benutzt, wenn die Abhängigkeit von anderen Ereignissen komplexer 
ist als hier und es auch mehr dieser möglichen Ereignisse gibt.

Hier könnte man das auch ganz einfach ohne diese Hilfsvariable machen, 
wennn es nur darum geht, dass die LED blinken soll, solange die 
Stundenzahl exakt und genau auf 3 steht.
1
int main()
2
{
3
  ....
4
5
  while( 1 )
6
  {
7
    if( Stunde == 3 )
8
    {
9
      if( Sekunde % 2 == 0 )
10
        PORT ... LED ausschalten
11
      else
12
        PORT ... LED einschalten
13
    }
14
    else
15
      PORT ... LED ausschalten
16
    ...
17
  }

Bei jedem Durchlauf durch die zentrale while-Schleife, also jeweils 
einen kleinen Augenblick später, stellt sich erneut die Frage
* Blinken oder nicht blinken?
* Wenn blinken, soll die LED dann ein oder aus sein? Und zwar zu genau 
dem jetzigen Augenblick.

von Oldie (Gast)


Lesenswert?

Verstanden, danke!

von Karl H. (kbuchegg)


Lesenswert?

Eine andere Idee:
1
  while( 1 )
2
  {
3
    if( minute < 2 )
4
    {
5
      if( millisekunden < 100 )
6
        PORTD |= LED2;
7
      else
8
        PORTD &= ~LED2;
9
    }
10
11
    else if( minute < 4 )
12
    {
13
      if( millisekunden < 200 )
14
        PORTD |= LED2;
15
      else
16
        PORTD &= ~LED2;
17
    }
18
19
    else
20
    {
21
      if( millisekunden < 500 )
22
        PORTD |= LED2;
23
      else
24
        PORTD &= ~LED2;
25
    }
26
27
    ...
28
  }

hier 'blinkt' die LED die jeweils ersten 2 Minuten einer jeden Stunde im 
Sekundentakt mit einem ein/aus Verhältnis von 1:9, was dem ganzen mehr 
ein AUfblitzen verleiht.
Die nächsten 2 Minuten ist das Verhältnis 2:8, das Aufblitzen geht schon 
mehr in ein Blinken über, während es den Rest der Stunde ganz normal in 
einem Verhältnis von 1:1 blinkt.

Die Idee dahinter ist es, dass man anhand des Blinkens eine kleine 
Rückmeldung hat, wo in der Zeit man gerade ist. Ob das jetzt in den 
ersten 2 Minuten anders ist, oder alle halbe Stunde anders, oder alle 
ganze Stunde anders, das ist selbstverständlich dir überlassen. Du 
entscheidest wie du das machen willst. Ist nur eine Idee, die vielleicht 
hilfreich ist, damit man beim schnellen schauen auf die Schaltung 
eventuell ein bischen rausfinden kann, wie lange es noch ungefähr 
dauert, bis die 2 Stunden abgelaufen sind.
Die Möglichkeiten sind vielfältig, wie man aus Abfragen basierend auf 
Millisekunden, Sekunden, Minuten oder Stunden oder Kombinationen davon, 
diverse Lichtspiele machen kann.

Es gibt nur eine Regel. Die allerdings wird groß geschrieben: kein 
_delay_ms!

von Oldie (Gast)


Lesenswert?

Könnt ihr mir verraten, wie ich da noch einen zweiten Zeitpunkt 
integriere?
Im sinne von: Wenn 3 stunden && 3 minuten UND Wenn 4 Stunden && 3 
Minuten

[/c]

while( 1 )
    {
      if( stunde == 3 && minute == 3 )
      isLedBlinking = 1;
      else
      isLedBlinking = 0;


      if( isLedBlinking )
      {
        if( sekunde % 2 == 0 )
        PORTD &= LED1;
        else
        PORTD |= LED2;
      }
      else
      PORTD &= LED1;

    }

[/c]

Danke

von Karl H. (kbuchegg)


Lesenswert?

Oldie schrieb:
> Könnt ihr mir verraten, wie ich da noch einen zweiten Zeitpunkt
> integriere?
> Im sinne von: Wenn 3 stunden && 3 minuten UND Wenn 4 Stunden && 3
> Minuten

Indem du es hinschreibst. && ist ein logisches UND
1
 if( ( stunde == 3 && minute == 3 ) &&
2
     ( stunde == 4 && minute == 3 ) )

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz schrieb:
> Oldie schrieb:
>> Könnt ihr mir verraten, wie ich da noch einen zweiten Zeitpunkt
>> integriere?
>> Im sinne von: Wenn 3 stunden && 3 minuten UND Wenn 4 Stunden && 3
>> Minuten
>
> Indem du es hinschreibst. && ist ein logisches UND
>
>
1
>  if( ( stunde == 3 && minute == 3 ) &&
2
>      ( stunde == 4 && minute == 3 ) )
3
>

Aber eigentlich denk ich nicht, dass du hier ein UND willst. Denn es 
gibt keinen Zeitpunkt, für den gilt, dass sowohl die Bedingung (stunde 
== 3 und minute == 4) als auch die Bedingung ( stunde == 4 und minute == 
3 ) gleichzeitig zutrifft. Irgend ein Zeitpunkt kann entweder mit den 
einen Zeitpunkt übereinstimmen oder mit dem anderen. Aber nie mit beiden 
gleichzeitig, was aber Voraussetzung wäre, damit ein UND korrekt ist. 
Denn bei einem UND müssen ja die beiden Teile beide gleichzeitig wahr 
sein, damit das Gesamtergebnis wahr ist.

Du willst eher ein Oder.
Wenn der aktuelle Zeitpunkt entweder Zeitpunkt1 (stunde == 3 und minute 
== 3) ist ODER wenn der Zeitpunkt dem Zeitpunkt2 (stunde == 4 und minute 
== 3) entspricht, dann mach was
1
  if( ( stunde == 3 && minute == 3 ) ||
2
      ( stunde == 4 && minute == 3 ) )

da aber die geforderten Minuten in beiden Fällen identisch sind, ginge 
auch:
Wenn Stunde gleich 3 oder 4 UND minuten gleich 3
1
  if( ( stunde == 3 || stunde == 4 ) && ( minute == 3 ) )

Man hätte auch so vorgehen können
1
   if( stunde == 3 && minute == 3 )
2
     isLedBlinking = 1;
3
4
   else if( stunde == 4 && minute == 3 )
5
     isLedBlinking = 1;
6
7
   else
8
     isLedBlinking = 0;

Würde ebenfalls aufs selbe rauslaufen.

Genauso wie
1
   if( stunde == 3 || stunde == 4 )
2
   {
3
     if( minute == 3 )
4
       isLedBlinking = 1;
5
     else
6
       isLedBlinking = 0;
7
   }
8
   else
9
     isLedBlinking = 0;

Oder
1
   isLedBlinking = 0;
2
   if( stunde == 3 || stunde == 4 )
3
   {
4
     if( minute == 3 )
5
       isLedBlinking = 1;
6
   }

viele Wege führen nach Rom und es gibt mehr als eine Art, einer Katze 
das Fell über die Ohren zu ziehen.

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.