Hallo, ich tue mir gerade etwas schwer mit meinem UART Protokoll. Nach vielem Lesen von Beiträgen habe ich mich für mein erstes Protokoll für ASCII-Format Übertragung entschieden, da es sowieso nicht zeitkritisch ist und es einfacher und lesbar ist. Ich denke für ein Anfänger sicherlich nicht verkehrt, da auch alle Steuerzeichen zur Verfügung stehen und nichts substituiert werden muss. Mein Ziel ist es, vom PC aus Daten zu senden per RS232, die 8-bit und 16-bit Werte sind (natürlich vorher gewandelt in strings). Der µC (AVR Atmega88) soll die Daten aufnehmen und ins EEPROM schreiben/speichern. Implementiert habe ich die UARTlib von Peter Fleury mit FIFO Puffer. Also Protokoll habe ich mir derzeit folgendes überlegt: - µC Startet mit XON und gibt somit dem PC frei, dass er Daten senden kann. - Kommandobit: Auch case Unterscheidung, je nach Case, soll der Wert einer bestimmten Variable zugeordnet werden, z.B. case(1) = Wert in fooByte1, case(2) Wert in fooWord1, case(3) Wert in fooByte2 usw. - Daten - PC setzt seinen Status auf XOFF wartet bis er wieder ein XON erhält vom µC erhält für den nächsten Datensatz - µC holt die Daten aus dem Puffer und schreibt sie in das EEPROM. Wenn dies beendet ist, sendet er wieder XON Woher weiß der µC aber, wann aber z.B. das Kommandobit feritg übertragen wurde und wann Daten kommen und wann Daten zu Ende sind? Danke.
Thorben schrieb: > - µC Startet mit XON und gibt somit dem PC frei, dass er Daten senden > kann. Das ist eigentlich nicht Sinn der Sache bei XON/XOFF Warum soll denn der PC nicht ständig senden dürfen? Du hast doch mit der Fleury LIb sowieso eine FIFO dazwischen, die in den kurzen Pausen, in denen dein µC was anderes macht, die Zeichen zwischenzeitlich aufnimmt. > - Kommandobit: Wieso Bit? > Auch case Unterscheidung, je nach Case, soll der Wert > einer bestimmten Variable zugeordnet werden, z.B. case(1) = Wert in > fooByte1, case(2) Wert in fooWord1, case(3) Wert in fooByte2 usw. Du denkst schon viel zu technisch. > Woher weiß der µC aber, wann aber z.B. das Kommandobit feritg übertragen > wurde und wann Daten kommen und wann Daten zu Ende sind? Du bist nicht mehr mit Commandozeilen aufgewachsen, stimmts? Da wusste jeder, dass man an der Command-Line ein Kommando eingibt und wenn man fertig ist, drückt man auf Return. Return ist ein Zeichen wie jedes andere auch. Aber es signalisiert dem empfangenden Programm: Jetzt ist meine Eingabe fertig - du kannst anfangen sie auszuwerten. Der PC sendet zb den 'Text' Timeout=129<Return> Der µC sieht sich den Text an (nachdem er die Zeile komplett empfangen hat, was er am Erhalt des Return feststellt), zerlegt sie am '=' in 2 Teile, dem 'Timeout' und dem '129'. Durch Textvergleich findet er raus, dass bei 'Timeout' eine bestimmte Variable gemeint ist und dass die einen neuen Wert bekommen soll. Also wird der 2.te Text, "129" erst mal in eine Zahl umgewandelt 129, und diese Zahl dann an die Variable zugewiesen. Und wenn der PC die LED 5 einschalten will, dann schickt er vielleicht den Text LEDON 5<Return> etc. etc. Denk dir was aus, wie die Texte aussehen sollen. Wenn der PC wissen will, ob LED 3 eingeschaltet ist oder nicht, dann schickt er vielleicht ? LEDON 3<Return> Und der µC anwortet mit ON<Return> oder OFF<Return> oder 0<Return> oder 1<Return> oder wie auch immer. Da ist deine Phantasie gefragt. Ein HP7475 Plotter wird zb so gesteuert PU; PA3000,2000; PD; PA1000,2000;PA1000,1000;PU; hier ist also nicht <Return> der Trenner sondern ';'. PU bedeutet 'Pen Up' PD bedeutet 'Pen Down' PA bedeutet 'Position Absolut' wobei 2 Zahlenangaben zu machen sind, nämlich die X und die Y Position, an die der Stift fahren soll.
Karl Heinz Buchegger schrieb: > Warum soll denn der PC nicht ständig senden dürfen? Du hast doch mit der > Fleury LIb sowieso eine FIFO dazwischen, die in den kurzen Pausen, in > denen dein µC was anderes macht, die Zeichen zwischenzeitlich aufnimmt. Weil ich in das EEPROM schreiben will und das 2-4ms in Anspruch nimmt. Um einen Array mit 200 Stellen und 16-bit (den ich unter anderem senden will) werten zu übertragen, bräuchte ich daher doch einen großen Puffer (der PC sendet sicherlich schneller). Um den Überlauf des Puffers zu verhindern, wollte ich diese Flusskontrolle integrieren. Karl Heinz Buchegger schrieb: > Du bist nicht mehr mit Commandozeilen aufgewachsen, stimmts? Ja, das stimmt :-) Das mit Return verstehe ich nicht ganz. Wenn ich doch Variablenwerte sende, z.b. ein uint8_t test = 123, dann bekomme ich doch die Zeichenfolge '1' '2' '3' '\0' vom UART. Meinst du mit Return die abschließende 0? Wie sollte ich das nun am besten angehen?
Hey Torben, durch Return wird das Zeichen angehängt '\r'. Dann einfach das Empfangsregister immer nach diesem Zeichen mit if abfragen. Wenn TRUE dann weißt du wann er fertig ist.
Thorben schrieb: > Karl Heinz Buchegger schrieb: >> Warum soll denn der PC nicht ständig senden dürfen? Du hast doch mit der >> Fleury LIb sowieso eine FIFO dazwischen, die in den kurzen Pausen, in >> denen dein µC was anderes macht, die Zeichen zwischenzeitlich aufnimmt. > > Weil ich in das EEPROM schreiben will und das 2-4ms in Anspruch nimmt. Ja und? Dann schickt eben der PC das Kommando weg und wartet auf Antwort vom µC. Der PC schickt Timeout=129<Return> und der µC muss das Kommando mit einem OK<Return> quittieren. Und solange der PC das OK (oder ein NAK im Fehlerfall) nicht erhält, macht er nicht weiter.
Thorben schrieb: > dann bekomme ich doch die > Zeichenfolge '1' '2' '3' '\0' vom UART. woher soll denn die \0 kommen?
Thorben schrieb: > Um einen Array mit 200 Stellen und 16-bit (den ich unter anderem senden > will) werten zu übertragen, Kein Mensch sagt, dass du die 200 Werte in einem Rutsch übertragen musst. > sende, z.b. ein uint8_t test = 123, dann bekomme ich doch die > Zeichenfolge '1' '2' '3' '\0' vom UART. Du bekommst kein \0 von der UART. Woher soll denn die UART wissen, wann eine Übertragung fertig ist? Auch eine µC-UART kann nicht in die Zukunft schauen. > Meinst du mit Return die > abschließende 0? \r oder \n
Ok, soweit alles erst einmal verstanden für den Anfang. Das quittieren macht natürlich sind. Danke erstmal, ich versuche das mal so umzusetzen.
Karl Heinz Buchegger schrieb: > Thorben schrieb: > >> Um einen Array mit 200 Stellen und 16-bit (den ich unter anderem senden >> will) werten zu übertragen, > > Kein Mensch sagt, dass du die 200 Werte in einem Rutsch übertragen > musst. Dann gibt es eben zum Beispiel einen 'Datenblock', der mehrere Werte umfassen kann. Zb maximal 16 Werte Der PC schickt BLOCK 1; 0, 129, 512, 867, 378, 93, 93, 23, 0, 0, 8, 125, 12, 18, 14, 18<Return> Der µC empfängt die Zeile holt sich die Blocknummer vor dem ; raus (hier Block 1), extrahiert die 16 Werte und schreibt sie ins EERPOM, wobei ihm die Blocknummer sagt, wo die Werte hinmüssen. Wenn er damit fertig ist, schickt er ein OK<Return> zum PC zurück, woraufhin der ihm den nächsten Block schickt.
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.