Forum: Mikrocontroller und Digitale Elektronik UART: Regel für SYNC-Byte?


von Detlev T. (detlevt)


Lesenswert?

Hallo Leute,

eine Frage an die "Theoretiker" unter euch.

Ich möchte mehrere Bytes via UART übertragen. Das heißt, ich muss 
feststellen können, dass es sich (vermutlich) um das erste Byte eines 
Frames handelt. Das macht man üblicherweise mit einem bestimmten Wert 
("SYNC-Byte").

Frage: Gibt es irgendwelche mathematische Theorien, um ein möglichst 
optimalen Wert zu wählen? 0x00 und 0xFF sind sicher nicht geeignet, aber 
welche sonst?

Die Nebenbedingungen sind:
 - Es handelt sich um einen Bytestrom (keinen Bitstrom)
 - Jeder Wert - von 0x00 bis 0xFF - kann in den Nutzdaten vorkommen
 - Ob es sich tatsächlich um einen gültigen Frame handelt wird am Ende 
mittels CRC-Prüfsumme festgestellt.

Mein Bauchgefühl sagt mir, man sollte eine Kombination kurzer und 
längerer 0/1-Längen nehmen, z.B. 0x3A = [0]00111010[1] (mit Start- und 
Stopbit). Kann das jemand bestätigen/berichtigen?

Vielen Dank für eure Hilfe.

Gruß, DetlevT

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Detlev T. schrieb:
>  - Jeder Wert - von 0x00 bis 0xFF - kann in den Nutzdaten vorkommen
> Gibt es irgendwelche mathematische Theorien, um ein möglichst
> optimalen Wert zu wählen?
Garantiert, aber wenn du in deinem Datenstrom jedes Byte und jede 
beliebige Bytereihenfolge in gleicher Häufigkeit haben kannst, dann ist 
jede Sync-Kennung gleich gut und gleich schlecht...

Dann da reicht prinzipiell ein einziges Byte nur für eine 
Wahrscheinlichkeit von 1/256, dass du das richtige Sync-Byte gefunden 
hast.

> Mein Bauchgefühl sagt mir, man sollte eine Kombination kurzer und
> längerer 0/1-Längen nehmen, z.B. 0x3A = [0]00111010[1] (mit Start- und
> Stopbit). Kann das jemand bestätigen/berichtigen?
Das wäre wohl eher eine Beruhigung für deinen Bauch, als ein wirklicher 
Grund.

> Das heißt, ich muss feststellen können, dass es sich (vermutlich) um
> das erste Byte eines Frames handelt. Das macht man üblicherweise mit
> einem bestimmten Wert ("SYNC-Byte").
Oder gleich mit einem Sync-Word (16-Bit), bzw. einem noch längeren 
Sync-Pattern (aka Magic-Code 0xAA,0x55,0xAA...)...

Die sicherste Methode wäre aber, einen bestimmten Wert nicht zur 
Datenübertragung zu nehmen. Wenn da z.B. ein ADC angeschlossen ist, dann 
könnte es ja reichen, nur die Werte 0..254 zur Datenübertragung zu 
nehmen, und die 255 zur Synchronisation.

Oder die 254 und 255 in 2 Bytes zu verschlüsseln: wenn 254 übertragen 
werden soll, dann kommen die 2 Bytes 254 und 0, wenn 255 übertragen 
werden soll, dann kommen die 2 Bytes 254 und 1 (das Zeichen 254 wäre 
hier quasi ein "Escape"-Zeichen). Dann hättest du die 255 wieder 
"freigeräumt" und könntest diesen Wert als Sync-Zeichen verwenden. 
Daraus resultiert aber eine unterschiedlich lange Übertragungsdauer, 
weil ja für diese Werte jeweils 2 Bytes übertragen werden müssen. Und 
dann bräuchtest du im Empfänger einen Mechanismus, der das wieder 
zurückwandelt. Nicht kompliziert, nur eben ein wenig aufwendig...

von Detlev T. (detlevt)


Lesenswert?

Hallo Lothar,

wird das Signal durch einen Impuls gestört, der eine Zeit lang eine "0" 
repräsentiert, ergibt sich für den UART je nach dessen Länge einer der 
Werte 0xFF, 0x7F, 0x3F,..., 0x01 oder 0x00. Solche Werte halte ich daher 
für ein SYNC-Byte weniger geeignet, die sollte man lieber gleich 
verwerfen, wenn sie während einer Sendepause auftreten, und nicht auf 
Datenbytes warten, die niemals kommen werden.

Gruß, DetlevT

von Kevin K. (nemon) Benutzerseite


Lesenswert?

warte doch ab, bis das nächste Datenpaket eintrifft und prüfe, ob der 
Abstand zwischen zwei Triggerbytes gleich der Länge eines Datenpakets 
ist. So mache ich es hier, habe die 255 als Triggerbyte. Ich lese 
mehrere A/D-Wandler aus und übertrage verrechnete Werte zum PC. Die 255 
entspricht einer Eingangsspannung von +10V, also dem höchsten Ausschlag, 
wenn der PC das High-Byte "findet", beim Low-Byte kann die 255 recht 
häufig vorkommen, daher mache ich eine Erkennung, ob die 255 beim 
nächsten und übernächsten Paket auch an der gleichen Stelle ist. Mein 
Signal rauscht, sodass es eher unwahrscheinlich ist, dass das Low-Byte 3 
mal in Folge 255 ist. Außerdem habe ich eine kleine Korrektur, dass 
meine Triggerung sich nach falschem Einrasten erneut synchronisiert.

von Guru (Gast)


Lesenswert?

@ Detlev

Ich habe, offen gesagt, den Eindruck, das Du die möglichen Störungen und 
Gegenmaßnahmen auf Bit-Ebene und Protokollebene nicht in den 
richtigen/sinnvollen Proportionen siehst und sie falsch anwendest.

Zunächst mal gibt es eine Sicherungsschicht (wenn man das denn 
angesichts der geringen Möglichkeiten so nennen mag).  Die besteht nur 
aus dem Parity-Bit und kann naturgemäß nur einen Teil der denkbaren 
Störungen erkennen, es werden keine Fehler korrigiert.
Ihrer Funktion nach kann sie nur Störungen, die ein Bit betreffen 
erkennen sowie bestimmte Kombinationen von Mehrbitstörungen. Sollte 
letzteres tatsächlich regelmäßig/reproduzierbar auftreten so ist _RS232 
nicht das geeignete Übertragungsmedium_ !

Genau diesen letzteren Fall aber stellst Du hier in den Raum, nämlich 
das mehrere Bits gestört werden.

Ebenso ist die Anwendung von Prüfsummen eine die Fehler auf der Bitebene 
erkennen soll. Je nach Wahl des Verfahrens muss bei Problemen damit 
entweder das Prüfsummenverfahren oder das Übertragungsmedium gewechselt 
werden.


Ein völlig anderer Fall ist die Synchronisation auf Protokollebene. Hier 
geht es nicht um die Erkennung von Störungen auf der Bitebene. Aber 
nur für diese Ebene stellt sich die Frage der Wahl einer geeigneten 
Bitkombination, Anwendung von Escape Sequenzen oder ähnlichem.

Die Auswahl eines bestimmten Musters macht also keinen Sinn. Denn 
genauso wie Du annimmst, das eine Störungen eine Reihe von Bits auf 0 
zieht kann man annehmen, dass völlig andere Störungsmuster auftreten die 
Dein Muster dann nicht abfängt.


Entweder also, hast Du uns die Information darüber, das und warum nur 
eine bestimmte Art von Störungen vorliegen kann nicht gegeben oder 
aber Dein Versuch die Übertragung an der Stelle des 
Frame-Synchronisationsbytes sicherer zu machen ist untauglich.

von Sven P. (Gast)


Lesenswert?

Kommt drauf an, wie immer.
Zur Synchronisation benutzt man auch gerne eine BREAK-Bedingung. Die 
taucht im USART z.B. als Framefehler auf, der im normalen Datenstrom 
normalerweise nicht vorkommt. Dazu noch ein paar Prüfbytes, um den 
Fehler von echten Übertragungsfehlern zu unterscheiden.

Das macht z.B. DMX so.

von cskulkw (Gast)


Lesenswert?

Vielleicht ein bißchen Tricky, aber

was spräche den dagegen, die Länge der Nutzdatenbits an die 
Identifikation zu verknüpfen.

Mein Vorschlag wäre, die Sync-Info z. B. mit 7-Bit oder weniger zu 
übertragen. Solange im Empfangsinterrupt des nicht synchonisierten 
Empfänger stets Datenframes mit 8-Bits eintreffen, sollte ein Frameerror 
erkannt werden und die Daten verworfen werden.

Wenn dann ein 7-Bitwort empfangen wird, wäre es gleichgültig, welchen 
Wert es enthielte. Damit die Datenframelänge für die nun folgende 
Nachricht paßt, müßte der Empfänger nur auf die andere Datenbitlänge 
umschalten. Bei UART sollte das im Gegensatz zu CAN funktionieren.

Ein Punkt ist mir jedoch nicht klar. Wann weißt Dein Programm, dass ein 
Datenkontainer vollständig ist. Hast Du eine festgelegte Byteanzahl?

von Detlev T. (detlevt)


Lesenswert?

Hallo Leute,

ich habe das S.N.A.P.-Protokoll im Hinterkopf. Einiges gefällt mir da 
nicht, deshalb will ich mir etwas einfacheres ausdenken. Dort wird 0x54 
als SYNC-Byte verwendet. Ich kann die Frage daher auch so formulieren: 
Gibt es einen Grund, warum dieser Wert besser geeignet ist als so 
mancher andere?

Störungen muss ich ohnehin erkennen. (@Guru: von RS232 hatte ich nichts 
geschrieben. Nur von UART). Es könnte aus meiner Sicht aber von Vorteil 
sein, "typische" Störungen gleich verwerfen zu können.

Gruß, DetlevT

von Guru (Gast)


Lesenswert?

> @Guru: von RS232 hatte ich nichts geschrieben. Nur von UART

Aha. Und? Beruht die Tatsache, dass unvollständige Informationen 
vorliegen auf einem Fehler Deinerseits oder meinerseits?
UART heisst üblicherweise RS232. Wenn nicht hättest DU die Information 
geben müssen.

von Kevin K. (nemon) Benutzerseite


Lesenswert?

Guru schrieb:
>> @Guru: von RS232 hatte ich nichts geschrieben. Nur von UART
> UART heisst üblicherweise RS232.
bei weitem nicht!

von Guru (Gast)


Lesenswert?

@ Kevin K. (nemon)

>Guru schrieb:
>>> @Guru: von RS232 hatte ich nichts geschrieben. Nur von UART
>> UART heisst üblicherweise RS232.
>bei weitem nicht!

Das "UART" "bei weitem nicht" "üblicherweise", heisst anders 
ausgedrückt, das UART "in den seltensten Fällen" mit RS232 verknüpft 
ist.

Aha.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Kevin K. schrieb:
>> UART heisst üblicherweise RS232.
> bei weitem nicht!
Wenn ich Auto schreibe, dann hast du sofort das "Durchschnittsauto" 
(nämlich einen PKW) vor Augen. Und wenn ich dann aber einen LKW meinte, 
dann wäre es schön, wenn ich dich vorher darauf hinweise. Es könnte ja 
sein, dass das an meiner Aussage was ändert...
Wenn ich U(S)ART (ohne Einschränkungen oder Anmerkungen) lese, dann habe 
ich sofort eine RS232-Schnitte vor Augen...

Detlev T. schrieb:
> Störungen muss ich ohnehin erkennen. (@Guru: von RS232 hatte ich nichts
> geschrieben. Nur von UART). Es könnte aus meiner Sicht aber von Vorteil
> sein, "typische" Störungen gleich verwerfen zu können.
Wenn man schon nach "typischen Störungen" sucht, dann wäre es durchaus 
interessant, welches Medium diese typischen Störungen mit sich bringen 
könnte. Und UART ist hier dann ja wohl ein Begriff, der z.B. auf CAN 
genauso zutrifft. Nur sind dort die Störmechanismen und die 
Störbehandlung ganz anders...

Detlev T. schrieb:
> durch einen Impuls gestört, der eine Zeit lang eine "0"
> repräsentiert, ergibt sich für den UART je nach dessen Länge einer der
> Werte 0xFF, 0x7F, 0x3F,..., 0x01 oder 0x00. Solche Werte halte ich daher
> für ein SYNC-Byte weniger geeignet, die sollte man lieber gleich
> verwerfen, wenn sie während einer Sendepause auftreten, und nicht auf
> Datenbytes warten, die niemals kommen werden.
Wenn ich z.B. xFF als Sync-Byte nehme, und es kommt wegen einer Störung 
ein xFF zustande, dann tut mir das nicht weh. Denn mit dem nächsten 
gültigen und fehlerfrei übertragenen Frameanfang kommt ja wieder ein 
xFF. Und auf das wird neu synchronisiert. Dazwischen warte ich auf gar 
nichts...

Schlimmstenfalls/Bestenfalls kommt ein Timeout-Fehler, der mich auf eine 
schlechte Übertragungsstecke hinweisen könnte. Genauso dann, wenn zwei 
Frame-Starts hintereinander kommen...

von Kevin K. (nemon) Benutzerseite


Lesenswert?

Guru schrieb:
> @ Kevin K. (nemon)
>
>>Guru schrieb:
>>>> @Guru: von RS232 hatte ich nichts geschrieben. Nur von UART
>>> UART heisst üblicherweise RS232.
>>bei weitem nicht!
>
> Das "UART" "bei weitem nicht" "üblicherweise", heisst anders
> ausgedrückt, das UART "in den seltensten Fällen" mit RS232 verknüpft
> ist.
>
> Aha.

RS232 ist als asynchroner Bus eine Untermenge aller UART-Varianten. 
Derzeit wird sie wohl sehr häufig implementiert, um eine Schaltung mit 
einem Computer zu verbinden. Wenn du aber beispielsweise einen µC an 
einen PC ohne RS232-Schnittstelle klemmen willst, nimmst du 
möglicherweise einen Wandler von UART mit TTL-Pegel zu USB (FT232 und 
konsorten). Der µC bekommt davon nichts mit, dem ist völlig egal, was 
mit den Daten passiert. Aber RS232 hast du trotz UART nicht benutzt.
Bei der Zeile, die du zitierst trat genau das Problem auf, dass du UART 
mit RS232 gleichgesetzt hast, der User vor dir aber (vermutlich, man 
weiß es nicht so recht) TTL-Pegel meinte.
Das "üblicherweise" aus deinem Post impliziert, dass man pauschal UART 
mit RS232 gleichsetzen kann und Ausnahmen vernachlässigbar selten sind. 
RS232 ist wie gesagt, eine häufige Implemention, aber es gibt noch 
andere, die eben nicht vernachlässigbar häufig anzutreffen sind. So 
drücke ich es auch mit meinem "bei weitem nicht" aus. Letzteres heißt 
nämlich nicht "in den seltensten Fällen".

Just my 2 Cent

von Detlev T. (detlevt)


Lesenswert?

Lothar Miller schrieb:
> Wenn ich U(S)ART (ohne Einschränkungen oder Anmerkungen) lese, dann habe
> ich sofort eine RS232-Schnitte vor Augen...

Und ich eine RS485. ;-)

Beim UART sind "0" und "1" aber nicht gleichwertig, weil "1" den 
Ruhezustand bedeutet - und "0" den Beginn eines Frames.

Aber meine eigentliche Frage wurde nicht beantwortet. Vermutlich kann 
man daher wirklich nach Lust und Laune sich einen Wert aussuchen.

Gruß, DetlevT

von Guru (Gast)


Lesenswert?

@ Kevin K.

>So drücke ich es auch mit meinem "bei weitem nicht" aus. Letzteres heißt >nämlich 
nicht "in den seltensten Fällen".

Wenn Du diese Äusserung unter das Zitat von mir stellst schon.
"üblicherweise" lässt nämlich durchaus auch das Gegenteil zu. Das UART 
zwangsweise, immer und nur mit RS232 verknüpft ist, habe ich nie 
geschrieben. "Bei weitem nicht" ist eine Negation die nur sehr wenige 
Ausnahmen zulässt. In Verbindung heisst das "in den seltensten Fällen". 
Das mich hier jemand belehren will, der noch nicht mal die Grundlagen 
der Sprache und Logik kennt, ist absurd.

Lothar hat es schon gesagt: Mangels Information geht man vom Üblichen 
aus. Du suggerierst das hier nur, das ich eine absolute Aussage 
getroffen habe, zu welchem Zweck auch immer, denn das Problem des TO 
hilft das nicht zu lösen.

Also, ich halte mich mal 'raus, anstatt mich auf sinnlose Diskussionen 
einzulassen.

Das Grundproblem, das hier einerseits Informationen fehlen und 
andererseits verschiedene Problembereiche vermischt werden habe ich 
angesprochen.
Wenn es nutzt, dann gut. Wenn nicht, dann auch gut.

von Kevin K. (nemon) Benutzerseite


Lesenswert?

@Guru, bloß nicht als blödes Anmachen sehen ;) Ich halte mich hier jetzt 
auch mal raus, zumindest, was die sprachlichen Feinheiten angeht.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Bevor Ihr hier ein Semiotik-Seminar gründet: Der Begriff U(S)ART 
impliziert eine asynchrone serielle Schnittstelle, was für die 
Problembetrachtung ausreichend genau ist.

Ob nun RS232, TTL-Pegel, RS485 oder RS422 auf dem Übertragungsmedium 
genutzt wird, ist für das Problem des Threadstarters vollkommen 
irrelevant.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Kevin K. schrieb:
> ... einen Wandler von UART mit TTL-Pegel zu USB (FT232) ...
> Aber RS232 hast du trotz UART nicht benutzt.
Allerdings möchte ich gern dazu anmerken, dass selbst FTDI den FT232 
ausdrücklich FT232 benannt hat. Und nicht FTUART...  ;-)

> Bei der Zeile, die du zitierst trat genau das Problem auf, dass du UART
> mit RS232 gleichgesetzt hast, der User vor dir aber (vermutlich, man
> weiß es nicht so recht) TTL-Pegel meinte.
Ich meine nicht. Denn seine Bedenken waren genau so, dass ein kurzer 
Störspike im Ruhezustand (='1', high, 5V TTL) fälschlicherwese als 
Startbit angesehen werden könnte, und daraus resultierend ein xFF 
eingelesen würde...

Detlev T. schrieb:
> Beim UART sind "0" und "1" aber nicht gleichwertig, weil "1" den
> Ruhezustand bedeutet - und "0" den Beginn eines Frames.
Und ob die '1' jetzt als 5V im Logikpegel oder als -3..12V im RS232 
Pegel dargestellt wird, ist dabei eher zweitrangig...

Rufus Τ. Firefly schrieb:
> Ob nun RS232, TTL-Pegel, RS485 oder RS422 auf dem Übertragungsmedium
> genutzt wird, ist für das Problem des Threadstarters vollkommen
> irrelevant.
Das bringt die Thematik auf den Punkt.

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
Noch kein Account? Hier anmelden.