www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Abbruch einer Schleife


Autor: Tobias Domhöfer (tobias92)
Datum:

Bewertung
0 lesenswert
nicht 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
  }

}

Autor: aa (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Volker Zabe (vza)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: aa (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Volker Zabe (vza)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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...  :-/

Autor: aa (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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)
                          ^              ^

Autor: Arnold (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: aa (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Problem gelöst?

Autor: aa (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hasse solche Leute... RÜCKMELDUNG???

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.