Forum: Compiler & IDEs for Schleife


von Achim S. (achims)


Lesenswert?

Hallo
habe ein Problem mit einem Stück Code. Habe ihn hier rangehängt.

while(1)                  // Beginn Hauptschleife
       {
  if (waits == 0xFF)    // Frage signal waits
       {
          waits = 0;            // signal wait = 0
    if(!(PINC&(1<<PC5)))      // Abfrage PortC PC5Grün
    leds_set_status(1,5);  // schaltet LED 5 Grün auf ein

     else
    leds_set_status(0,5);  // schaltet LED 5 Grün auf aus
  }
    }
Es wird durch einen Timer und ISR alle 500ms geschaltet. Möchte jetzt 
die Zeit auf 10ms senken und die Schleife 50 mal abfragen. Hatte es mit 
for versucht. Klappt aber nicht.

for(wats=0; waits<=50;waits--) was mache ich wieder falsch?
achim

von strunz (Gast)


Lesenswert?

Ich versteh nur Bahnhof. Wie ist waits definiert? Wenn du in der 
Schleife waits ständig zurücksetzt gibt das eine Endlosschleife... ?!?

von Peter II (Gast)


Lesenswert?

was ist waits? Was macht der Timer mit waits?

Bitte den mehr code zeigen, sonst kann man da nicht helfen.

von M. J. (manfred-64)


Lesenswert?

Was soll das bringen diese Schleife mehr als 1x zu durchlaufen !!!

von XXX (Gast)


Lesenswert?

Hallo

for(wats=0; waits<=50;waits--)
      ^^                   ^^

Vielleicht hilft an der ersten Stelle noch ein "i"
und an der zweiten Stelle ein "++".

Gruß
Joachim

von M. J. (manfred-64)


Lesenswert?

Ich meinte NUR 50x, ist ja bis jetzt ne Endlosschleife

von Achim S. (achims)


Lesenswert?

Kein Problem.
{
  TCNT2 = 0;
  OCR2=249;
  TCCR2=(1<<WGM21)|(1<<CS21)|(1<<CS20);
  TIMSK |= (1<<OCIE2);
  }

ISR (TIMER2_COMP_vect)      // wait1=1ms,
  {
  if(  wait<9)      // 10ms
    {  wait++;  }    // erhöht
  else        // wenn dann ...
    {  wait=0;      // setzt wait1 auf 0
       waits=0xFF;       // Signal alle 10ms
    }
  }
Timer und ISR bringen alle 10ms einen Impuls. Damit möchte ich zählen. 
Das soll delay ersetzen, so das der Prz durchläuft.
Bitte die Fehler zu entschuldigen.

von M. J. (manfred-64)


Lesenswert?

Das mit dem Interrupt war klar aber wie so willst Du deine Hauptschleife 
nur 50x durchlaufen???

von Adib T. (adib_t)


Lesenswert?

XXX schrieb:
> Hallo
>
> for(wats=0; waits<=50;waits--)
>       ^^                   ^^
>
> Vielleicht hilft an der ersten Stelle noch ein "i"
> und an der zweiten Stelle ein "++".
>
> Gruß
> Joachim

Diese Schleife wird 51mal durchlaufen. Gruss, Adib.

von Achim S. (achims)


Lesenswert?

Hallo Manfred
ist ganz einfach. Wenn ich die LED blinken lassen will, kann ich delay 
nehmen. Da schläft der Prz für eine Zeit. Das will ich nicht. Also nehme 
ich den Impuls vom Timer und jage denn durch die Schleife, 50 mal 
zusammen 1Sekunde. Jedesmal setze ich einen Zähler um ein zurück. 
Dadurch spare ich Zeit und kann was anderes machen. Warum soll der Prz 
so lange dort warten. Reicht doch wenn er alle 10ms vorbei kommt und was 
macht
achim

von Achim S. (achims)


Lesenswert?

Alib schrieb:
> Hallo
>
> for(wats=0; waits<=50;waits--)
>       ^^                   ^^
>
> Vielleicht hilft an der ersten Stelle noch ein "i"
> und an der zweiten Stelle ein "++".
>
> Gruß
> Joachim

Diese Schleife wird 51mal durchlaufen. Gruss, Adib.

Ist es nicht besser wenn ich mit- zähle bis auf null?

von M. J. (manfred-64)


Lesenswert?

Achim Seeger schrieb:
> Da schläft der Prz für eine Zeit. Das will ich nicht.
...
> Reicht doch wenn er alle 10ms vorbei kommt und was
> macht

Tut er ja in den Progremmschnipsel die Du gepostet hast.

Was willst Du dann mit einer FOR Schleife im Hauptteil.

von XXX (Gast)


Lesenswert?

Hallo

Du fängst ja mit 0 an    --> waits = 0
Die Schleife wird solange wiederholt, bis du 50 erreichst  --> waits 
<=50
Wenn du 50 erreichen willst, mußt du addieren --> waits++

Oder zweite Alternative: Du durchläust mit waits-- den kompletten
negativen Zahlenbereich und näherst dich der 50 von oben.
Dann hast du aber wesentlich mehr Durchläufe als 50.

Gruß
Joachim

von M. J. (manfred-64)


Lesenswert?

Ich glaube ich hab nun verstanden was Du willst !?

Du musst nur das in einer eigenen Prozedur auslagern:

> waits = 0;            // signal wait = 0
>     if(!(PINC&(1<<PC5)))      // Abfrage PortC PC5Grün
>     leds_set_status(1,5);  // schaltet LED 5 Grün auf ein
>
>      else
>     leds_set_status(0,5);  // schaltet LED 5 Grün auf aus

von Achim S. (achims)


Lesenswert?

Das mit dem + ist jetzt klar. Hatte wahrscheinlich nur die falsche 
Richtung angesehen.
Das mit der Prozedur ist auch klar. Nehmen wir das Beispiel des 
Blinkens. Wenn ich die LED für 0,5 s anmache und für 0,5 S ausmache ist 
das 1 Hz blinken. Mein Timer bringt alle 10ms einen Impuls. Muss ihn 
also von 0 bis 49 zählen lassen und dann schalten. Andere Version. Wenn 
ich ein delay von 100ms brauche, muss ich den Impuls 10x zählen und dann 
weiterschalten. Bruache noch eine kleine Routine die das macht, so in 
eine Zeile.
achim

von M. J. (manfred-64)


Lesenswert?

Ich muss hier mit nem P3 1GH arbeiten ;(
Da macht selbst das scrollen keinen Spass.
Post doch noch mal dein Listig in einem Stuck!

und dann stelle bitte noch mals Deine Frage die nur Bezug auf diesen 
Code nimmt, da ich verwirrt bin, den Dein Code sollte das machen was Du 
vorhast.
Soweit ich die Fragestellung verstanden habe.

von Achim S. (achims)


Lesenswert?

Hallo Manfred
kein Problem, mal das ganze.

{
  TCNT2 = 0;
  OCR2=249;
  TCCR2=(1<<WGM21)|(1<<CS21)|(1<<CS20);
  TIMSK |= (1<<OCIE2);
  }

ISR (TIMER2_COMP_vect)      // wait1=1ms,
  {                                     // war vorher 500 = 0,5s
  if(  wait<0)      // bei 9 sind es 10ms
    {  wait++;  }    // erhöht
  else        // wenn dann ...
    {  wait=0;      // setzt wait1 auf 0
       signal_wait=0xFF;    // Signal alle 10ms
    }
  }

while(1)        // Beginn Hauptschleife
  {
    if (waits == 0xFF)    // Frage signal wait
  {
          waits = 0;         // signal wait = 0
    if(!(PINC&(1<<PC5)))   // Abfrage PortC PC5 LED 5 Grün
    leds_set_status(1,5);    // schaltet LED 5 Grün auf ein

   else
    leds_set_status(0,5);  // schaltet LED 5 Grün auf aus
  }
    }

return 0;
}

So, alles drin. Beginnt mit Timer 1ms. Dann kommt ISR mit 10ms. Waits 
schaltet die Abfrage und Umschaltung der LED. Bei einer Zeit von 500ms 
schaltet direkt um. Will jetzt 10ms nehmen und das Signal 50x abfragen, 
so wie for (waits=0,waits<=49;waits++). Klappt aber nicht, und verstehe 
meinen Fehler nicht.

von chick (Gast)


Lesenswert?

Laß Deinen Zähler in der Interrupt-Routine nur simple hochzählen.

Frag im Hauptprogramm ab:

ist er 50, so schalte die Led an
ist er 100, so schalte die led aus und setz den Zähler auf 0

fertig.

Im Hauptprogramm sind zwei simple Abfragen, die Interrupt-Routine ist 
auch kurz.

Mehr brauchst Du nicht.

von Walter S. (avatar)


Lesenswert?

Achim Seeger schrieb:
> for (waits=0,waits<=49;waits++)

meinst du vielleicht
for (waits=0; waits<=49; waits++)

ansonsten sollte man nicht Codefragmente und frisch eingetipptes 
verwenden,
sondern wie Gutenberg copy and paste machen

von M. J. (manfred-64)


Lesenswert?

Du glaubst also das das Programm mit der ursprünglichen Zeile

> if(  wait<499)      // bei 9 sind es 10ms

irgend wo in einer Warteschleife hängt und der µC für nichts anderes 
Zeit hat ?
Dem ist nicht so, es gibt bei diesem Programm keine "Warteschleife", da 
Du ja mit einem TimerInterrupt arbeitest!!!
Die Hauptschleife wird ständig durchlaufen bis der Timerinterrupt 
ausgelöst wird.

Wenn Dir das auslösen des Timerinterrupts alle 1ms zu häufig ist (500x 
bis das waits "Signal" benötigt wird) musst Du den Timerinterrupt auf 
10ms erhöhen und
> if(  wait<499)      // ISR alle 1ms, 500x = 0,5s
wie von Dir bereit geändert
> if(  wait<49)      // ISR alle 10ms, 50x = 0,5s

von Achim S. (achims)


Lesenswert?

Hallo Manfred
was du da schreibst ist klar. Es geht alles über den Timer. Möchte aber 
von 500ms auf 10ms die ISR umstellen. Damit die LED im gleichen Takt 
bleiben, muss ich an den LED bis 50 zählen und dann erst schalten. 
Deshalb die for Schleife. Ich möchte die 10ms des Timer/ISR auch an 
anderen Stellen im Prg nutzen. Um die Zeiten Nutzen zu können sind 500ms 
sehr schlecht, 10ms weitaus besser.

von Peter II (Gast)


Lesenswert?

Achim Seeger schrieb:
> Damit die LED im gleichen Takt
> bleiben, muss ich an den LED bis 50 zählen und dann erst schalten.
> Deshalb die for Schleife.

jetzt versteht ich was du willst. Aber dafür nimmt man keine for 
schleife. Sondern man zählt einfach so eine Variable noch.


uint8_t cnt = 0;

while(1) {

 if (waits == 0xFF) {
    waits = 0;
    cnt++;
    if ( cnt == 50 ) {
      cnt = 0;
      if(!(PINC&(1<<PC5)))   // Abfrage PortC PC5 LED 5 Grün
         leds_set_status(1,5);    // schaltet LED 5 Grün auf ein
      else
         leds_set_status(0,5);  // schaltet LED 5 Grün auf aus
     }
  }
}

von chick (Gast)


Lesenswert?

Schon mal meinen Vorschlag in Erwägung gezogen? Einfacher gehts nicht, 
eine For-Schleife hat bei Deiner Aufgabenstellung nichts zu suchen. 
For-Schleifen sind um etwas sequentiell abzuarbeiten, z.B. in Arrays.

Dieses Geeiere mit einer For-Schliefe, einfach irr.

von Achim S. (achims)


Lesenswert?

Hallo Peter
werde deine Sache gleich Probieren.Habe mich täuschen lassen durch die 
Abfrage.
Bleibt noch eins. Denke wahrscheinlich viel zu kompliziert. Wenn ich 
delay ersetzen will, dann kann ich doch eine Zeile nehmen mit so einem 
Vergleich, zählen lassen bis 10ms mal x und den Code in den klammern 
ausführen lassen? oder? und das will ich noch zu kurz wie möglich 
bekommen.
Hallo chick, werde auch deines testen, Hatte für mich schon sowas 
gemacht. Bin leider mit der Abfrage vom ISR durcheinander gekommen.
achim
PS schöne Ostern

von M. J. (manfred-64)


Lesenswert?

Achim Seeger schrieb:
> Ich möchte die 10ms des Timer/ISR auch an
> anderen Stellen im Prg nutzen. Um die Zeiten Nutzen zu können sind 500ms
> sehr schlecht, 10ms weitaus besser.

Das war das fehlende Stück Info :)

Mach was Peter vorgeschlagen hat und mach dir noch mals Gedanken über 
FOR Schleifen, wie bereits von chick angeregt.


und noch viel Spaß bei'm Experimentieren :)

von Achim S. (achims)


Lesenswert?

Hallo
Der Code geht ganz hervorragend. Noch ein bischen angepasst, alles ok.
Kleine Frage noch dazu. Wenn ich diesen Code mehrmals verwende, z.B. um 
unterschiedliche LED an verschiedenen Teilen im Prg zu schalten, muss 
ich jedesmal eine andere Bezeichnung nehmen oder kann ich für alle 
Zeitschleifen immer den selben Buchstabe nehmen?

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.