Den CAN-Bus mit dem mySTM32 light verwenden

Diese Übung soll zu zweit ausgeführt werden bzw. sind zwei mySTM32 light Boards für diese Übung notwendig.
Im bisherigen Tutorial haben Sie den I²C Bus kennengelernt. Dieser Bus dient dazu verschiedene Controller zum Beispiel auf einer Leiterplatte zu verbinden. Wenn die zu vernetzenden Controller weiter auseinander liegen, zum Beispiel können für die Sensoren und Aktuatoren an einer Baumaschine schnell einige Meter Kabellänge zusammenkommen, benutzt man andere Feldbussysteme. Vor allem im Fahrzeugbereich ist der CAN-Bus ein häufig verwendetes Bussystem. CAN steht für Controller Area Network. Der Name sagt also schon, dass es sich hier um ein Netzwerkprotokoll für Mikrocontroller handelt. Im Gegensatz zum I²C Protokoll werden beim CAN sogenannte Frames versendet. Diese bestehen aus Steuerinformationen wie dem Nachrichten ID und den zu übertragenden Nutzdaten. Im Standardmodus bietet der Frame 8 Byte bzw. 8×8 = 64 Bit Nutzdaten an. Im CAN werden die Informationen üblicherweise nicht Ereignisorientiert einmalig gesendet sondern zyklisch mit einer bestimmten Updaterate zum Beispiel alle 20 oder 100 Millisekunden. Die Updaterate korreliert mit der Wichtigkeit der Nachricht. Das Ausbleiben einer Nachricht impliziert den Ausfall des entsprechenden Knotens.

Es sind zwei Controllerboards über den CAN-Bus zu vrernetzen. Dabei soll jedes Board über einen Taster und eine LED verfügen. Beim betätigen der Taste soll die LED auf dem jeweils anderen Board leuchten.

Anforderungen an die Lösung:

  • Sende-Taster jeweils an Pin A0
  • Emfangs-LED jeweils an Pin B0
  • CAN-Updaterate 100 Millisekunden
  • Nachrichten IDs Board 1 = 1, Board 2 = 2

Wenn Sie noch ein Klassendiagramm geöffnet haben wählen Sie im Kontextmenü (rechte Maustaste) des Diagramms den Menüpunkt „nach oben“. Falls das Projekt nicht mehr geöffnet ist, öffenen sie das SiSy UML-Projekt wieder. Führen Sie folgende Vorbereitungsarbeiten durch:

  • neues Klassendiagramm anlegen
  • Zielsprache ARM C++
  • Zielplattform STM32F042 mySTM32 Board light HAL
  • Diagrammvorlage Application Grundgerüst für PEC Anwendungen (XMC, STM32, AVR) laden
  • Treiberpaket für STM32F0 zuweisen
  • optional Template stm32F042_48Mhz zuweisem

Eine CAN-Bus Lösung zu implementieren ist etwas komplexer. Es ist notwendig sich mit dem CAN-Bus etwas eingehender zu beschäftigen. Bevor wir beginnen sollten uns über folgende Aspekte klar sein:

  • Systemzustände werden zyklisch als Nachrichten auf den Bus gelegt (gesendet)
  • Nachrichten haben keine Empfängeradressen sondern einen ID des abgebildeten Systemzustandes
  • jeder Controller kann die für ihn wichtigen Systemzustände empfangen und darauf reagieren
  • Controller können/müssen die gewünschten Nachrichten (ID's) herausfiltern
  • der/die Systemzustände werden in 64 Bit Nutzdaten (8 Byte) codiert

Versuchen wir die wichtigen Bausteine für den Systementwurf herauszufinden. Der zu sendende Systemzustand ist ein Taster. Für die Codierung des Tasterzustandes wird übrigens lediglich 1 Bit in der zu sendenden Nachricht benötigen. Der Controller wertet die Taste zyklisch, zum Beispiel alle 100 Millisekunden aus, codiert den Zustand (0/1) in einer CAN Nachricht und sendet diese auf dem CAN-Bus. Der empfangende Controller filtert und decodiert die empfangene Nachricht vom CAN-Bus und schaltet entsprechend die LED.



Im Paket „Middleware/CanSupport/pec_Can“ finden sich geeignete Bibliotheksbausteine für die gestellte Aufgabe. Es gibt Bausteine für den CAN-Bus und die Sende- und Empfangsnachrichten. Die für die Lösung wichtigen Elemente sind in der folgenden Darstellung markiert.

Aus den herausgearbeiteten Systembausteinen lassen sich folgende Grobentwürfe der CAN Lösung ableiten.
Zuerst der Grobentwurf für die Senderlösung.

Dazu der korrespondierende Entwurf der Empfängerlösung.

Das CAN-Protokoll ist nicht Bestandteil der PEC-Basispakete sondern im Paket Middleware enthalten. Für die Verwendung der CAN-Bibliotheksbausteine ist es notwendig das entsprechende Treiberpaket „pec_can“ aus dem Ordner „Middleware/CanSupport“ in das Klassendiagramm einzubinden.

MERKE: Middleware benutzen = entsprechendes Paket zuweisen

Zunächst ist die Senderlösung zu implementieren. Beachten Sie, das Paket pec_can in das Klassendiagramm einzubinden.
Eine kurze Zusammenfassung der notwendigen Aktionen:

  • neues Klassendiagramm vorbereiten
  • Paket pec_Can einbinden
  • Klassen SendButton, CanBus und SendMessage anlegen und verbinden
  • Bibliotheksbausteine PecButtonClickAndHold, PecCanBus, PecCanMsgSend anbinden
  • konkrete Controller Ressourcen pinA0 und canPortA11A12_stm32f0 anbinden
  • Operation onEvent100ms der Klasse Controller überschreiben
  • Operation onConfig der Klasse SendMessage überschreiben

In der Operation onConfig() der Klasse MessageRecive weisen wir dem Messagobjekt den ID 1 zu.

SendMessage::onConfig():void
msgId=0x01; 

Für das zyklische Senden des Zustandes des Tasters nutzen wir das 100 Millisekunden Ereignis der Klasse Controller. Den Tasterzustand codieren wir im ersten Datenbyte der Nachricht mit 0 für nicht betätigt und mit 1 für Taster betätigt.

Controller::onEvent100ms():void
if (sendButton.isPressed())
{
	canBus.sendMessage.msgData.data8[0] = 1;
}
else
{
	canBus.sendMessage.msgData.data8[0] = 0;
}
canBus.sendMessage.send();

Danach kann die Empfängerlösung zu implementiert werden. Beachten Sie, das Paket pec_can in das Klassendiagramm einzubinden.
Eine kurze Zusammenfassung der notwendigen Aktionen:

  • neues Klassendiagramm vorbereiten
  • Paket pec_Can einbinden
  • Klassen ReciveLED, CanBus und ReciveMessage anlegen und verbinden
  • Bibliotheksbausteine PecLed, PecCanBus, PecCanMsgRecv anbinden
  • konkrete Controller Ressourcen pinB0 und canPortA11A12_stm32f0 anbinden
  • Operation onRecive der Klasse ReciveMessage überschreiben
  • Operation onConfig der Klasse ReciveMessage überschreiben

Damit die richtige Nachricht empfangen wird weisen wir den ID 1 der erwarteten Empfangsnachricht zu.

ReciveMessage::onConfig():void
msgId=0x01; 

Die Dekodierung der Nachricht realisieren wir einfach im Empfangs-Ereignis des Nachrichtenobjektes.

ReciveMessage::onRecive():void
if (msgData.data8[0] == 1)
{
	app.reciveLED.on();
}
else
{
	app.reciveLED.off();
}

Übersetzen Sie die Lösungen. Korrigieren Sie ggf. Schreibfehler. Übertragen Sie die lauffähigen Programme in den Programmspeicher der Controller.

  1. Erstellen (Kompilieren und Linken)
  2. Brennen
  3. verbinden Sie auf den Boards entsprechend Taster 1 mit A0 und die rote LED mit B0
  4. Stellen Sie zwischen den Boards ein CAN Verbindung her, beachten Sie CAN Hi=Hi, GND=GND, Lo=Lo

Videozusammenfassung

Erlernte und gefestigte Arbeitsschritte:

  1. Klassendiagramm anlegen und öffnen
  2. Diagrammvorlage für PEC Applikation auswählen
  3. laden des richtigen Treiber-Pakets
  4. Middleware-Pakete einbinden
  5. gewünschte Bausteine im Explorer suchen und ins Diagramm ziehen
  6. Klassen aggregieren, Komponenten bilden
  7. Operationen überschreiben
  8. den nötigen Quellcode in den Operationen erstellen
  9. Erstellen und Brennen eine ARM Applikation im Klassendiagramm

Und weil es so schön war hier das Ganze noch mal als Video.

«« ACHTUNG VERALTETES VIDEO »»

Übung

Erweitern Sie beide Lösunge so, dass diese jeweils eine SendeTaste und eine EmpfangsLED besitzen und die Board 1 an 2 und Board 2 an ein sendet.

Weiter mit: