for Schleife

#2625261
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
#2625298
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.
#2625343
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
Gast #2625384
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
#2625415
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
#2625745
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.
#2625968
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
#2625997
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.
Gast #2626002
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
     }
  }
}
#2626016
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
#2626083
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 :)

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