Forum: Mikrocontroller und Digitale Elektronik Abbruch einer Schleife


von Tobias D. (tobias92)


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
  }

}

von aa (Gast)


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.

von Volker Z. (vza)


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

von aa (Gast)


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.

von Volker Z. (vza)


Lesenswert?

aa schrieb:
> Das hatte ich mir verkniffen, denn...

Natürlich hast du Recht.
Aber ob der TO mit UART-ISR mit State-Mashine + parrallel laufendem 
Timmer besser zurecht kommt, ist auch Fraglich!

Gruß Volker

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Volker Zabe schrieb:
> mit State-Mashine + parrallel laufendem Timmer besser zurecht kommt
Uuuah...
Damit kommt er garantiert nicht besser zurecht!

Lies doch deinen Text vor dem Senden bitte noch einmal durch. Soviel 
Zeit muß sein...  :-/

von aa (Gast)


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)
                          ^              ^

von Arnold (Gast)


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

von aa (Gast)


Lesenswert?

Problem gelöst?

von aa (Gast)


Lesenswert?

Ich hasse solche Leute... RÜCKMELDUNG???

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.