Forum: Compiler & IDEs Bufferverhalten beim Auslesen des UDR


von Sebastian (Gast)


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

von Peter D. (peda)


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

von Jakob B. (teddynator)


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.

von Sebastian (Gast)


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

von Karl H. (kbuchegg)


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

von Peter D. (peda)


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

von Günter R. (galileo14)


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.

von blubb (Gast)


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 :
1
if ( strncmp( buffer , PSR("TEST") , 4) == 0 )
2
  {
3
     // tuwas 
4
     buffer[0] = '\0' ;
5
  }

von Sebastian (Gast)


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.

von Günter R. (galileo14)


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").

von Peter D. (peda)


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

von Stefan B. (stefan) Benutzerseite


Lesenswert?


von Sebastian (Gast)


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?!

von Stefan E. (sternst)


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.

von Sebastian (Gast)


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

von Stefan E. (sternst)


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.

von Sebastian (Gast)


Lesenswert?

Stefan Ernst schrieb:
>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.

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.