PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Serielle Verbindung: Wie auf Bytes synchronisieren?



bjoerng
23.08.2011, 12:30
Hallo Ihr,

nachdem ich Wikipedia etc. gewälzt habe ohne Ende und keine Antwort gefunden habe, frag ich mal hier. Ich will auf meinem ATtiny13 eine serielle Datenübertragung (TTL-Level-RS232) implementieren. (Ja, gibt's schon als Codebeispiel, ich wollte es aber zum Lernen gerne selbst machen, und ist ja grundsätzlich auch nicht so schwer.)

Was ich noch nicht verstanden habe, ist die Synchronisation auf Byte-Ebene: Wie finde ich in einem längeren Bitstrom heraus, was das Start- und was das Stopbit ist? Gerade dadurch, daß die Pause zwischen Start- und Stopbit Null sein kann. Nehmen wir an, der Kommunikationspartner schickt ständig Bytes mit dem Binärwert 10101010. Füge ich ein Startbit (0) und ein Stopbit (1) an, ergibt sich ein kontinuierlicher Strom 01010101010101010101... Wo finde ich hier den Anfang?

Danke im Voraus!
Björn

Che Guevara
23.08.2011, 13:04
Hallo,

ich hatte vor einiger Zeit das gleiche Problem und hab mir damit beholfen, dass ich ein Startbyte eingeführt habe. Dieses Byte hatte einen Wert, welcher von den anderen Bytes niemals erreicht werden konnte. Somit wartet mein Programm immer auf diesen Wert, um sich von selbst zu Synchronisieren.

Gruß
Chris

bjoerng
23.08.2011, 14:14
Nein, das reicht nicht bzw. ist die zweite Stufe -- ich will ja wissen, wo ich in einem Bitstrom den Anfang der Bytes finde. Solange ich den nicht kenne, kann ich auch den Wert der Bytes nicht bestimmen und also auch das Startbyte nicht erkennen. Wenn ich aus dem Bit- erstmal sauber einen Bytestrom gemacht habe, brauche ich noch ein Startbyte.

Che Guevara
23.08.2011, 15:11
Wenn du ganze Bytes überträgst, kannst du doch auch nur an jedem Anfang die Syncronisation starten. Der Lese Befehl braucht ja schließlich ganze Bytes, oder hast du dir da etwas selbst geschrieben, was bits empfängt?
Alternativ kannst du auch eine best. Bitfolge als Start/Stop befehle definieren, du musst nur darauf achten, dass diese Bitfolge sonst nicht vorkommen kann! Mit nur einem Bit wirds schwierig, das würde ich höchstens mit einem zweiten Pin (Int) machen, aber ich würde schon mehrere Bits als Start/Stop Kondition verwenden.

Gruß
Chris

EDIT:
In welcher Sprache willst du dass den machen?

Richard
23.08.2011, 15:32
Nein, das reicht nicht bzw. ist die zweite Stufe -- ich will ja wissen, wo ich in einem Bitstrom den Anfang der Bytes finde. Solange ich den nicht kenne, kann ich auch den Wert der Bytes nicht bestimmen und also auch das Startbyte nicht erkennen. Wenn ich aus dem Bit- erstmal sauber einen Bytestrom gemacht habe, brauche ich noch ein Startbyte.


Du sendest ja 10 0der 11 (bei 2 Stop) Bits 1 Start 8 Data 1 oder 2 Stop Bit. Nach 10 0der 11 Bit ist ein Byte fertig das musst Du halt festlegen. :-) Wenn jetzt mitten im Byte gestartet wird kommt halt Müll dafür wurde CRC erfunden. Das selber basteln ist möglich aber nicht empfehlenswert, Hartware RS 232 fragt jedes BIT ca. 16 x ab ob es H oder L ist, bei mehr H als L gild das Bit dann als H sonst als L. Mit ASM habe ich es allerdings nur so gemacht.....

1 Länge vom Startbit ermitteln + 1/2 der Zeit dann nächstes Bit (in der Mitte testen) + Startbit Zeit nächsten Bit (in der Mitte Testen)............ Durch die Startbit Zeit hatte ich babei gleich eine Automatische Baudraten Erkennung. Mühselig das überläßt man besser die Hartware. :-) Nach 10 Bit kommt das nächste Start Bit.....
Hat super geklappt. :-)

Gruß Richard

bjoerng
23.08.2011, 15:57
Wenn jetzt mitten im Byte gestartet wird kommt halt Müll dafür wurde CRC erfunden.

Genau das ist mein Problem. Wenn mitten im Byte gestartet wird, kommt Müll -- das kann ich aber erst eine Ebene höher erkennen und dann bitten, daß die unterste Schicht auf die nächste steigende Flanke als Startbit aufsetzen soll. RS232 erkennt das aber irgendwie direkt, und ich verstehe nicht, wie das möglich sein soll.

Richard
23.08.2011, 16:19
Genau das ist mein Problem. Wenn mitten im Byte gestartet wird, kommt Müll -- das kann ich aber erst eine Ebene höher erkennen und dann bitten, daß die unterste Schicht auf die nächste steigende Flanke als Startbit aufsetzen soll. RS232 erkennt das aber irgendwie direkt, und ich verstehe nicht, wie das möglich sein soll.

jede Übertragung hat einen Anfang Ende Pause Anfang... wenn schön mit gezählt wird klappt das sehr gut, jedenfalls damals bei mir. :-) ansonsten suche einmal nach
Bit-Arbitrierung mir ist das etwas zu hoch...:-) Unter http://de.wikipedia.org/wiki/Controller_Area_Network ist da etwas zu verlinkt.

Gruß Richard

PicNick
23.08.2011, 17:27
Du müsstest nach jedem potentiellen Start-Bit ( 1-->0 Übergang ) schauen, ob das 10-Bit dann eine Stoppbit (1) sein kann. Das müsstest du theoretisch machen, bis du keine Framing-Errors mehr dazwischen hast (wo das eben nicht der Fall ist).

Ist aber IMHO eine recht theoretische Situation. Meistens werden ja doch sowas wie Messages gesendet, und wenn zwischen zwischen solchen messages auch nur 1 Byte lang Pause ist, ist dein Quer-einsteiger-empfänger schon wieder dabei.

Übrigens, wenn z.B USASCII gesendet wird (Text ), ist auch der Stopp-Bit-übergang immer 0-->1

Besserwessi
23.08.2011, 20:06
Wenn die Daten mit nur 1 Stopbit und ohne extra Pausen gesendet werden, kann man Pech haben und es dauert eine ganze Weile bis man die richtigen Startbits gefunden hat. Je nach den übertragenen Daten verschiebt sich das angenommene Startbit etwas, bis man an der richtigen Stelle landet. Bei 2 oder mehr Stopbits geht es schneller und braucht höchstens 8 - 10 Bytes bis man richtig liegt.

PICture
23.08.2011, 20:23
Hallo!

Ich habe mal mehrere Bits ohne Start- und Stopbits dazwischen versendet, wobei im ersten Byte wurde die Anzahl der nachfoldenden Bits kodiert (1 bis FFh). Die Pakete ("bursts") haben natürlich am Anfang und Ende Start- und Stoppbits und bei mehreren nötige Pausen dazwischen. ;)

Klebwax
23.08.2011, 23:04
Was ich noch nicht verstanden habe, ist die Synchronisation auf Byte-Ebene: Wie finde ich in einem längeren Bitstrom heraus, was das Start- und was das Stopbit ist? Gerade dadurch, daß die Pause zwischen Start- und Stopbit Null sein kann. Nehmen wir an, der Kommunikationspartner schickt ständig Bytes mit dem Binärwert 10101010. Füge ich ein Startbit (0) und ein Stopbit (1) an, ergibt sich ein kontinuierlicher Strom 01010101010101010101... Wo finde ich hier den Anfang?

Hallo,

zuverlässig geht das garnicht. Deswegen wird RS232 für "ernsthafte" Datenübertragung auch nicht verwendet. Man kann aber versuchen, ein solches System zuverlässiger zu machen. Dazu gehört als erstes, Framingerrors zu erkennen und ernst zu nehmen. Hardware UARTs haben dafür ein Status Bit. Framing Error heißt, daß an der erwarteten Stelle kein Stopbit ist. Dann muß das bisher empfangene Byte verworfen werden. Auch Parity hilft, einen Synchronisationsfehler zu erkennen, wird aber nur noch selten verwendet.

Das wichtigste ist aber, das der Sender ab und an Pausen länger als ein Byte macht. Bei interaktiven Systemen wie einem Terminal stellt sich das von alleine ein, eine Seite sendet und wartet dann auf eine Antwort. User machen so was eigentlich automatisch, solage Return drücken bis ein Prompt erscheint. Bei autonomen Systemen gibt es aber immer wieder Schwierigkeiten. Es gibt dort keine Garantie, das der Empfänger nicht erst gestartet wird, während der Sender schon aktiv ist. Dewegen wird gerne zu einem Modem (was immer das heute auch ist, GSM z.B.) solage "AT" geschickt, bis ein "ok" zurück kommt. Erst dann werden ernsthafte Daten geschickt.

All das muß die Software erledigen. Bei anderen "Kurzstreckenprotokollen" wie I2C oder SPI erledigt das die Hardware selbst. Ein I2C Empfänger, der mitten in einer Übertragung gestartet wird, wartet auf ein "BUS IDLE", bevor er empfängt. SPI wartet, bis CS von inaktiv auf aktiv wechselt. Halbe Frames werden also garnicht empfangen. Ähnliche Mechanismen gibt es bei Ethernet, HDLC und den anderen Protokollen.

MfG Klebwax