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 :
1 | if ( strncmp( buffer , PSR("TEST") , 4) == 0 ) |
2 | {
|
3 | // tuwas
|
4 | buffer[0] = '\0' ; |
5 | }
|
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
blubb schrieb: > if ( strncmp( buffer , PSR("TEST") , 4) == 0 ) strncmp_P Beitrag "strncmp_P <-> memcpy" http://www.cs.mun.ca/~paul/cs4723/material/atmel/avr-libc-user-manual-1.6.5/group__avr__pgmspace.html#g8283f9a987be92ae137ee610e6b11b90
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.