www.mikrocontroller.net

Forum: Compiler & IDEs Bufferverhalten beim Auslesen des UDR


Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Freunde,

ich habe eine prinzipielle Frage zum Buffern von USART Daten.

Wenn ich Daten empfange speicher ich ersteinmal alles in einem Array 
zwischen und werte anschließend die Daten aus.

Wenn ich jetzt etwas auswerte bleiben die Daten im Buffer natürlich 
erhalten und so kann es kommen, dass ein Kommando in einer if-Abfrage 
natürlich ständig ausgeführt wird, obwohl ich das nur einmal wollte.

Ist es hier prinzipiell zu empfehlen, den Buffer nach dem lesen zu 
löschen? Es gibt sicher fälle wo man den mehrmals lesen möchte, aber wie 
geht man da normalerweise vor.

Man könnte sich auf der anderen Seite natürlich im Terminalprogramm 
ständig den eigentlichen Befehl senden und dann einen "lösch"-Befehl 
hinterher.

Ja.. das ist also meine Frage :-)

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sebastian schrieb:
> Wenn ich jetzt etwas auswerte bleiben die Daten im Buffer natürlich
> erhalten und so kann es kommen, dass ein Kommando in einer if-Abfrage
> natürlich ständig ausgeführt wird, obwohl ich das nur einmal wollte.

Dann hast Du einen Fehler in Deinem Programmablaufplan.

Wenn die Daten ausgewertet wurden, dann erkläre den Puffer für ungültig 
und lese die nächsten Daten ein.


Peter

Autor: Jakob B. (teddynator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich speichere den wert in eine Variable ab und lösche ihn dann aus dem 
udr. in der if abfrage setze ich ein beliebiges bit "abarbeitung 
erledigt" und beziehe es in die abfrage mit ein... also vom prinzip her:
"if ((received==0xff) & (abarbeitung erledigt == 0)){bit setzen; 
sonstiges;}"
variable lässt sich aber dennoch noch abfragen. aber nicht vergessen das 
bit wieder auf 0 zu setzen wenn beispielsweise ein neuer uart interrupt 
ausgelöst wird.

Nicht der beste Programierstiel, denk ich mal. Aber funktioniert.

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger schrieb:
> dann erkläre den Puffer für ungültig

bedeutet das löschen?

@ Jakob:

ich mache das ja im Prinzip auch so:

DATEN -> UDR -> RX_Buffer > Auswerten des Buffers

Und du setzt jetzt ein globales Flag um das einmalige Auslesen zu 
verifizieren. Interessant. Werd ich mal probieren wies damit klappt.

Danke

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sebastian schrieb:
> Peter Dannegger schrieb:
>> dann erkläre den Puffer für ungültig
>
> bedeutet das löschen?

Kann es bedeuten. Ja sicher. Ein Buffer in dem kein Text enthalten ist, 
wird schwer auszuwerten sein :-)

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sebastian schrieb:
> bedeutet das löschen?

Nein, man kann nichts löschen.

Wenn Du z.B. auf Deiner Festplatte eine Datei löschst, wird nur im 
Filesystem der belegte Bereich für ungültig erklärt, z.B. durch ein Bit.
Und wenn dann wieder neue Daten geschrieben wurden, wird das Bit wieder 
gesetzt.

Genauso kannst Du den Puffer verwalten.
Wann das neue Paket gültig ist, hängt von Deinem Protokoll ab.


Peter

Autor: Günter R. (galileo14)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Sebastian:

Du wirst doch in deinem Puffer (Array) irgendeine Art von Ende-Zeichen 
haben, das deiner Befehlsauswertung sagt, bis wohin die empfangenen 
Zeichen gehen (z.B. CR oder NULL). Und ein Pointer muß wohl auf die 
nächste freie Stelle im Puffer zeigen (das kann auch der Array-Index 
sein). Und dann muß wohl irgendein Flag da sein, das anzeigt, ob gerade 
Daten vom UART empfangen werden oder ob das Endezeichen schon 
eingetroffen ist und der Befehl ausgewertet werden kann.

Dann ist es wohl so, daß der Befehl ausgewertet wird, der Pointer danach 
wieder auf den Pufferanfang gesetzt und das Auswerteflag gelöscht wird. 
Den eigentlichen Pufferinhalt muß man nicht löschen, denn die Daten, die 
hinter der Pointermarke stehen, interessieren ja nicht.

Normalerweise gibt es keine Fälle, wo man mehrmals lesen möchte, denn 
der Befehl ist dann ja ausgeführt. Für Sonderfälle würde ich mir dann 
evt. spezielle Pufferinhalte gesondert irgendwohin kopieren, falls 
Bedarf dafür sein könnte.

Autor: blubb (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wenn man normale strings hat .. wa sspricht dagegen
buffer[0] = '\0' ;  zu setzen

alle anderen string funktionen in einer abfrage liefern hier ein 
negatives ergebnis
da das erste zeichen eine terminierung ist
also quasi :
if ( strncmp( buffer , PSR("TEST") , 4) == 0 )
  {
     // tuwas 
     buffer[0] = '\0' ;
  }

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Jungs,

mir is nach langem grübeln doch noch eine Frage gekommen.

Mein UDR hat 8bit. Mein gesendeter String besteht aus 3 Chars also 
24bit.

Wie macht der uc es, dass es trotz eines 8 bit Registers 24bit empfangen 
kann??

Meine Vermutung wäre ja, dass der uc durch das stop bit erkennt wann der 
erste char zuende ist und dann vor dem darauffolgenden bit diesen char 
in einen Buffer im z.B. SRAM schreiben muß. Hierbei würde auch die 
Geschichte mit der Baudrate Sinn machen.. und die müsste immer deutlich 
unter der Systemfrequenz liegen.

Autor: Günter R. (galileo14)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich denke, du mußt dich mal mit grundsätzlichen Fragen befassen, hier 
z.B. mit allgemeiner serieller Datenübertragung. Dabei erfährst du, daß 
immer Zeichen mit 8 Bit übertragen werden; wenn du einen String 
überträgst, so werden die einzelnen Zeichen des Strings nacheinander 
übertragen, unter  Zwischenschaltung von Start- und Stopbits, wie du 
schon richtig festgestellt hast (Stichwort "asynchrone serielle 
Übertragung").

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sebastian schrieb:
> Meine Vermutung wäre ja, dass der uc durch das stop bit erkennt wann der
> erste char zuende ist und dann vor dem darauffolgenden bit diesen char
> in einen Buffer im z.B. SRAM schreiben muß.

Dann mußt Du das so programmieren.
Die UART-HW setzt nur ein Flag, daß 1 Byte empfangen wurde.


Peter

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger schrieb:
> Die UART-HW setzt nur ein Flag, daß 1 Byte empfangen wurde.

Dann lese ich dies aus und zwar mindestens vor dem darauffolgenden 9. 
bit. richtig? So wirt das UDR durchs lesen gelöscht und die nächsten 8 
bit rutschen rein. Und wie gesagt muss das lesen aus dem UDR viel 
schneller sein als das Lesevorgang zwischen zwei seriell gesendeten 
bits.. oder?!

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sebastian schrieb:
> Dann lese ich dies aus und zwar mindestens vor dem darauffolgenden 9.
> bit. richtig? So wirt das UDR durchs lesen gelöscht und die nächsten 8
> bit rutschen rein. Und wie gesagt muss das lesen aus dem UDR viel
> schneller sein als das Lesevorgang zwischen zwei seriell gesendeten
> bits.. oder?!

Nein, UDR ist mehrfach gepuffert (ist in Wirklichkeit ein kleiner FIFO, 
kein einzelnes Register). Du hast also VIEL mehr Zeit zum Auslesen.

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan Ernst schrieb:
> Nein, UDR ist mehrfach gepuffert (ist in Wirklichkeit ein kleiner FIFO,
>
> kein einzelnes Register).

Ich hab's grad mal in der Doku nachgelesen:

The receive buffer consists of a two level FIFO. The FIFO will change 
its state whenever the
receive buffer is accessed.

Wenn mir jetzt noch jemand sagt wie groß der FIFO ist wäre ich wunschlos 
glücklich :-)

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sebastian schrieb:
> Wenn mir jetzt noch jemand sagt wie groß der FIFO ist wäre ich wunschlos
> glücklich :-)

> The receive buffer consists of a two level FIFO. The FIFO will change
> its state whenever the
> receive buffer is accessed.

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan Ernst schrieb im Beitrag #1507452:
>Autor: Stefan Ernst (sternst)
>Datum: 04.12.2009 13:56

>----------------------------------------------------------------------- ---------

>Steht normalerweise bei der UDR-Beschreibung.The receive buffer consists of a two 
>level FIFO.

>Dazu kommt dann noch das Input-Shift-Register, also 3 Bytes effektiv.


Die Antwort wärs gewesen. Trotzdem danke für deine damalige und jetzige 
Antwort.

P.S. Bei Level denke ich immer an Prinzen mit Schwertern und große, böse 
Endgegner.

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.