Hallo, hat jemand einen Tipp (am besten mit Code-Beispiel), wie ich mit dem Hardware-UART eines MSP430F149 und einem GCC-Programm möglichst effektiv einen String unbekannter (bzw. variabler) Länge (z.B. 2 bis 50 Zeichen) empfangen kann, der vom PC über die RS232-Schnittstelle an den MC gesendet wird ? Die Zeichen sollen vom PC z.B. mit 9600 Baud direkt hintereinander (sozusagen als Block bzw. Zeichenkette) an den MC gesendet werden. Der String sollte MC-seitig zunächst in einen Puffer geschrieben und nach (erkanntem) Übertragungsende möglichst schnell vom Hauptprogramm ausgewertet werden. Der (interruptgesteuerte) Empfang von einzelnen Zeichen und das (interruptgsteuerte) Versenden von Strings beliebiger Länge mit dem MC klappt schon.
1.) Einen Protokollrahmen mit Start- und Endkennung definieren. Nach belieben erweitern um Längenbyte und Checksumme. 2.) Timeoutüberwachung: Timer beim ersten empfangenen Byte starten und nach jedem weiteren empfangenen Byte zurücksetzen. Nach dem letzten Byte wird der Timer weiterlaufen. Wenn ein definierter Timeout überschritten wird, ist die Übertragung beendet (oder ein Übertragungsfehler aufgetreten)
Danke, so ähnlich hatte ich es mir schon vorgestellt. Allerdings kann ich den empfangenen String ja erst nach dem Empfang und nicht während des Empfanges auf die Korrekthet eines ev. definierten Protokollformates prüfen. Der Knackpunkt ist wohl die Überwachung des Timeouts nach dem Empfang von Zeichen. Wenn der Timeout ein gewisses Limit überschritten hat (ev. abhängig von der Übertragungsrate), sollte davon auszugehen sein, dass die Übertragung des Strings beendet ist. Wenn da jemand ein funktionierendes Codebeispiel mit der Verwendung von TimerA oder TimerB des MSP430 hätte, könnte ich mir die Neuerfindung des (anfangs meist eher eckigen) Rades sparen.
>Allerdings kann ich den empfangenen String ja erst nach dem Empfang und >nicht während des Empfanges auf die Korrekthet eines ev. definierten >Protokollformates prüfen. Wieso nicht? Berechnest Du nebenher noch 'ne FFT? Bei 9600bd langweilt sich Dein µC doch nur ;-)
In die Prüfsumme des vorgesehenen Protokolls geht die Länge des Strings mit ein, daher kann die Korrektheit erst nach der vollständigen Übertragung überprüft werden.Die Zeichen werden auch bei einer Übertragungsrate von "nur" 9600 Baud schnell hintereinander übertragen und es erscheint mir daher zweifelhaft, ob eine Überprüfung während der Übertragung sinnvoll ist.Zudem möchte ich mir die Option offen halten, später auch mit höheren Übertragungsraten zu arbeiten.Die Erkennung einer abgeschlossenen Übertragung sollte zweckmässigerweise also wohl über einen Timeout erkannt werden. Vielleicht hat ja jemand dafür ein in der Praxis erprobtes Codebeispiel für den Hardware-UART des MSP430, das mit geeigneten Timer-Interrupts arbeitet.
Du sollst ja auch nicht Korrektheit überprüfen, sondern lediglich erkennen ob ein Startbyte ankam -> Beginn einer Übertragung oder ein Stopbyte -> Ende der Übertragung. Mit Hilfe eines eventuellen Längenbytes könnstest Du einen Zähler zur Kontrolle mit aufziehen. Timeout ist trotzdem notwendig, sonst wartest Du bei einem Fehler womöglich ewig auf ein Stopbyte!
Mindestens ein definiertes Startbyte macht aus meiner Sicht Sinn. Ein Stopbyte eher nicht, denn das dürfte dann ja nicht innerhalb der Zeichenfolge vorkommen und da es sich auch um variable Daten handeln kann, wäre das eine problematische Einschränkung (die mit zusätzlichem Aufwand natürlich wieder aufgehoben werden könnte). Aber da ich ja sowieso einen Timeout am Ende brauche, ist das Stopbyte entbehrlich und die korrekte Übertragung (incl. Länge, etc.) kann ja mit der Auswertung des empfangenen Strings im Hauptprogramm verifiziert werden.
Wir benutzen für sowas fast immer das recht simple Protokoll, was der LMX9820 verwendet.
>> nach (erkanntem) Übertragungsende möglichst schnell vom Hauptprogramm
ausgewertet werden.
... aber vor dem Erkennen des Übertragungsendes in aller Ruhe auf das
Timeout warten ...
Ist die Sendepause zwischen zwei Strings garantiert größer als die
größte zulässige Pause zwischen zwei Zeichen eines Strings?
Ist das ASCII-Zeichen ETX (End of TeXt) wirklich nicht als Teil des
Strings auszuschließen bzw. bedeutet es überhaupt was anderes, falls es
dort vorkommt? Oder nachdem es ohnehin in C programmiert wird, bietet
sich das ASCII-Zeichen Null an.
Wenn du aus Geschwindigkeitsgründen beim Empfang die Buffergröße nicht
jedesmal überprüfen willst:
1 | char buffer[64]; |
2 | uint8_t ii; |
3 | #define BUFFER_MASK (64-1)
|
4 | |
5 | ...
|
6 | buffer[(ii & BUFFER_MASK)] = xyz; |
7 | ...
|
dann kannst du nur noch den eigenen String überschreiben, der restliche Speicher bleibt bei einem Buffer-Überlauf sicher. (Buffer-Länge muß dafür eine Zweier-Potenz sein.)
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.