Abbruch einer Schleife

OP #1929853
Lesenswert?

Hallo,
ich habe ein problem und zwar weiß ich nicht, wie ich nach einer 
bestimmten zeit aus der schleife rausgehe, weil sie sonst unendlich 
durchlaufen wird, wenn der uart nichts empfängt. villt kann mir einer 
von euch weiterhelfen.
hier mein code:

void ResiveString (void)
{
unsigned char i = 0;

  RWL;            //Senden
  //interne Daten
  for (i = 0; i < 9; i++)
  {
    while ((UCSRA & 0x80) == 0) //warten bis Zeichen eingelesen wurde
    {
    ;
    }
    Einlesepuffer[i] = UDR;      //Zeichen einlesen
  }

}
Gast #1929859
Lesenswert?

>void ResiveString (void)
receive Bitte...
  ^^

>RWL;            //Senden
???

>  for (i = 0; i < 9; i++)
>  {
>    while ((UCSRA & 0x80) == 0) //warten bis Zeichen eingelesen wurde
>    {
>    ;
>    }
>    Einlesepuffer[i] = UDR;      //Zeichen einlesen
>  }
Nicht gut, in doppelter Hinsicht:
- In 6 Monaten weisst du nicht mehr was mit 0x80 gemeint ist, (1<<BIT) 
ist deutlich besser.
- Die Auslesemethode funktioniert zwar (auf den ersten Blick), ist aber 
blockierend. Besser: Interrupts nutzen.
#1929861
Lesenswert?

- Timer aufsetzen
- In der ISR ein Flag setzen.
- In deiner Routine den Timmer starten und
  und in der Schleife auf das Flag prüfen und eventuell raus springen.

Man muß aber nicht auf Zeichen vom UART warten, hierfür kann man auch 
Interrupts verwenden.

Gruss Volker
Gast #1929868
Lesenswert?

>- Timer aufsetzen
>- In der ISR ein Flag setzen.
>- In deiner Routine den Timmer starten und
>  und in der Schleife auf das Flag prüfen und eventuell raus springen.
Das hatte ich mir verkniffen, denn...
- um beide Schleifen (for+while) zu verlassen ist ein Goto, ein weiteres 
return oder eine zusätzliche Variable+Bedingung nötig, alles nicht 
besonders leserlich. Außerdem weiß der Aufrufer nicht ohne weiteres ob 8 
Bytes gelesen wurden, i ist lokal und kann nicht abgefragt werden und im 
aktuellen Zustand gibt die Funktion keinen Status zurück (und "unsauber" 
ist das imho sowieso).
- Ich vermute mal der Fragesteller ist (relativer) Anfänger, da sollte 
man sich gleich die richtigen Verfahren (-->Interrupt) angewöhnen, nicht 
solche Basteleien.
Gast #1929888
Lesenswert?

>Aber ob der TO mit UART-ISR mit State-Mashine + parrallel laufendem
>Timmer besser zurecht kommt, ist auch Fraglich!
Wohl war, aber irgendwann wird er sich damit beschäftigen müssen. Dann 
ist es besser gleich die "richtigen" Methoden zu lernen statt Zeit in 
irgendwelche Murkslösungen (naja, villeicht etwas zu hart) zu stecken...

Nehm es mir nicht übel: parallel (...) Timer (Niemand ist perfekt)
                          ^              ^
Gast #1930180
Lesenswert?

Hallo Tobias,

ich würde Dir auch auf jeden Fall zur Nutzung von Interrups raten. Such 
mal nach Beispielen. Es ist eigentlich nicht so kompliziert.

Du kannst Dir auch auf die schnelle eine Zählervariable bauen, die Du 
inkrementierst. Du musst nur berechnen oder messen, wie lange die 
Abarbeitung der Schleife dauert um die Variable sinnvoll vorzubelegen.

int TimeOutCounter = 30000;

while ((UCSRA & 0x80) == 0)
{
   TimeOutCounter--;

   if(TimeOutCounter == 0)
   {
      break;
   }
}

ODER kürzer:

int TimeOutCounter = 30000;
while (((UCSRA & 0x80) == 0) && (TimeOutCounter--))
{
;
}

Schön ist das so aber nicht!

Gruß
Arnold

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