Forum: Mikrocontroller und Digitale Elektronik CRC bei UART-Busprotokoll


von Max C. (max_der_bastler)


Lesenswert?

Hallo alle miteinander,

ich bin dabei, fuer meine privaten Projekte ein einheitliches Bussystem 
zu entwerfen. Als Uebertragungsmedium verwende ich eine normale 
Differenzbusschnittstelle und einen UART, sodass jeder Mikrocontroller 
in der Lage ist, mein Busprotokoll umzusetzen.

Am besten erlaeutere ich euch kurz, wie ich mir alles vorstelle:
- Multimaster System
- nicht terminierter Buszusgriff, Verwendung von CSMA/CD
- jeder Teilnehmer am Bus hoert immer zu und trifft so die Entscheidung,
  ob der Bus frei oder besetzt ist (ueber Wartezeit nach letztem
  gesendetem Paket)
- moechte ein Teilnehmer senden, wartet er, bis der Bus frei ist
  - der Sender sendet zuerst die Adresse des Empfaengers
  - der Empfaenger muss ueber ein 'ACK' dem Sender bestaetigen, dass er
    sich angesprochen fuehlt
  - der Sender sendet nach korrekt empfangenem 'ACK' seine Adresse, die
    Anzahl der Nutzbytes und wartet nach vollendetem Senden wieder auf
    ein 'ACK' des Empfaengers
- beim Empfaenger sieht es entsprechend so aus:
  - der Empfaenger erkennt, dass er angesprochen ist und sendet ein
    'ACK' zurueck, um seine Empfangsbereitschaft zu signalisieren
  - es werden Senderadresse und Anzahl der Datenbytes empfangen und
    zwischengespeichert
  - es werden die Nutzdaten empfangen und mitgezaehlt
  - sind die Anzahl der Nutzdaten mit der uebermittelten Anzahl
    identisch, wird ein weiteres 'ACK' gesendet

Auf der Leitung sieht das ganze so aus:

Sender:     |E-Adresse|...|S-Adresse|Anz-Byte|...Daten...|...|
Empfaenger: |.........|ACK|..............................|ACK|

Bisher funkioniert dieses Verfahren sehr gut. Ich habe euch hier erstmal 
nur den fehlerfreien Ablauf geschildert. Natuerlich habe ich noch 
Abfragen auf Zeitueberschreitungen, fehlende 'ACK' und Datenkollisionen 
drin. Somit kann ich auch eine Fehlerunterscheidung treffen und auf die 
einzelnen Fehler unterschiedlich reagieren.
Ich moechte eine Erweiterung um einen CRC machen. Ich zerbreche mir 
jetzt den Kopf, wie genau ich das machen soll, da ich ja keinen 
durchgehenden Datenstrom vom Sender zum Empfaenger habe, sondern 
Unterbrechungen durch die 'ACK' des Empfaengers. Ausserdem muesste ich 
die 'ACK' ja auch noch CRC sichern...

Was haltet ihr erstmal von meiner Idee an sich und habt ihr ein paar 
Tips, wie ich den CRC am geschicktesten einbauen kann? Ich habe bisher 
im Forum und im Inernet nichts gefunden, was mir da weiterhelfen 
koennte.

PS: wundert euch nicht, dass ich immer 'ae', 'oe', 'ue' und so schreibe. 
Ich bin gerade beruflich in China und habe hier nur ein Laptop mit 
englischer Tastatur.

Gruss,
Max

von Ein Gast (Gast)


Lesenswert?

Max C. schrieb:
> Ausserdem muesste ich die 'ACK' ja auch noch CRC sichern...
Eigentlich sollte es doch reichen, wenn du das eigentliche Datenpakete 
(incl. Absenderads.) über CRC sicherst, um den Hammingabstand zu anderen 
gültigen Datentelegrammen zu erhöhen. Ein ACK ist sowieso immer gleich, 
d.h. ein CRC darüber wäre sowieso redundant und könnte durch eine 
längere Kodierung des ACK ersetzt werden. Mit Datentelegrammen kann das 
ACK alleine wegen seiner Länge nicht verwechselt werden.

von Purzel (Gast)


Lesenswert?

Ein ACK mit einem CRC zu versehen ist muessig, denn es gibt immer fast 
dasselbe. Das Datenpacket versieht man sinnvollerweise mit einem CRC.
Einfach einen CRC ueber einem block rechnen. Ein CRC-16 reicht fuer 
2^16bit=8kBytes. Da sollte man falls moeglich die Tabellenmethode und 
nicht die Shift-XOR Methode waehlen. Man tradet Groesse gegen 
Rechenzeit.

Siehe auch
http://www.ibrtses.com/embedded/shortmsgprotocol.html


PS ich bin hier zuhause, und habe immer eine ASCII tastatur

von Holler (Gast)


Lesenswert?

Purzel schrieb:
> Siehe auch
> http://www.ibrtses.com/embedded/shortmsgprotocol.html

Ganz interessant: gibts das Protokoll auch als fertigen C-Code?

von Bronco (Gast)


Lesenswert?

Max C. schrieb:
> Was haltet ihr erstmal von meiner Idee an sich und habt ihr ein paar
> Tips, wie ich den CRC am geschicktesten einbauen kann?

Im Grunde baust Du eine Art CAN-Bus in Software nach.
Warum nimmst Du nicht einfach gleich den CAN-Bus?

Deinem Argument, daß jeder Microcontroller mit UART Dein Protokoll 
sprechen könnte, halte ich entgegen: Dann mußt Du auf diesem 
Microcontroller erstmal Dein Protokoll implementieren! Und testen! Und 
Absichern!
CAN & Co. gibt's wie Sand am Meer, fix und fertig, getestet und 
abgesichert.

von picbastler (Gast)


Lesenswert?

Hey, der CAN-Bus lag mir auch schon auf der Zunge. Gerade für "die 
privaten Projekte" ideal, weil er schon fertig entwickelt ist und man 
sich um andere Dinge kümmern kann. Ich habe es hinter mir: hatte 
angefangen, auf RS-485 Basis über ein eigenes Protokoll nachzudenken, 
aber das sehr schnell wieder verworfen, nachdem mir ein halber Tag 
Herumspielen mit dem CAN ein funktionierendes Netzwerk einbrachte...

von Max C. (max_der_bastler)


Lesenswert?

>Im Grunde baust Du eine Art CAN-Bus in Software nach.
Im Prinzip hast du recht. Ich habe mir aus verschiedenen Protokollen die 
fuer mich sinnvollen Teile herausgepickt. Inzwischen gibt es auch noch 
kleinere Abaenderungen.

An den CAN-Bus habe ich auch gedacht, allerdings empfaengt da ja jeder 
Teilnehmer die Nachrichten auf dem Bus. Ich muesste also ein eigenes 
Protokoll auch wieder darueber legen.
Wie sieht das bei euch denn mit CAN-Protokollen aus? Oder nutzt jemand 
von euch standartisierte Protokolle wie CANopen? Gibt es dazu gute 
Dokus, da ich bisher keine gefunden habe :(

Ach ja, was auch bloed bie CAN ist, ist die geringe Teilnehmerzahl von 
gerade mal 32 Stueck. Man muesste also oft Repeater einbinden oder gibt 
es auch kraeftigere Bustreiber?

von Harald A. (embedded)


Lesenswert?

Max C. schrieb:
>
> An den CAN-Bus habe ich auch gedacht, allerdings empfaengt da ja jeder
> Teilnehmer die Nachrichten auf dem Bus.

Kann man so machen, muss aber nicht. Stichwort Maske und Filter

Es gibt natürlich auch Transceiver mit mehr als 32 Teilnehmer....
TJA1050 oder MCP2551 u.v.a.m.

von picbastler (Gast)


Lesenswert?

Dass jeder Teilnehmer alle Telegramme zur Verfügung hat, empfinde ich 
eher als Vorteil. Ich habe gewissermaßen Funktion und Adresse in die ID 
codiert und damit finden alle Daten ihren Bestimmungsort, egal in 
welchem Netzknoten eine Funktion implementiert ist.

von Wilhelm F. (Gast)


Lesenswert?

@Max:

Denk dir für die seriellen Übertragungen einen Protokollframe mit Header 
aus, und gut ist es.

Für CAN braucht man wohl definitiv keine Zusatzüberprüfung mehr. Das 
macht das CAN-Protokoll schon alleine. Dafür wurde es entwickelt. Es 
sollte sehr sicher sein. CAN hat wohl von selbst schon HD6.

Mit CAN würde ich auch Hobbybasteleien machen, weil ich weiß, wie gut es 
ist. Allerdings nur, wenn ich gerade CAN-Controller habe. Ich machte 
sogar einmal eine industrielle Applikation mit CAN.

In industriellen Anwendungen, wo ein Datenframe mal bis zu etwa 200 
serielle Bytes hat, sah ich schon, daß als Prüfsumme einfach nur die 
Byteinhalte ohne Übertrag auf summiert werden, und die Prüfsumme in 
einem Byte steht. Sie wird im Frame mit übertragen. Die Dinge 
funktionierten zuverlässig.

OK, CRC, kann man machen, wenn man lustig ist.



Für die ganz normale serielle Schnittstelle am 8051 habe ich hier 3 
Boards mit LWL-Schnittstelle, die man als Netzwerk z.B. Ringnetz koppeln 
kann. Bei LWL sehe ich da auch keine besondere Fehleranfälligkeit in der 
Übertragung, das ist äußerst zuverlässig und störungsunanfällig, durch 
EMV schon mal gar nicht.

von Max C. (max_der_bastler)


Lesenswert?

Ich habe mir nochmal alle Sachen zum CAN-Bus angeschaut und ihr habt 
mich ueberzeugt. Der CAN-Bus ist fuer mich wirklich sehr gut geeignet.
Jetzt habe ich mir aber natuerlich auch weiter gedanken darueber 
gemacht, wie ich meine Daten ueber den CAN versende. Da ich vorallem 
Sensordaten abfragen will, wuerde ich diese am liebsten mit einem 
Zeitstempel versehen.
Leider habe ich trotz langer Suche im Forum und google nichts wirklich 
verwertbares gefunden.
Habt ihr ein paar Ideen, wie ich einen Zeitstempel in meinen kurzen 
8Byte Datenrahmen reinbekomme?

von Konrad S. (maybee)


Lesenswert?

Max C. schrieb:
> Zeitstempel

Wenn jeder Teilnehmer in der Lage sein soll, den Zeitstempel zu 
versenden, dann hat auch jeder Teilnehmer eine Uhr und braucht den 
Zeitstempel nicht.
Nur die Uhren der Teilnehmer müssen synchron laufen.

von Harald A. (embedded)


Lesenswert?

Was sind das für Sensordaten, dass die Empfangszeit im Empfänger bzw. im 
zentralen Datensammler nicht genau genug ist? Die typische 
Übertragungszeit beträgt doch nur wenige Millisekunden (worst-case)

von Bronco (Gast)


Lesenswert?

Max C. schrieb:
> Da ich vorallem
> Sensordaten abfragen will, wuerde ich diese am liebsten mit einem
> Zeitstempel versehen.

CAN funktioniert i.d.R. so, daß die Teilnehmer nicht "abgefragt" werden, 
sondern von sich aus in festen Zeitrastern ihre Daten senden.
Z.B. Temperatursensor 1 sendet alle 10ms die aktuelle Temperatur. Es 
bleibt den angeschlossenen Teilnehmern überlassen, ob sie das 
interessiert oder nicht.

Das klingt auf den ersten Blick seltsam und nach unnötiger Buslast, ist 
aber tatsächlich ziemlich clever, weil immer alle Informationen 
verfügbar sind, ohne daß man danach fragen muß.
Da die Nachrichten über ihre ID priorisiert sind, setzen sich wichtige 
Nachrichten durch.

PS: Die Sendeperiode der Teilnehmer muß so abgestimmt werden, daß die 
Buslast in Grenzen bleibt, sonst kommt's zu Datenstau.

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.