Hallo zusammen, da ich auf keine grünen Zweig komme, möchte mal fragen wie ihr so etwas machen würdet: Aufbau: Ein 90S2313 sendet über UART fünf Bytes im Sekundentakt, ein zweiter 90S2313 empfängt diese. So weit so gut. Diese fünf Bytes bedeuten 1.byte = Startbyte 2.byte = Temperatur 3.byte = Anlagenstatus 4.byte = ist immer null 5.byte = ist immer 255 Der Empfang funktioniert. Nun möchte ich das 3.Byte auswerten. Nun kann es aber sein, das der Empfänger gerade dann eingeschaltet wird, wenn der Sender gerade schon sendet (also das die ersten bytes schon abgeschickt sind). Wie kann man nun die Empfangenen Bytes daraufhin überprüfen, das Byte3 auch wirklich byte3 ist und nicht irtümlich Byte4 als Anlagenstatus ausgewertet wird? Danke für jeden Tip!
Ganz einfach. Du hast ja ein Startbyte! Mit diesem kannst (musst) du synchronisieren, d.h. wenn du das Startbyte empfängst setzt du einen Zähler auf 0 und zählst dann die eintreffenden Bytes. Du musst aber dafür sorgen, dass die folgenden Bytes niemals den Wert des Startbytes annehmen können, z.B. indem du beim Sender einen Offset addierst, welchen du dann beim Empfänger wieder subtrahierst. Als Startbyte verwendet man üblicherweise Hex 0x02, welches auch als STX bezeichnet wird. Falls du es ganz genau machen willst kannst du am Ende des Telegramms noch ein Hex 0x03 (ETX) anhängen. Gruss Christian
so isses, immer schöne frames bilden. und statt 00 und 0xff würde ich lieber ein Prüfsummenbyte schicken, so hat der Empfänger die Möglichkeit, Übertragungsfehler zu erkennen. Solltest du Probleme haben, das Startbyte eindeutig zu haben (weil die Datenbytes denselben Wert annehmen können) wandle die Datenbytes in 2 Hex-Ascii-Bytes um. Bsp: zu sendendes Datum 0x28, sendest du 0x32 (ASCII '2'), 0x38 (ASCII '8'). Mit diesem Verfahren hast du den ganzen Bereich unter 0x30 für eindeutige Steuerzeichen zur Verfügung.
Einfach genial! Ich glaub' ich nehme beide Tips und vereinige sie im Prog. Dankeschön!
Wenn die Daten nur jede 1s kommen, kann man auch einen Timer aufsetzen. Dann muß man nur die 2 Datenbytes senden: Wenn ein Byte empfangen wird, wird ein Timer gestartet. Wird dann das 2.Byte nicht innerhalb von 10ms empfangen, dann war das ein Fehler. Ansonsten hat man die 2 Bytes und wertet sie aus.´ Das ist eine sehr einfache und gebräuchliche Methode. Wichtig ist eben nur, daß die minimale Zeit zwischen 2 Paketen immer länger ist, als die maximale Zeit zwischen 2 Bytes eines Pakets. Peter
sicher, das geht, aber gebräuchlich würde ich das nicht nennen. Solche Sachen sind immer empfindlich gegen nachträgliche Änderungen, wer weiß schon, was alles noch kommt. Irgendwann wird die Übertragungsrate erhöht (50x/s), weitere Daten kommen hinzu,die Baudrate muß erniedrigt werden (lange Strecke) usw. Saubere Frames basteln ist meiner Meinung nach immer die bessere Lösung.
hi, die methode von peter d. benuetze ich auch.ist vollkommen angemessen fuer diesen fall. wenig software ....und wer braucht schon einen traegen temperaturwert 50x /sekunde? lange leitungen,niedrige baudrate ...wo gibt es da probleme? stx , etx und womoeglich bcc sind in diesem fall uebertrieben. ..aber: jedem tierchen sein plaesierchen. ciao
Zum Thema "Saubere Frames": Wenn man spezielle Steuerbytes definiert, dürfen diese dann aber auch nie in den Daten enthalten sein ! Deshalb wird STX, ETX, CR, LF, usw. nur bei Textübertragung benutzt, d.h. wenn die Datenbytes immer >=20h sind. Müssen echte Binärdaten übertragen werden, wird das schon komplizierter. Peter
Korrekt. Zum Thema Steuerzeichen: siehe oben Ist wirklich eine Binärübertragung nötig (hat letzlich die höchste Nutzdatenrate) benutze ich die 9bit-Übertragung (Steuerbytes aller Art mit TB8=1, Nutzdaten TB8=0) Ich will hier keinen Glaubenskrieg entfachen, alles hat seine Vor- und Nachteile. Aber die Sache mit der Zeitsynchronisierung KANN anfällig werden, und mit meiner bevorzugten Methode spare ich mir, über solche Sachen überhaupt nachdenken zu müssen. Die Routinen dafür sind fertig, warum also soll man sich solche Hilfskrücken antun? mfg crazy horse
Hallo, um ganz sicher zu sein ob die empfangenen Daten auch mit den gesendeten übereinstimmen reicht ein Parity oder auch eine Prüfsumme nicht aus. Mehrfachfehler in beiden Byt's werden nicht erkannt. Für fehlerfreie Steuerdaten übertrage ich einen Block 3 mal und vergleiche die im Empfänger. Das alle drei falsch sind und trotzdem übereinstimmen ist noch nie vorgekommen. MfG Manfred Glahe
Quatsch, alles viel zu kompliziert und eingeschränkt! Daten werden sauber in ein Frame gepackt: "DLE STX Daten DLE ETX" Kommt in den Daten ein DLE vor, wird es verdoppelt. Ausgelesen und ausgewertet wird ein solcher Frame durch einen Automaten: sercom_tlg_len: Telegrammbyte-Zaehler EmpfangenesTlg[]: Telegrammpuffer recByte: Empfangenes Byte von der Schnittstelle Initialisierung: state_receive = 0; // Dieser Automat wird jedes Mal beim Empfang eines Zeichens aufgerufen switch (state_receive) { case 0: if (recByte == DLE) state_receive = 1; break; case 1: if (recByte == STX) {state_receive = 2; sercom_tlg_len = 0;} else if (recByte != DLE) state_receive = 0; break; case 2: EmpfangenesTlg[sercom_tlg_len++] = recByte; if (DLE == recByte) state_receive = 3; break; case 3: if (recByte == DLE) { state_receive = 2; } else if (recByte == ETX) { // Ende-DLE wieder entfernen sercom_tlg_len--; // Telegrammdaten koennen ausgewertet werden //... state_receive = 0; } break; default: state_receive = 0; break; }
Hi! Ich verwende im folgendes Prinzip bei solchen Sachen: Ich empfange ein Byte, und schiebe es in ein Byte-Schiebe-Register, das in diesen Fall 5 Bytes lang wäre. Dann schau ich immer bei jedem Empfang nach, ob Die Bytes wie Start und Stop-Bytes korrekt sind. Bei dem Beispiel wären es das Byte 1, 4 und 5. Und wenn das der Fall ist, dann kannst du ja das Byte 2, und 3 exakt auslesen. mfg Weinga-Unity
Richtig, Oliver K. Das ist die Lösung, die ich seit Jahren in professionellen Produkten einsetze (mit 16bit CRC hinten dran). Bei so einem Frame erkent man das Ende, egal wann man in die Übertragung einsteigt.
Die Methode mit dem Timeout hat den riesen Vorteil, daß, wenn jemand übers Kabel stolpert und es dann wieder reinsteckt, der Timeout sofort zuschlägt und die Gefahr erkannt und gebannt hat. Bei einer Frame-Statemaschine dagegen, kann diese für immer hängenbleiben oder ein halbes altes Paket mit einem halben neuen fehlerhaft zusammenbasteln. Für absolut maximale Geschwindigkeit sendet man die Bytes im TX-Interrupt mit höchster Priorität (PS = 1) direkt hintereinander und wartet immer eine Bytezeit zum nächsten Paket (160*Timer T1 Überlauf). Der Empfänger zählt dann auch die T1-Überläufe und erkennt irgendwo zwischen 160 < x < 320 (z.B. bei 255) das Ende eines Pakets. Lange, kurze oder variable Pakete und Änderung der Baudrate haben da überhaupt keinen Einfluß. Ob man bei langen Paketen und langen Leitungen auch noch eine CRC mit ins Paket aufnimmt oder andere Fehlererkennungsmethoden, ist eine ganz andere Sache. Denke mal, daß Ingo vorerst auf sowas verzichten kann. Wenns erstmal läuft, kann man sowas ja immer noch einfügen. Peter P.S.: PS und T1 beziehen sich auf eine 8051-Architektur.
> Bei einer Frame-Statemaschine dagegen, kann diese für immer hängenbleiben oder
ein halbes altes Paket mit einem halben neuen fehlerhaft zusammenbasteln.
Nein. Sie bleibt nicht hängen. Lediglich auf einen Pufferüberlauf muß
man achten, falls ein Telegramm abgeschnitten wird und ein neues (als
ein nicht neu erkanntes Telegramm) den Puffer weiter füllt.
Das Erkennen, ob ein gültiges Telegramm empfangen wurde, wird in der
Auswertung der Daten vorgenommen. Wie schon Jens schrieb, ist ein 16-Bit
CRC eine gute Lösung.
Grüße
Oliver
Ups! Beim kopieren der Routine ist mir ein Fehler passiert. Case 3 muß so sein:(//!!!!!!!) Damit kann sich der Automat bei einem Fehler wieder synchronisieren. case 3: if (recByte == DLE) { state_receive = 2; } else if (recByte == ETX) { // Ende-DLE wieder entfernen sercom_tlg_len--; // Telegrammdaten koennen ausgewertet werden //... state_receive = 0; } else state_receive = 0; //!!!!!!!!!! break;
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.