= Poor Man's CAN = Diese Seite beschreibt die Definition eines Feldbussystems welches von den physikalischen Eigenschaften an CAN angelehnt ist, aber mit den in fast allen Mikrocontrollern integrierten UART Transceivern realisiert werden kann. == Eigenschaften == * Differentielle Signalleitungen wegen Störsicherheit * Optional: Galvanische Trennung vom Bus * Multi Master Fähigkeit * Kollisionserkennung * Protokoll ist nur Optional == Hardware Ebene == * Interface über Normale CAN Transceiver * [[http://www.reichelt.de/?ACTION=3;ARTICLE=58427;PROVID=2402|SN65HVD230D]] (3.3V Kompatibel) * [[http://de.farnell.com/texas-instruments/iso1050dubr/can-transceiver-isoliert-5v/dp/1755712|ISO1050]] (Galvanisch getrennt) * [[http://www.reichelt.de/?;ARTICLE=39907|PCA82C250]] * [[http://www.reichelt.de/?ACTION=3;ARTICLE=90069;PROVID=2402|MCP2551]] * Geschwindigkeit: beliebig bis zu 1 MBit/s * 4-Draht Interface * 2 Verdrillte Leitungen für Daten (Differentielle Pegel) * 2 Leitungen für Versorgungsspannung * Stecker * 4-Pol Micromatch * 6-Pol Wannenstecker (ähnlich belegt wie TTL-UART) * 4-Pol Steckbare Anschlussklemmen * Buchse auf der Platine: [[http://www.reichelt.de/?ACTION=3;ARTICLE=36645;PROVID=2402|RIACON Typ 182]] * Stecker: [[http://www.reichelt.de/?ACTION=3;ARTICLE=36631;PROVID=2402|RIACON Typ 169]] * Belegung (Sicht auf den Stecker auf der Platine) * links: Masse * mitte links: CANL * mitte rechts: CANH * rechts: +5V * 8-Pol RJ45 * Pins 1,3,5: 24V * Pins 2,4,6: GND * Pin 7: CAN-L * Pin 8: CAN-H === Eagle Lib === Die Eagle Lib mit den Steckern gibt es im [[Downloads|Download-Bereich]] * [[attachment:Downloads/lib-com.lbr]] == Protokoll-Ebene == Aus wiederverwendbarkeitsgründen ist das Protokoll an das CAN Protokoll angelehnt. === Aufbau eines Frames === * Frame Start 9-Bit Übertragung, nur bei der ID ist das 9te Bit gesetzt. * 8Bit Message ID * 4Bit Steuerbits * 4Bit Anzahl der Daten-Bytes * 0-15 Byte Daten * 8Bit CRC * http://www.maxim-ic.com/app-notes/index.mvp/id/27 === weitere Spezifikationen === * Ein Modul muss bevor es einen Nachricht senden darf eine zufällige Zeit zwischen 500µs und 1500µs auf dem Bus lauschen. Falls in der Zeit Daten empfangen werden, beginnt die Wartezeit von vorne. * Nach dem Senden eines Datenbytes muss überprüft werden ob das selbe Byte wieder empfangen wurde. Erst dann wird das nächste Byte gesendet. Falls die Daten nicht übereinstimmen wird 3x hintereinander die ID 0x00 gesendet um zu signalisieren dass ein Fehler aufgetreten ist. Daraufhin Setzen alle Busteilnehmer ihre empfangsbuffer zurück. Die Nachricht wird nun ganz normal (inclusive der Wartezeit) nochmal gesendet. * Es gibt explizit kein Acknolagement der Empfangenden Knoten, da Nachrichten prinzipiell für mehrere bestimmt sein können. Falls erforderlich muss die Rückmeldung in der Anwendung in Form einer gesonderten Antwortnachricht erfolgen. === Impementierung === * [[attachment:pmc.c]] * [[attachment:pmc.h]] * [[attachment:pmc.config.h]] * [[attachment:uart.zip]] (Beispielimplementierung des UART-Stacks) == alternatives Protokoll == Der Ansatz dieses Protokolls ist es nicht eine möglichst simple Datenübertragung zu ermöglichen, sondern harten Echtzeitbedingungen zu genügen. Da dieser Entwurf einen nicht unerheblichen Anteil an Protokolldaten erfordert ist die Übertragungsrate spezifisch an die zeitlichen Anforderungen des Zielsystem anzupassen. Die Kommunikation wird von einem Master verwaltet der die Module zyklisch überprüft. Beim Start des Systems findet eine generelle Abfrage ''aller'' Moduladressen statt, um die vorhandenen Module automatisch zu erkennen. Diese Abfrage kann je nach Anforderung wiederholt werden; neu hinzugefügte Module können so erkannt und eingebunden werden. Die Dauer eines Standardzyklus sollte dabei nicht überschritten werden und muss bei entsprechenden Echtzeitanforderungen berücksichtigt werden. Die eigentliche Datenübertragung verläuft in zwei Runden, dazu werden Statusanfragen an alle ''bekannten'' Module gesendet. Die angesprochenen Knoten antworten mit einem Telegramm das als einziges Datenbyte, die Anzahl der reinen Datenbytes enthält die der Knoten senden möchte. Möchte der Knoten keine Daten senden, wird mit `0x00` als Datenbyte geanwortet. Der Master kann so überprüfen ob das Modul noch funktionsfähig ist und ob die Anfrage den Knoten erreicht hat. Aufgrund dieser rücklaufenden Daten, der hinterlegten Priorität und des Alters der Anforderung plant der Master nun die Sendereihenfolge des aktuellen Zeitschlitzes und ruf in dieser die Knoten zur tatschächlichen Datenübertragung auf. Generell werden die Anfragen des Masters ''immer'' mit einem Telegramm des entsprechenden Knotens beantwortet, um die Kommunikation zu bestätigen. Der Master hingegen beantwortet die Sendungen des Slave nicht, sondert fordert bei fehlerhafter Übertragung die Daten zu einem geeigneten Zeitpunkt neu an. Erkennt der Slave selbst einen Fehler in der Übertragung kann diese optional mit dem Senden des EOT-Zeichens (`0x04`) vorzeitig abgebrochen werden, da dies zwingend zu einen ungültigen Telegramm führt. Sollen Daten von Slave zu Slave übertragen werden, ist keine aktive Bestätigung vom Zielmodul vorgesehen, diese Bestätigung wird nach erfolgter, für den Master gültigen, Übertragung explizit angefordert. Die Daten müssen grundsätzlich als ASCII übertragen werden und dabei den folgenden Anforderungen entsprechen. Es dürfen pro Datensatz zwischen 0 und 32 Datenbytes enthalten sein, daraus folgt das die Länge eines Datensatzes mindestens 8 und höchsten 40 Byte beträgt. Die Prüfsumme wird berechnet aus allen Zeichen zwischen SOH und ETX als Kette von XOR-Verknüpfungen mit dem Startwert `0x00`. Das Ergebnis wird in Halbbytes zerlegt, je der Wert `0x41` addiert und der Nachricht angefügt. . ||||||'''Datentelegramm''' || ||1 ||`0x01` ||SOH - start of heading || ||2 ||`0x41 - 0x5F` ||Moduladresse || ||3 ||`0x41 - 0x5F` ||Funktionsaufruf (Sendeanforderung, Slave-Slave-Bestätigung, ...) || ||4 ||`0x02` ||STX - start of text || ||4 + n ||`0x20 - 0x7E` ||n. Datenbyte || ||4 + n + 1 ||`0x03` ||ETX - end of text || ||4 + n + 2 ||`0x41 - 0x50` ||Prüfsumme oberes Halbbyte + `0x41` || ||4 + n + 3 ||`0x41 - 0x50` ||Prüfsumme unteres Halbbyte + `0x41` || ||4 + n + 4 ||`0x04` ||EOT - end of transmission ||