Guten morgen zusammen, ich habe gestern meine ersten Zeichen per UART an HTerm gesendet (Controller Atmega88 mit einem FT232RL USB->Serial Konverter). Mein eigentliches Ziel ist es, Daten von einem Programm am PC (zunächst erstmal manuell von HTerm) an den µC zu senden und dort dann in das EEPROM zu speichern. Gesendet werden soll 1 Array mit 200 Stellen (Variablen darin 16-bit signed) und ein paar kleine Konfig-Variablen (8-bit unsigned) Der UART kann ja nur 8-bit in einem Rutsch übertragen. Also muss ich die Variable zerlegen durch maskieren und immer erst das MSB oder LSB senden und dann eben das andere und am µC in der richtigen Reihenfolge durch 8faches schieben wieder durch Veroderung der beiden zusammenbasteln in eine Variable. Soweit habe ich das aus der Suche mal verstanden. Der Empfang geschieht natürlich per Interrupt, um nichts zu verpassen. Ich dachte ich puffere dies und schreibe es im Hauptprogramm dann in das EEPROM, da die Schreibzugriffe hier ja nicht sonderlich schnell sind. Jetzt ist meine Frage, wie baue ich das Protokoll auf. Habe ich der Suche ebenfalls richtig entnommen, dass man eine 8-bit Zahl am besten in ein ASCII-Zeichen konvertiert, welche dann als 1 Zeichen gesendet werden kann und der µC das wieder rückkonvertiert zu einer Zahl und diese speichert? Wie stelle ich fest, dass keine Zahl verloren geht bzw. wäre es ja fatal, wenn beispielsweise ein MSB verloren geht, dann verschiebt sich ja alles um 1 Byte. Ich habe leider keinen Portpin mehr frei um das im Handshake zu machen, daher wäre hier enie Software Prüfung besser. Wie macht man das in der Regel, sendet man 1 Character der signalisiert das nächste Byte ist MSB und einen anderen der signalisiert das nächste ist LSB? Wie trage ich dafür sorge, dass alles an der richtigen Stelle im EEPROM gespeichert wird? Schickt man die Stelle irgendwie passend zur Variable mit (den Array zählt man sinnvollerweise durch hätte ich gesagt, aber wie macht man es bei den Konfig-Variablen, die teilweise nicht nacheinander im EEPROM liegen)? Ich weiß, das sind jetzt vielleicht ein paar viele Fragen, aber vielleicht hat der ein oder andere ein bisschen Zeit hier Erfahrung zu teilen. Danke.
Zahlen nach ASCII zu konvertieren ist Blödsinn, es sei denn, Du willst sie auf einem PC in einem terminal-Programm anschauen. Übertrage das Array so wie es ist. Als Kontrolle kannst Du die Länge des Arrays mitübertragen, eine Checksum über alle Bytes anhängen, denk Dir einfach was sinnvolles aus. Eine Steinzeitmethode wäre z.B. ein Byte zu senden, der µC muß es zurücksenden, danach wird erst das nächste Byte gesendet. Geht ist langsam, aber wenns Du Angst vor Datenverlusten hast (wieso eigentlich, wenn das Design gut ist?), dann wär das eine Methode, die beruhigt.
Hier mal zum Vergleich 2 Varianten: 1. ASCII-Kodierung Vorteil: es lässt sich einfach ein relativ sicheres Protokoll realisieren, da Du eindeutige Steuerzeichen zur Verfügung hast (z.B. STX als Beginn usw.). Nachteil: >= doppelte Länge des Datensatzes 2. Code-Transparent Vorteil: kleine Datensatzlänge Nachteil: ein Protokoll ist schwieriger zu realisieren. Erkennung von Beginn des Datensatzes oder Verlust von Daten muss z.B. durch Messung der Zeiten zwischen 2 UART-Zeichen erfolgen. Das bedeutet dann für den Sender: zwischen 2 Datensätzen ist immer eine Pause erforderlich, innerhalb des Datensatzes ist keine oder nur ein deutlich kleinere Pause erlaubt. In beiden Fällen ist aber immer eine Time-Out-Erkennung nötig, um eine Unterbrechung des Datenstroms zu erkennen. Weiter Datensicherungen sind dann nach Bedarf und Geschmack: Checksum gegen Bitverfälschungen, Quittung gegen Datenverlust ... Das hängt dann davon ab, wie störanfällig die Übertragung ist und welche Ansprüche an die Datensicherheit gestellt werden. Problematisch ist in jedem Fall eine variable Datensatzlänge, da Fehler schwieriger zu erkennen sind. Sie sollte daher nach Möglichkeit vermieden werden. Gruß Dietrich
Martin schrieb: > Jetzt ist meine Frage, wie baue ich das Protokoll auf. Habe ich der > Suche ebenfalls richtig entnommen, dass man eine 8-bit Zahl am besten in > ein ASCII-Zeichen konvertiert, welche dann als 1 Zeichen gesendet werden > kann und der µC das wieder rückkonvertiert zu einer Zahl und diese > speichert? Ja, am besten denkst Du Dir ein "Message" basiertes Protokoll aus, wobei diese Message in sich geprüft werden kann. Wenn Du beispielsweise ein Array mit 200 Integer-Werten übertragen möchtest, könnte eine zu übertragende Message z.B. so aussehen: Startbytes - 2 Bytes (zwei beliebige Werte nach Deiner Wahl) Messagelänge - 2 Bytes (die Anzahl der nachfolgenden Bytes als Integer) Nutzbytes - 400 Bytes (die 200 zu übertragenden Integer-Werte) Prüfsumme - z.B. 4 Bytes (die 200 Integer-Werte als Long-Integer aufsummiert) Die Empfangsroutine lauert in Sendepausen nun immer darauf, ob die beiden Startbyte ankommen, und danach müssen in schneller Folge alle anderen Bytes eintreffen. Tritt ein Timeout auf, lauert der Empfänger einfach wieder auf die nächsten Startbyte nach einer Sendepause. Programmlogik des Empfängers dann etwa so: - Empfange erstes Startbyte - Wenn erstes Startbyte OK, weitermachen, sonst zurück auf Anfang - Empfange zweites Startbyte - Wenn zweites Startbyte OK, weitermachen, sonst zurück auf Anfang - Empfange Längenwert und fange an zu zählen bei 0 - Empfange Nutzbytes und zähle die Zahl der empfangenen Bytes mit - Empfange Prüfsumme und zähle die Zahl der empfangenen Bytes mit - Wenn alle Bytes entsprechend der Länge empfangen, prüfe die Prüfsumme - Wenn Prüfsumme OK, dann Daten einwandfrei empfangen - Wenn Prüfsumme nicht OK oder ein Timeout beim Empfangen auftrat ==> Daten verwerfen Falls irgendwo beim Messageempfang ein Timeout auftritt: Zurück auf Anfang. Du müßtest dann eben nur die beiden Startbytes festlegen, die Art wie die Prüfsumme (oder ein CRC-Wert) gebildet wird und wie lang der zeitliche Abstand zwischen zwei Bytes innerhalb eines Message-Blocks sein darf (Timeout-Zeit).
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.