Hallo, ich habe folgendes Problem: Ausgangssituation: 5 ASCII Zeichen sollen seriell über das UART Protokoll in einer bestimmten Reihenfolge (Wert eines Sensors) von einem Mikrocontroller zum anderem Mikrocontroller übertragen werden. Realisiert wird dies mit zwei XMC2GO - Mikrocontrollern von Infineon. Die Übertragung erfolgt durch die UART 0 - DAVE 4 - APP: UART_Transmit(&UART_0, transmit,5); —> überträgt die ersten 5 Felder des Arrays „transmitt [ ]“. UART_Receive(&UART_0, receive, 5); —> empfängt diese 5 Byte und schreibt sie in die ersten 5 Felder „receive []“ Wie kann ich nun sicherstellen, dass der Empfänger auch wirklich beim ersten Byte beginnt, die 5 Zeichen zu speichern? Z.B. wenn Sender beginnt zu senden, bevor Empfänger aktiv ist. Die Methode mit einem Startbyte versuchte ich, jedoch ohne erfolg: Ansatz war: Sender: Sende Startbyte z.B. 0x02 Sende die 5 Datenbyte Empfänger: Empfange 1 Byte wenn Startbyte —>Empfange 5Byte—>schreibe auf LCD wenn nicht —>Schleife von vorne Was ich mir nicht erklären kann ist, wieso der empfangene Wert nach dem zweiten Empfang in der richtigen Reihenfolge abgelegt wird, obwohl beispielsweise durch kurzes ausstecken der TX Leitung, der erste Empfang noch nicht gepasst hat (verschoben war)? -->genau das will ich zwar erreichen, jedoch stimmt das erst beim 2. Empfang und ich weiß eben nicht wieso das überhaupt funktioniert. Vielen Dank schon mal im Voraus.
Willkommen in der wunderbaren Welt des Protokolldesigns... das mit dem framing machst Du schon ganz richtig, wobei Du selbstverständlich darauf achten musst, dass das Startbyte selber niemals im Nuztdatenstrom vorkommen kann (da gibt es Transposition o.ä. Mechanismen). Auf seriellen Schicht 1 Medien musst Du IMMER damit rechnen, dass Zeichen verloren gehen, deswegen ist ein framing unerlässlich. Wenn Du für alle Ewigkeiten sicherstellen kannst, dass jede Paketlänge immer 5 ist, kannst Du es beim Startzeichen belassen, aber wenn Du nicht mit jedem einzelnen Byte hadern musst, ist es für Zukunftskompatibilität empfehlenswert, den Frame zu erweitern (also entweder Frameendzeichen oder - wesentlich besser - Länge im Header schicken). Eine Checksumme über den frame ist bei seriellen Protokollen auch kein Fehler und kann graue Haare vermeiden helfen. Warum in diesem Fall erst die zweite Kommunikation hinhaut, kann man so aus der Ferne nicht beurteilen. Es ist nicht so etwas wie Autobauding in Effekt? Oder ist das zu Grunde liegende Medium vielleicht RS485 und es gibt Richtungsumschaltungsprobleme?
:
Bearbeitet durch User
Fabian K. schrieb: > Wie kann ich nun sicherstellen, dass der Empfänger auch wirklich beim > ersten Byte beginnt, die 5 Zeichen zu speichern? Durch Synchronisation zwischen Sender und Empfänger. Bei ASCII Zeichen ist das einfach, da die mit 7 Bit übertragen werden können. Indem du z.B. bei der Übertragung des ersten Bytes zusätzlich das achte Bit setzt und es beim Empfänger auswertest, läßt sich das einfach ohne zusätzlichen Protokoll-Overhead umsetzen.
Die einfachste Moeglichkeit waere natuerlich ein Startbyte das niemals in deinen Nutzerdaten vorkommt. Ist aber nicht immer zu realisieren. Naechster Ansatzpunkt, timing+Startbyte. Du kannst ja sicher davon ausgehen das die Zeit zwischen zwei Bytes deutlich kuerzer ist wie zwischen zwei Datenbloecken. Also sorge dafuer das dein Bytezaehler auf 0 zurueckgestellt wird wenn eine zu lange Zeit vergangen ist. Du kannst ausserdem nie sicher sein das bei einer Uebertragung ein Bit verfaelscht wurde. Also haenge an deine Bytes noch eine CRC16 an. Programmiere das ganze in einer Statemachine die im Zweifel immer auf den Anfang zurueckfaellt. So kannst du einen stabilen Empfang sicherstellen der sich im Zweifel immer neu syncronisiert. Zusaetzlich wuerde ich dir empfehlen ein Byte dafuer zu verschwenden einen Zaehler zu uebertragen der bei jedem Paket um eins incrementiert wird. So weiss der Empfaenger das er ein Paket verloren hat. Noch sehr viel klueger waere es allerdings wenn du dir nicht selber etwas ausdenkt sondern ein gaengiges Protokoll verwendest. Ein Beispiel waere dafuer Modbus. Der Grund ist das du dann fertige Standardsoftware verwenden kannst um deine Uebertragung zu testen. Olaf
Vielen Dank schon mal für die vielen schnellen Antworten. Da es sich nur um Zahlenwerte handelt, wäre es mit einem Startbyte problemlos möglich. In dem Fall war ich also schon mal auf der richtigen Spur. Allerdings hat das wie bereits gesagt bei meinem Versuch nicht funktioniert. Es kamen nur noch sehr wenige werte an und als erstes Zeichen wurde mir anstatt dem ersten Zahlenwert das Startbyte ausgegeben.Ich werde am Montag wenn ich Zeit habe meinen Code mal posten...
Ich war heute noch einmal dran... Mein Fehler war, dass ich nach dem senden des Startbits noch ein kurzes Delay einbauen musste. Jetzt funktioniert es. Ich würde jetzt jedoch vielleicht auch noch zusätzlich die Timing-Methode einbauen. Aber wie kann ich abfragen, wann das erste Byte kommt, um den Timer zu starten?
> Aber wie kann ich abfragen, wann das erste Byte > kommt, um den Timer zu starten? Du benutzt einen Hardwaretimer der dir eine nutzbare Zeitbasis schafft. Ausserdem empfaengt man Bytes im IRQ. Olaf
Bisher habe ich ohne IRQ empfangen... Dann versuche ich es jetzt mal mit einer IRQ, Vielen Dank.
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.