Implementieren einer CAN-Protokollschicht in Software

Hintergrund

Ich entwickle ein Projekt, das die bescheidenen Mikrocontroller-Spezifikationen von erfordert:

  • 8 12-Bit-10-kHz-ADCs
  • 1kB Arbeitsspeicher
  • 48-QFN oder kleinerer Footprint
  • 20 kbps verkettbares, rauschresistentes und fehlerkorrigierendes Kommunikationsprotokoll

Die Anforderungen an die Signalverarbeitung sind ziemlich gering, und die meisten können an den Hauptprozessor im System exportiert werden. Die ersten drei Spezifikationen sind einfach zu erfüllen und können für weniger als 2 US-Dollar in der Menge durchgeführt werden. Die Kommunikation findet jedoch in einer Umgebung mit starkem elektrischem Rauschen statt, sodass rauschanfällige Netzwerke wie LIN und I2C ausfallen. Ein zusätzliches Argument gegen LIN ist, dass ich das Ganze mit 5 V oder 3,3 V betreiben möchte und LIN-Transceiver 12 V benötigen und daher einen zusätzlichen Regler oder Kabel pro Sensorplatine benötigen würden. Ich habe mich für diese Aufgabe zunächst für CAN entschieden. CAN-Controller verursachen jedoch erhebliche Kosten, und ich bin gespannt, ob dies in Software möglich ist.

CAN-Physical-Layer

Die CAN-Spezifikation definiert die Data-Link- und Physical-Layer des OSI-Netzwerk-Referenzmodells. Viele kostengünstige 8-Pin-ICs, wie der NXP TJA1040/50 , der Maxim MAX3058/59 , der Microchip MCP2551 und der TI SN65HVD1050 existieren zur Implementierung der physikalischen Schicht. Die Implementierung der Bitübertragungsschicht mit D/A-Wandlern oder Operationsverstärkern wäre schwierig, wenn nicht sogar unmöglich, daher sind diese ICs die etwa 1 US-Dollar wert, die sie kosten.

CAN-Datenverbindungs-/Protokollschicht

Für die Datenverbindungsschicht fügen einige Mikrocontroller den grundlegenden UART-, I2C- und SPI-Kommunikationsschichten CAN-Protokollmodule hinzu. Diese sind jedoch deutlich teurer als die Basis-Chips.

Untersuchung der Kosten von CAN-Protokollmodulen

Um diese Behauptung zu untermauern, hier ein paar populäre Mikros in CAN- und Nicht-CAN-Versionen aus der :

  • ATmega16 – ATMEGA16M1 (mit CAN): 3,87 $, ATMEGA168A (ohne CAN): 3,23 $
  • dsPIC – DSPIC33FJ64MC802 (mit CAN): 6,14 $, DSPIC33FJ64GP202 (ohne CAN): 5,48 $
  • PIC18 – PIC18F2480 (mit CAN): 6,80 $, PIC18F24J10 (ohne CAN): 2,10 $
  • Cortex-M3 – STM32F103C4T6A (mit CAN): 6,50 $, STM32F100C4T6B (ohne CAN): 2,73 $

Um fair zu sein, habe ich nur Mikrocontroller mit äquivalenten Speichergrößen verglichen, aber viele der Nicht-CAN-Versionen sind mit kleineren Speichergrößen für weniger Geld erhältlich. Externe CAN-Controller wie der Microchip MCP2515 kosten fast 2 US-Dollar, daher ist es offensichtlich kostengünstiger, das CAN in den Mikrocontroller zu integrieren, wenn Sie die Option haben.

Interessanterweise ist das ATmega-Teil bei weitem das billigste mit CAN ausgestattete Teil im Bestand von Digikey.

Funktion der CAN-Protokollschicht

Das in den dsPIC-Mikrocontrollern enthaltene CAN-Modul macht Folgendes:

Das CAN-Bus-Modul besteht aus einer Protokoll-Engine und Nachrichtenpufferung/-steuerung. Die CAN-Protokoll-Engine übernimmt alle Funktionen zum Empfangen und Senden von Nachrichten auf dem CAN-Bus. Nachrichten werden übertragen, indem zuerst die entsprechenden Datenregister geladen werden. Status und Fehler können durch Lesen der entsprechenden Register geprüft werden. Jede auf dem CAN-Bus erkannte Nachricht wird auf Fehler geprüft und dann mit Filtern abgeglichen, um zu sehen, ob sie empfangen und in einem der Empfangsregister gespeichert werden sollen.

Dies scheint in Software ziemlich machbar zu sein.

Die Frage

Kann eine Softwareprotokollschicht verwendet werden, um die CAN-Spezifikation mit nur einem kostengünstigen, mit UART ausgestatteten Mikrocontroller und einem CAN-Transceiver zu implementieren? Wenn ja, gibt es Open-Source-Implementierungen?

Können CAN-Transceiver alternativ mit UARTs verwendet werden, um ein benutzerdefiniertes Protokoll zu implementieren? Ich bin mit einer Single-Master-Topologie einverstanden; Ich verstehe, dass es schwierig sein kann, ein Schiedsverfahren in einem benutzerdefinierten Protokoll richtig hinzubekommen.

CAN ist auch 12 V, da es für den Einsatz im Automobil entwickelt wurde.
@Kenny - Die bei den obigen Transceivern verwendeten Spannungspegel betragen 5 V.
Wenn Sie die STM32F-Serie in Betracht ziehen, darf ich auch dieses NXP-Teil vorschlagen? Es ist ein Cortex-M0-Kern. search.digikey.com/scripts/DkSearch/…
@Jon - Diese wurden nicht unbedingt in Betracht gezogen, und ein M0 wäre ideal für diesen Anwendungsfall. Berücksichtigen Sie jedoch, dass Teile des Nuvoton M052LAN auch Cortex-M0 sind und ungefähr die Hälfte des Mengenpreises (1,21 USD gegenüber 2,35 USD), aber hat kein CAN-Modul. Diese Art von Preisunterschied ist meine Motivation.
Vielleicht möchten Sie auch die Betriebsbewertung in Betracht ziehen. Die meisten Teile mit CAN-Unterstützung werden für Nicht-CAN-Varianten im Vergleich zu kommerziellen Industrie- oder Automobilkomponenten verwendet.
Fantastische Ressourcen: Mikrochip-Dokumente an713, an754 und an228. Hier ist ein 713: ww1.microchip.com/downloads/cn/AppNotes/cn_00713a.pdf

Antworten (4)

Ich denke, die Implementierung des CAN-Protokolls nur in Firmware wird schwierig sein und eine Weile dauern, bis es richtig ist. Es ist keine gute Idee.

Ihre Preise sind jedoch hoch. Ich habe gerade nachgesehen, und ein dsPIC 33FJ64GP802 im QFN-Gehäuse wird für 3,68 USD bei Microchipdirect für 1000 Stück verkauft. Der Preis wird für reale Produktionsmengen niedriger sein.

Das Hardware-CAN-Peripheriegerät erledigt einige echte Dinge für Sie, und die Preiserhöhung dafür ist bei weitem nicht das, was Sie behaupten.

Hinzugefügt:

Da Sie entschlossen zu sein scheinen, die Firmware-Route auszuprobieren, sind hier einige der offensichtlichen Probleme, die Ihnen in den Sinn kommen. Es wird höchstwahrscheinlich andere Probleme geben, die mir noch nicht aufgetreten sind.

Sie wollen CAN mit 20 kbit/s machen. Das ist eine sehr langsame Rate für CAN, die für mindestens 10 Sekunden von Metern bis zu 1 Mbit / s erreichen. Um Ihnen einen Datenpunkt zu geben, ist der NMEA 2000-Schiffssignalisierungsstandard auf CAN mit 200 kbit/s geschichtet, und das soll von einem Ende eines großen Schiffes zum anderen gehen.

Sie denken vielleicht, dass Sie nur einen Interrupt pro Bit brauchen und in diesem Interrupt alles tun können, was Sie brauchen. Das wird nicht funktionieren, weil in jeder CAN-Bitzeit mehrere Dinge passieren. Auf der Unterbitebene müssen insbesondere zwei Dinge getan werden. Der erste erkennt eine Kollision und der zweite passt die Bitrate im laufenden Betrieb an.

Auf einem CAN-Bus gibt es zwei Signalisierungszustände, rezessiv und dominant. Rezessiv ist, was passiert, wenn nichts den Bus antreibt. Beide Leitungen werden um insgesamt 60 Ω zusammengezogen. Ein normaler CAN-Bus, wie er von gängigen Chips wie dem MCP2551 implementiert wird, sollte an beiden Enden 120-Ω-Terminatoren haben, also insgesamt 60 Ω, die die beiden Differenzleitungen passiv zusammenziehen. Der dominante Zustand ist, wenn beide Linien aktiv auseinander gezogen werden, irgendwo um 900 mV vom rezessiven Zustand entfernt, wenn ich mich recht erinnere. Im Grunde ist dies wie ein Open-Collector-Bus, außer dass er mit einem Differenzialpaar implementiert ist. Der Bus ist rezessiv, wenn CANH-CANL < 900 mV und dominant, wenn CANH-CANL > 900 mV. Der dominante Zustand signalisiert 0 und der rezessive 1.

Immer wenn ein Knoten eine 1 auf den Bus "schreibt" (ihn loslässt), prüft er, ob ein anderer Knoten eine 0 schreibt. Wenn Sie den Bus im dominanten Zustand (0) finden, wenn Sie glauben, dass Sie senden, und Wenn das aktuelle Bit, das Sie senden, eine 1 ist, bedeutet dies, dass jemand anderes auch sendet. Kollisionen spielen nur eine Rolle, wenn die beiden Sender sich nicht einig sind, und die Regel lautet, dass derjenige, der den rezessiven Zustand sendet, sich zurückzieht und seine Nachricht abbricht. Der Knoten, der den dominanten Zustand sendet, weiß nicht einmal, dass dies passiert ist. So funktioniert die Arbitrierung auf einem CAN-Bus.

Die CAN-Bus-Arbitrierungsregeln bedeuten, dass Sie den Bus auf halbem Weg durch jedes Bit, das Sie als 1 senden, beobachten müssen, um sicherzustellen, dass jemand anderes keine 0 sendet. Diese Überprüfung wird normalerweise nach etwa 2/3 des Bits durchgeführt , und ist die grundlegende Begrenzung der CAN-Buslänge. Je langsamer die Bitrate, desto mehr Zeit bleibt für die Ausbreitung im ungünstigsten Fall von einem Ende des Busses zum anderen, und desto länger kann der Bus daher sein. Diese Prüfung muss jedes Bit durchgeführt werden, wo Sie denken, dass Sie den Bus besitzen und ein 1-Bit senden.

Ein weiteres Problem ist die Anpassung der Bitrate. Alle Teilnehmer an einem Bus müssen sich auf die Bitrate einigen, enger als bei RS-232. Um zu verhindern, dass sich kleine Taktunterschiede zu erheblichen Fehlern summieren, muss jeder Knoten in der Lage sein, etwas länger oder kürzer als sein Nennwert zu tun. In der Hardware wird dies implementiert, indem eine Uhr etwa 9x bis 20x schneller als die Bitrate läuft. Die Zyklen dieser schnellen Uhr heißen Zeitquanten. Es gibt Möglichkeiten, um zu erkennen, dass der Anfang neuer Bits in Bezug auf die Stelle wandert, an der sie Ihrer Meinung nach sein sollten. Hardware-Implementierungen fügen dann ein Zeitquantum in einem Bit hinzu oder überspringen es, um es erneut zu synchronisieren. Es gibt andere Möglichkeiten, wie Sie dies implementieren könnten, solange Sie sich an kleine Phasenunterschiede zwischen Ihren erwarteten Bitzeiten und den tatsächlich gemessenen Bitzeiten anpassen können.

In jedem Fall erfordern diese Mechanismen, dass verschiedene Dinge zu verschiedenen Zeiten innerhalb eines Bits erledigt werden. Diese Art von Timing wird in der Firmware sehr schwierig oder erfordert, dass der Bus sehr langsam läuft. Angenommen, Sie implementieren ein Zeitquantensystem in Firmware mit 20 kbit/s. Bei mindestens 9 Zeitquanten pro Bit würde dies einen 180-kHz-Interrupt erfordern. Das ist sicherlich mit so etwas wie einem dsPIC 33F möglich, wird aber einen erheblichen Teil des Prozessors verbrauchen. Bei der maximalen Befehlsrate von 40 MHz erhalten Sie 222 Befehlszyklen pro Interrupt. Es sollte nicht so lange dauern, alle Überprüfungen durchzuführen, aber wahrscheinlich 50-100 Zyklen, was bedeutet, dass 25-50 % des Prozessors für CAN verwendet werden und alles andere, was läuft, unterbinden muss. Das verhindert viele Anwendungen, die diese Prozessoren oft ausführen, wie Puls-für-Puls-Steuerung eines Schaltnetzteils oder Motortreibers. Die Latenz von 50-100 Zyklen bei jedem zweiten Interrupt wäre ein kompletter Showstopper für viele der Dinge, die ich mit solchen Chips gemacht habe.

Sie werden das Geld also ausgeben, um CAN irgendwie zu machen. Wenn nicht in dem für diesen Zweck vorgesehenen dedizierten Hardware-Peripheriegerät, dann in einem größeren Prozessor, der den erheblichen Firmware-Overhead handhabt und sich dann mit der unvorhersehbaren und möglicherweise großen Interrupt-Latenz für alles andere befasst.

Dann gibt es das Up-Front-Engineering. Das CAN-Peripheriegerät funktioniert einfach. Aus Ihrem Kommentar geht hervor, dass die zusätzlichen Kosten für dieses Peripheriegerät 0,56 US-Dollar betragen. Das scheint mir ein Schnäppchen zu sein. Wenn Sie kein Produkt mit sehr hohen Stückzahlen haben, werden Sie auf keinen Fall die erhebliche Zeit und die Kosten zurückerhalten, die erforderlich sind, um CAN nur in Firmware zu implementieren. Wenn Ihr Volumen so hoch ist, sind die genannten Preise sowieso nicht realistisch, und die Differenz zum Hinzufügen der CAN-Hardware wird geringer sein.

Ich sehe das wirklich nicht sinnvoll.

Ich schätze Ihre Meinung, aber ich bin neugierig, warum niemand versucht hat, die Schwierigkeiten zu umgehen - Jedes Projekt wird diese Probleme haben! Ich werde euch wissen lassen, wie es ausgeht, wenn ich es am Ende versuche.
Bei Stückzahlen von 1000 finde ich einen Preis von 3,12 $ für den dsPIC33FJ64GP202 von microchipdirect – ein Gesamtwertunterschied von 560 $! Es ist zumindest einen Versuch wert. Ich habe Preise pro Stück angegeben, einfach weil es einfacher war, Nummern für einzelne Stücke zu bekommen, ohne sich um Aufrollen, Standardpaketmenge usw. kümmern zu müssen.
@Kevin, niedrige Mengenpreise sind nicht immer proportional zu hohen Mengenpreisen. Ich weiß nicht, wie viele dieser Dinge Sie herstellen möchten, aber mit 560 US-Dollar wird die Technik für CAN in der Firmware nicht einmal ansatzweise bezahlt. Ich werde meiner Antwort einige der Schwierigkeiten hinzufügen, auf die Sie stoßen werden.
Ich habe ein bisschen damit herumgespielt und festgestellt, dass ein Dollarzeichen zu Beginn der Nachricht die Formatierung für alles danach durcheinander gebracht hat. Anscheinend gibt es irgendwo in der Formatierungssoftware einen bösen Fehler. Ich habe das Dollarzeichen durch "USD" ersetzt und jetzt ist die Formatierung wie beabsichtigt.
Der Formatierungsfehler ist merkwürdig, aber ich wollte sagen, dass ich entschlossen war, die Firmware-Route zu erkunden – nicht unbedingt, um sie auszuprobieren. Ich schätze Ihre Stimme der Erfahrung, die mir „Nein“ sagt, wollte aber sicherstellen, dass sie nicht einfach abgetan wird. Sie haben sicherlich genug Gründe angegeben, um es ohne zu viel zusätzliches Experimentieren abzulehnen.
@Olin, nur eine Kleinigkeit, aber NMEA hat 250 Kbs ( en.wikipedia.org/wiki/NMEA_2000 ). Und für andere basiert auf dem Automotive-Standard en.wikipedia.org/wiki/J1939
Die Antwort ist ja, das können Sie, aber ich stimme Olin hier vollkommen zu. Ich arbeite eigentlich Vollzeit in diesem Bereich. Ich verwende den dsPIC33FJ256-Chip. Die Zeit, die aufgewendet wird, um Dinge zu schreiben, die den Bit-Bang-Ansatz zum Laufen bringen, schmälert nur den Kostenvorteil, wenn Hardware dies für Sie erledigt und Sie das Rad neu erfinden. Ganz zu schweigen davon, dass alles, was Sie sonst noch an Hardware tun, sorgfältig geplant werden muss. Außerdem frage ich mich, ob Sie andere Protokolle auf höherer Ebene wie ISO14229 oder OSEK/Autosar NetworkManagement benötigen?
Das Formatierungsproblem ist wahrscheinlich LaTeX. meta.electronics.stackexchange.com/questions/434/…
@KevinVermeer Ich recherchiere gerade genau das. Wenn man Olins Informationen über das Stampfen im Bus ignoriert, ist die Interpretation der physikalischen Schicht nicht trivial. Sobald die IC-Hersteller das in den Griff bekommen haben, ist es ziemlich einfach, die anderen Bonus-Chips wie das mcp2551-Angebot bereitzustellen.

Wir verwenden den PIC18F25K80 . Obwohl es keinen DSP hat, kostet es ~ $ 2 in der Menge. Es ist fast ein direkter Ersatz für den von Ihnen erwähnten PIC18F2480. Wir verwenden den CCS -Compiler und seinen Software-Stack für CAN, der wahrscheinlich von Microchip portiert wurde. Es funktioniert gut für alles, was ich brauchte und ausprobiert habe.

Habe nicht nach ECAN gesucht. Blöder Microchip-Name, aber nächstes Mal muss ich genauer lesen! Wie ich schon sagte, meine Anforderungen an die Signalverarbeitung sind gering, daher glaube ich nicht, dass ich einen tatsächlichen DSP brauche.

Wenn ich das richtig lese, klingt es so, als wollten Sie die CAN-Funktionalität nur mit einem UART und einer cleveren Firmware bit-bashen. Vertrauen Sie mir, das wird nie funktionieren - ich schlage vor, einen guten Text über die Feinheiten von CAN oder CANopen zu lesen. Sie haben alle Kosteneinsparungen, die Sie suchen, ausgelöscht, indem Sie diesen Weg eingeschlagen haben.

Ich würde entweder einen Mikrocontroller mit einem CAN-Modul verwenden und die zusätzlichen 2 $ weitergeben, oder haben Sie über ein anderes Protokoll nachgedacht, das mit einem UART kompatibel ist, z. B. Modbus über RS-485 ?

Du liest es richtig. Ich habe die Vector Schulungsbroschüre zu CAN gründlich gelesen. Es sieht so aus, als ob jede Nachricht eine gewisse Vorverarbeitung für CRC benötigt, aber der Rest des Pakets sollte gleich sein und ich muss nur die Empfangsleitung weiter auf einen Konflikt überprüfen. Es scheint wirklich nicht so schwer zu sein, wie die Leute es darstellen, aber ich werde Ihren Rat auf jeden Fall berücksichtigen.
Ich mag jedoch die Idee von Modbus über RS485. Es scheint, dass die meisten dieser Transceiver auch eine 5-V-Versorgung haben; Ich hatte den Eindruck, dass es eine +/- Eingangsspannung wie RS232 benötigt. Werde dem mal nachgehen müssen.
bit hämmern wird ganz sicher funktionieren! Es ist nicht trivial, wie Olin oben erwähnt, aber es ist machbar. Ich habe es persönlich sowohl bei einem Mikro der PIC18F-Serie als auch bei einem Mikro der dsPIC33-Serie geschafft. Ich kann die PIC18F-Quelle hochladen, wenn Sie sie wirklich sehen möchten. Ich kann jedoch die dsPIC-Quelle nicht herausgeben, da sie Teil eines kommerziellen Projekts ist, an dem ich arbeite. In beiden Fällen verwenden wir MCP2551 und ich habe auch LIN-Code. LIN ist auf der Protokollebene etwas einfacher, aber die Implementierung von LIN-Zeitplänen ist etwas schwieriger ...
@EricM - Wie hoch war die Bitrate und konnten Sie die vollständige CAN-Spezifikation in Software implementieren? Ich würde gerne den PIC18F-Code dafür sehen.
Ja, implementierte die vollständige CAN-Spezifikation insofern, als das ECAN-Modul auf dem dsPIC nicht dupliziert wird, das sich um viele Aspekte kümmert. Bei der PIC18-Implementierung habe ich den Bus auf die volle Spezifikation und später bit-gebangt und dieser Code funktioniert auf einem dsPIC, der GPIO-Leitungen verwendet. Ich werde in ein paar Tagen mit dem Link zum Code aktualisieren.
Der Chip kann mit 1Mb mithalten. Ich habe viele hässliche Dinge getan, um die Schiedsregeln einzuhalten ... und hauptsächlich, um etwas über CAN zu lernen, aber ich würde dies in keinem kommerziellen Bereich empfehlen. Gehen Sie mit Hardware! MCP2551 & MCP2515 sind ausgezeichnete Chips ...

Ich denke auch über das Bit-Banging des CAN-Protokolls auf einem PIC µC nach, also bitte EricM, wenn Sie das wirklich getan haben, antworten Sie bitte und sagen Sie zumindest, welche Bitrate bei welcher Kernfrequenz von PIC18F oder DSPic Sie erhalten haben. Vielen Dank!

Allgemein: RS 485 wäre die Lösung für das primär gestellte Problem, aber es wäre auch möglich, CAN-(oder sogar FlexRay)-Transceiver mit Nicht-Vollduplex-UART-Kommunikation (Punkt 2 Punkt) als all diese Protokolle zu verwenden NRZ-Kodierung verwenden.

Aber in UART/V24/RS232 wird Vollduplex meistens verwendet, ohne darüber im Detail nachzudenken, also müssen Sie vielleicht etwas Gehirn in den Superloop oder die Zustandsmaschine Ihrer Anwendung stecken ...

Aber zurück zum CAN-Bitbanging: Ich arbeite seit vielen Jahren mit CAN und habe noch nie eine Bitbanging-Implementierung gesehen, aber soweit ich denken kann, sollte das für Bittimings bis zu 100kBit mit modernen µC wie DSPic oder ARM usw. funktionieren. (mit Kernen bei 80 MHz oder höher ...)

Zumindest wenn man nur das Rücklesen betrachtet... Das Senden würde einen gewissen Aufwand bedeuten, die Bitstrukturen so aufzubereiten, dass nicht 100% Buslast erreichbar wären, aber bei CAN sind mehr als 65% überhaupt selten...

Willkommen beim Electrical Engineering StackExchange. Der erste Teil Ihrer Antwort ist eigentlich gar keine Antwort, also stellen Sie eine neue Frage, wenn Sie das wollen. Das OP hat speziell nach der Softwareimplementierung des CAN-Protokolls gefragt, und Ihre Antwort scheint herumzuwandern, ohne diese Frage zu beantworten. versuchen Sie bitte, beim Thema der Frage zu bleiben.