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 :-)
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
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.
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
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 :-)
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
@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.
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 :
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.
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").
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
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?!
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.
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 :-)
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.
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.