CAN-Versuche Codegenerator DAvEkrre0001/MCT_Labor/CAN_Versuch_v2.pdf · Der CAN-Bus stellt in...

45
Hochschule Karlsruhe Technik und Wirtschaft Fakultät für Maschinenbau und Mechatronik CAN-Versuche & Codegenerator DAvE Einstellen des CAN-Moduls mit Hilfe des automatischen Codegenerators von Dave Prof. Dr.-Ing. Reiner Kriesten Geir Erlandsen B.Eng. 06. Oktober 2013

Transcript of CAN-Versuche Codegenerator DAvEkrre0001/MCT_Labor/CAN_Versuch_v2.pdf · Der CAN-Bus stellt in...

Hochschule Karlsruhe

Technik und Wirtschaft

Fakultät für Maschinenbau und Mechatronik

CAN-Versuche

&

Codegenerator DAvE

Einstellen des CAN-Moduls mit Hilfe des

automatischen Codegenerators von Dave

Prof. Dr.-Ing. Reiner Kriesten Geir Erlandsen B.Eng.

06. Oktober 2013

Inhaltsverzeichnis

1 Einleitung .............................................................................................................................. 1

1.1 CAN-Bus ............................................................................................................................................. 1

1.2 Evaluierungsboard........................................................................................................................ 1

1.2.1 CAN-Transciever ........................................................................................................... 1

1.2.2 Aufbau des CAN-Controllers .................................................................................... 2

1.2.3 Access Mediator – Schnittstelle zum CAN-Modul .......................................... 3

1.3 DAvE .................................................................................................................................................... 4

2 CAN-Modul mit DAvE konfigurieren ............................................................................ 6

2.1 Allgemeine Konfiguration ......................................................................................................... 6

2.1.1 Projekt anlegen .............................................................................................................. 6

2.1.2 Grundeinstellungen ..................................................................................................... 8

2.2 Konfiguration der CAN-Knoten ............................................................................................10

2.2.1 Verwendete Register .................................................................................................10

2.2.2 Konfiguration der Register mit DAvE ...............................................................12

2.2.3 Vergleich von DAvE-Code und selbstgeschriebenem Code ....................15

2.3 Konfiguration der verketteten Liste der Nachrichtenobjekte ...............................18

2.3.1 Verwendete Register .................................................................................................18

2.3.2 Konfiguration der Register mit DAvE ...............................................................19

2.3.3 Vergleich von DAvE-Code und selbstgeschriebenem Code ....................20

2.4 Konfiguration der Nachrichtenobjekte .............................................................................21

2.4.1 Verwendete Register .................................................................................................21

2.4.2 Konfiguration der Register mit DAvE ...............................................................24

2.4.3 Vergleich von DAvE-Code und selbstgeschriebenem Code ....................26

2.5 Funktionsfähiges Beispielprogramm .................................................................................29

2.5.1 Timer 0 konfigurieren mit DAvE .........................................................................29

2.5.2 Hilfsfunktionen mit DAvE erstellen ...................................................................30

2.5.3 Programmlogik hinzufügen ...................................................................................30

2.5.4 Testen des Beispielprogramms auf realer Hardware ...............................33

2.5.5 Testen des Beispielprogramms auf im Simulationsmodus ....................33

3 Laborversuche ................................................................................................................... 35

3.1 A1 - Vorbereitung ........................................................................................................................35

3.2 A2 – Lauflicht und Siebensegmentanzeige ......................................................................35

3.3 A3 – Kombiinstrument ..............................................................................................................36

4 Abbildungsverzeichnis ................................................................................................... 39

5 Literaturverzeichnis........................................................................................................ 40

6 Anhang ................................................................................................................................. 41

6.1 Anhang A – AD-Wandlung .......................................................................................................41

1.1 CAN-Bus

1

1 Einleitung

Das Ziel dieses Versuches ist es Ihnen die Verwendung von DAvE näher zu bringen. Des

Weiteren sollen die Studenten lernen, wie man das CAN-Modul der µC initialisiert und

CAN-Nachrichten senden und empfangen kann.

Um den Unterschied zwischen von DAvE erstelltem und gleichwertigem eigenhändig

erstelltem Softwarecode leichter zu erkennen, werden in den entsprechenden Kapiteln

die zwei Codestücke gegenübergestellt.

Das erste Kapitel soll einen kurzen Überblick über die für diesen Versuch wichtigen

Komponenten geben: den CAN-Bus, das Evaluierungsboard und den Codegenerator

DAvE. In Kapitel 2 wird anhand eines Beispielprogramms gezeigt, wie das CAN-Modul

mit Hilfe von DAvE konfiguriert wird. In Kapitel 3 werden CAN-Versuche beschrieben,

die Sie selbstständig erarbeiten sollen.

1.1 CAN-Bus

Der CAN-Bus stellt in vielen Bereichen, insbesondere in Fahrzeugen und in der

Automatisierungstechnik, eine der wichtigsten Kommunikationsarten dar. Aufgrund

dessen besitzen Rechner der XC800-Familie die Möglichkeit, ihre Informationen an

andere, externe Einheiten per CAN-Bus zu übermitteln und deren Daten zu empfangen.

Die Funktionsweise des CAN-Busses ist in der Vorlesung Mikrocomputertechnik

behandelt worden und wird hier nicht näher erläutert. Ein detaillierter Überblick über

die Funktionsweise und den Aufbau des CAN-Busses findet sich in

[VEC11][ETS08][LAW11].

1.2 Evaluierungsboard

Das im Labor verwendete Evaluierungsboard besitzt einen Mikrocontroller mit einer

Multi-CAN-Einheit, auf welche im weiteren Verlauf näher eingegangen wird.

1.2.1 CAN-Transciever

Die Umrechnung des Differenzsignales auf den – für µCs verwendbaren – TTL-

Pegelbereich mit den Werten 0V (für logisch 0) und 5V (für logisch 1) übernimmt der

1.2 Evaluierungsboard

2

Transceiver. Dieser ist außerhalb des Mikrocontrollers auf der Platine platziert, so dass

der µC nichts von der verwendeten Differenzauswertung „erfährt“.

Das Evaluierungsboard hat 2 Transceiver (für Knoten 0 und Knoten 1) mit jeweils einem

Abschlusswiderstand (siehe Abbildung 1).

Abbildung 1: CAN-Transceiver

1.2.2 Aufbau des CAN-Controllers

Abbildung 2: Schematischer Aufbau der Multi-CAN-Einheit [ddd]

CAN-Transceiver

1.2 Evaluierungsboard

3

Der grundlegende Aufbau des Multi-CAN Moduls der XC800-Einheit sieht wie folgt aus

(siehe Abbildung 2):

1. CAN-Controller - genannt “CAN-Node 0” und “CAN-Node 1”.

▪ Schnittstelle zu den Transceivern und mit Intelligenz ausgestattet.

2. Message Object Buffer

▪ Hier werden die Nutzdaten (max 8 Byte) von maximal 32 CAN-Nachrichten –

genannt Frames – gespeichert. Dieser Puffer besitzt viele Kontrollflags für die

einzelnen Message Objects (Nachrichtenobjekte).

3. Linked List Control

▪ Regelt die Zuweisung der Nachrichtenobjekte an einen der beiden existenten CAN-

Knoten.

▪ Regelt die Priorisierung der Nachrichtenobjekte.

Schnittstelle zu den weiteren internen Einheiten des XC800-Rechners

4. Interrupt Controller

▪ Erlaubt den Sprung in eine Interrupt-Routine

▪ Interrupts können entstehen durch

‐ Fehler in der Versendung und dem Empfang von CAN-Nachrichten

(knotenspezifischer Interrupt)

‐ Nach Versendung oder Empfang einer Nachricht im CAN-Knoten

(knotenspezifischer Interrupt)

‐ Nach Versendung oder Empfang einer Nachricht in einem Nachrichtenobjekt

(nachrichtenspezifischer Interrupt)

5. Clock-Control –Einheit

▪ Gibt den Takt des CAN-Kernels vor

6. Access Mediator

1.2.3 Access Mediator – Schnittstelle zum CAN-Modul

Die Konfigurationsregister des CAN-Moduls sind aufgrund ihrer Vielzahl nicht direkt mit

den Adressleitungen des XC-800-Kerns verbunden und somit nicht direkt vom XC800-

Kern adressierbar. Die Schnittstelle des XC800-Rechners zum CAN-Modul ist über den

Access Mediator geregelt.

1.3 DAvE

4

Der Access Mediator beinhaltet „Transferregister“, die von der CPU ansprechbar sind

und Lese- und Schreibzugriffe auf den „eigentlichen“ CAN-Registern ausführen. Die CAN-

Register sind nicht nur 8-Bit breit, sondern besitzen eine 16-Bit Adresse und sind 32-Bit

breit.

Die Kommunikation des XC800-Rechners mit dem CAN-Modul erfolgt über die

folgenden Transfer-SFR:

CAN_ADLH

In dieses 16-Bit breite Register wird die Adresse des lesenden bzw. des zu

beschreibenden CAN-Registers geschrieben1.

CAN-DATA0 bis CAN_DATA3

Diese 8-Bit breiten Register beinhalten die Daten, die in den CAN-Registern geschrieben

oder von den CAN-Registern gelesen werden.

CAN_ADCON

CAN Address/Data Control Register Reset Value: 0000 0000h

7 6 5 4 3 2 1 0

V3 V2 V1 V0 AUAD BSY RWEN

Dieses 8-Bit breite Register kontrolliert, welche Art der Kommunikation zwischen dem

XC800-Kern und dem CAN-Modul stattfinden soll. Bit 0 entscheidet ob die Daten auf das

CAN-Modul geschrieben oder gelesen werden. Bit 5 bis 8 bieten die Möglichkeit, den

Lese- bzw. Schreibvorgang lediglich für einzelne Datenbytes zuzulassen. Bit 1 zeigt an ob

gerade ein Transfervorgang stattfindet.

1.3 DAvE

Die Inbetriebnahme eines aktuellen Mikrocontrollers erfordert die Kenntnis über eine

ganze Reihe von Registern und ist - je nach Aufgabenstellung - nicht trivial. So sind für

sämtliche Register detaillierte Erklärungen im User Manual [INF10] vorhanden, mit

deren Hilfe die Konfiguration der Register erfolgen kann. Diese Methode fördert zwar in

starkem Maße das Verständnis des µCs, ist jedoch vergleichsweise zeitaufwändig.

Eine Möglichkeit der schnellen Inbetriebnahme bietet hingegen das Programm Digital

Application Virtual Engineer, kurz DAvE. Dieses stellt den Autocode-Konfigurator von

Infineon dar und ist inklusive Dokumentation über die Homepage von Infineon

erhältlich [INF11e].

Dem Entwickler wird eine grafische Oberfläche zur Verfügung gestellt, so dass mit Hilfe

von „Häkchen“ und einfachen Eingabefeldern die Einstellung notwendiger Register

1 Das Transfer-SFR CAN_ADLH ist vom Datentyp srf16, mit dem es möglich ist, 2SFR der Größe 1 Byte direkt zu manipulieren, falls diese hintereinander im Speicher residieren.

1.3 DAvE

5

vorgenommen werden kann. DAvE erstellt hiermit einen ausführbaren C-Code, welcher

die Grundkonfiguration von Ports, CPU und Peripherie-Einheiten darstellt.

Zu erwähnen ist, dass der erstellte Code in einer Art und Weise vorliegt, in der er für

größere Projekte geeignet ist. So existieren für die verschiedenen Peripherie-Einheiten

unterschiedliche Sourcen und Header-Files, es erfolgt die Bereitstellung von Makros und

Getter-/Setter-Funktionen zur Abstraktion der HW-Schicht.

DAvE kann dazu verwendet werden eine schnelle Inbetriebnahme von Peripherie-

Einheiten für ein Programm zu ermöglichen oder bestimmte Registerbelegungen zu

verifizieren. Für einen erfahrenen C-Programmierer sind die erstellten Dateien gut

lesbar aufgebaut.

Schließlich bleibt zu erwähnen, dass die erstellten .c- und .h-Module zusammen mit dem

Setup-Code in die verwendete Entwicklungsumgebung einzubinden sind.

Die Installation von DAvE erfolgt, ohne besondere Einstellungen vornehmen zu müssen.

Allerdings ist darauf zu achten, dass DAvE ein generisches Werkzeug darstellt und

verschiedene µCs von Infineon konfigurieren kann. Aus diesem Grund muss zusätzlich

ein Add-In für das gewünschte Derivat installiert werden, das sogenannte DIP (DAvE

Integration Package). Dieses kann nach der Installation von DAvE über den DAvE Setup

Wizard automatisch per Doppelklick installiert werden und integriert sich in das

Programm. Beim erneuten Öffnen werden die installierten DIPs angezeigt und der

gewünschte µC kann ausgewählt werden.

Achtung:

Wenn Sie mit DAvE Änderungen im Projekt vornehmen und den Quellcode erneut

generieren lassen, wird ALLES gelöscht, was nicht zwischen User Code Begin und User

Code End steht.

2.1 Allgemeine Konfiguration

6

2 CAN-Modul mit DAvE konfigurieren

Wie das CAN-Modul mit DAvE eingestellt wird, kann anhand eines Beispielprogramms

gezeigt werden. In diesem Kapitel wird erst die allgemeine Konfiguration durchgeführt.

Anschließend werden der Reihe nach die CAN-Knoten, die verkettete Liste der

Nachrichtenobjekte und die Nachrichtenobjekte selbst konfiguriert. Ein Auszug der

verwendeten Registern aus den User Manual sind in jedem Unterkapitel eingefügt um

leichter zu erkennen, welche Bits bei der Konfiguration gesetzt werden, ohne im User

Manual suchen zu müssen. Zum Schluss werden in diesem Kapitel die fehlenden

Komponenten für ein lauffähiges Programm ergänzend dargestellt.

2.1 Allgemeine Konfiguration

In diesem Kapitel werden globale Einstellungen des Projektes gezeigt, wie z.B. den

Microcontroller auszuwählen, den CAN-Bus-Clock einzustellen und ein Startup-File

generieren zu lassen.

2.1.1 Projekt anlegen

Zuerst wird ein neues Projekt erstellt. Die Erstellung des Projektes kann auf die

folgenden drei Arten durchgeführt werden:

1. Wenn das untenstehende Startup-Fenster erscheint

- > Mouse-Click auf „Create a new project“

Abbildung 3: Startup-Dialog

2. Navigationsleiste „File“ -> New

3. Über eine der Schaltflächen in der Navigationsleiste -> Symbol „weißes Blatt“

Im folgenden Fenster den richtigen Mikrocontroller auswählen -> XC888CLM

(Abbildung 4)

2.1 Allgemeine Konfiguration

7

Abbildung 4: Fenster „New Project“

Jetzt sollte das untenstehende Fenster im Vordergrund zu sehen sein (Abbildung 5):

Abbildung 5: Projekt Settings

Sie können jetzt das Projekt speichern, indem Sie auf der Navigationsleiste „File“ -> Save

klicken und den gewünschten Speicherort auswählen.

2.1 Allgemeine Konfiguration

8

2.1.2 Grundeinstellungen

In Abbildung 5 sehen Sie das Fenster, in dem allgemeine Einstellungen des Projektes

eingestellt werden können. Die vorgewählten Einstellungen können für den weiteren

Verlauf belassen werden. Eventuell kann „Device“ auf XC888CM-8FF“ geändert werden,

dies ist aber nicht zwingend notwendig. Mit den voreingestellten Werten wird:

System-Clock auf 96MHz und Peripherie-Clock (PCLK) auf 24Mhz gesetzt. Der

CAN-Modul wird mit 48MHz angesteuert da dieser an die Frequenz FCLK

gekoppelt ist.

der Global Interrupt gesetzt.

Main.c und Main.h und Startup-File erstellt.

Schließen Sie das Fenster, indem Sie auf das rote „Kreuz“ klicken.2

Hauptfenster

Abbildung 6: Hauptfenster

Jetzt sehen Sie in Abbildung 6 das Hauptfenster von DAvE. Hinter den im grafischen

Fenster dargestellten Einheiten verbirgt sich jeweils ein Konfigurationsmenü, um die

verschiedenen Peripherieeinheiten zu konfigurieren.

Drücken Sie jetzt auf das Symbol „Blitz“. Damit wird der C-Code erstellt.

2 Würden Sie jetzt schon einen ausführbaren C-Code erstellen, indem Sie auf die Schaltfläche mit dem „ Blitzsymbol“ drücken, würden Sie feststellen, dass sehr viel Code erstellt wurde, obwohl Sie bis jetzt eigentlich kaum was eingestellt haben.

2.1 Allgemeine Konfiguration

9

Im Projektordner sehen Sie jetzt die MAIN.C- und MAIN.H-Dateien und die Datei mit dem

Startup-Code (START_XC.A51).

Durch Doppelklick auf „Projekt.dpt“ können Sie das Projekt in Keil öffnen. Im Ordner

„Dave Files“ befinden sich die autogenerierten Dateien von DAvE.

Dateien

Start_XC.a51

Diese Datei sollte Ihnen bekannt sein und dient als korrekte Startup-Sequenz für den

Mikrocontroller und den Sprung an die Main-Funktion in der Source-Datei MAIN.C.

MAIN.H

Sie können noch die Datei MAIN.H manuell ins Projekt einbinden. Beim Öffnen der Datei

MAIN.H sehen Sie eine Auflistung mit der Zuordnung der SFR-Namen zu den jeweiligen

8-Bit Adressen. Zusätzlich werden die einzelnen Bits in den Bitadressierbaren Registern

mit Namen versehen. Das gleiche gilt für 16-bit SFR.

MAIN.C

Beim Öffnen der Datei MAIN.C sehen Sie, dass in der Funktion main() die Funktion

MAIN_vInit() aufgerufen wird. Vorläufig wird hier wenig gemacht. Am Ende der Funktion

MAIN_vInit() können Sie sehen, dass das Global Interrupt Flag gesetzt ist, wie bereits

zuvor festgelegt wurde.

2.2 Konfiguration der CAN-Knoten

10

2.2 Konfiguration der CAN-Knoten

In diesem Kapitel werden die CAN-Knoten 0 und 1 konfiguriert. Sie sind die

Schnittstellen zwischen den Nachrichtenobjekten und den CAN-Transceivern. Zunächst

werden die verwendeten Register vorgestellt. Anschließend wird gezeigt, wie man die

Register mit Hilfe von DAvE konfiguriert. Zum Schluss wird der von DAvE erzeugte

Quellcode mit einem gleichwertigen „von Hand“ eingetippten Quellcode verglichen. So

hat man einen direkten Vergleich und kann die Unterschiede besser erkennen.

2.2.1 Verwendete Register

2.2.1.1 CAN_NCRx - Node Control Register

NCRx – Node x Control Register Reset Value: 0000 0001h

31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

CALM CCE 0 CANDIS ALIE LECIE TRIE INIT

Funktion

Freischalten von Interrupts (Empfang und Versenden)

Freischalten des CAN-Knotens für den Betrieb am Bus

Wichtige Bits

Init: Teilnahme am Bus, wenn das Bit den Wert 0 hat

CCE: Konfiguration der Register erlaubt, wenn das Bit den Wert 1 hat

2.2.1.2 NPCRx - Node Port Control Register

NPCRx – Node x Port Control Register Reset Value: 0000 0000h

31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

LBM RXSEL

Funktion

Festlegung der Ein-/Ausgangsports zu den Transceivern

Die CAN-Knoten „intern“ miteinander verbinden

2.2 Konfiguration der CAN-Knoten

11

Wichtige Bits

RXSEL (Receive Input Selection): RXSEL==3 -> Port 1.4 ausgewählt

LBM: Loop-Back Mode aktiv, wenn das Bit den Wert 1 hat

2.2.1.3 NBTRx - Node Bit Timing Register

NBTRx – Node x Bit Timing Register Reset Value: 0000 0000h

31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

DIV8 TSEG2 TSEG1 SJW BRP

Funktion

Datenrate des CAN-Busses festlegen

Wichtige Bits

BRP: Baud Rate Prescaler

2.2.1.4 Weitere Register

Weitere Konfigurationsregister für die CAN-Knoten sind in [INF10] zu finden, können

aber auf ihren Initialwerten belassen werden.

2.2 Konfiguration der CAN-Knoten

12

2.2.2 Konfiguration der Register mit DAvE

Durch einen Klick auf die MultiCAN-Einheit im Hauptfenster3 wird das

Konfigurationsfenster geöffnet (siehe Abbildung 7). Im Reiter „Module Clock“ werden

die voreingestellten Werte belassen. Wie Sie sehen, arbeitet das CAN-Modul mit 48MHz.

Abbildung 7: Multi-CAN-Modul

Gehen Sie auf den Reiter “Nodes” und klicken Sie auf den Button „Node 0“. In dem sich

öffnenden Fenster werden die Portbelegungen für den Knoten 0 festgelegt (siehe

Abbildung 8). Wählen Sie P1.0 als Empfangspin und P1.1 als Sendepin.

Abbildung 8: Pin-Festlegungen für Knoten 0

Im Reiter „Control“ werden zwei Häkchen gesetzt (siehe Abbildung 9), und zwar bei

“Initalize the CAN Node 0” und “Enable the Loop-Back Mode”. Für dieses

Beispielsprogramm wird kein Interrupt auf Knotenebene aktiviert.

3 Siehe Abbildung 6

2.2 Konfiguration der CAN-Knoten

13

Abbildung 9: Initialisierungseinstellungen für Knoten 0

Im Reiter „Baud Rate“ wird im Feld „Required baud rate“ 100 eingetragen (100kbaud).

Die anderen Felder ändern sich dadurch automatisch bzw. werden auf ihrem Initialwert

belassen.

Für Knoten 1 wird analog vorgegangen. Allerdings wird hier P1.3 als Outputpin und P1.4

als Inputpin gewählt.

Damit die Einstellungen bei der Codegenerierung berücksichtigt werden, muss im Reiter

„Functions“ das Häkchen bei „CAN_vInit“ gesetzt werden. Generieren Sie jetzt den Code

erneut. Wie sie sehen sind jetzt zwei neue Dateien dazugekommen - CAN.H und CAN.C.

CAN.H-Datei

Beim Öffnen der Datei CAN.H sehen Sie eine Auflistung mit der Zuordnung der

Registernamen des CAN-Moduls zu den jeweiligen 16-Bit Adressen. Dabei gilt zu

beachten, dass die angegebenen Adressen nicht mit den Adressen im Handbuch (User

Manual) [INF10] übereinstimmen. Mit einem doppelten Linksshift (<<) – welcher hier

nicht durchgeführt werden muss bzw. darf - stimmen die Werte mit denen im Handbuch

überein4.

4 Näheres dazu, siehe [KRI12, S.159].

2.2 Konfiguration der CAN-Knoten

14

Erwähnenswert sind 4 wichtige Macros, die in der Datei CAN.H definiert sind und in den

nächsten Abschnitten weiter verwendet werden:

1

2

#define CAN_vReadEN() CAN_ADCON = 0x00; while(CAN_ADCON & CAN_ADCON_BSY) //#define CAN_ADCON_BSY 0x02 -> Startet Lesevorgang

1

2

3

#define CAN_vWriteEN(ubDCtrl) CAN_ADCON = ((ubDCtrl) | ADCON_W); while(CAN_ADCON & CAN_ADCON_BSY) -> Startet Schreibvorgang

1

2

#define CAN_vWriteCANAddress(uwAdr) CAN_ADLH = uwAdr -> Transfer der Registeradresse

1

2

3

4

#define CAN_vWriteCANData(ulValue) CAN_DATA01 = (ulValue & 0xFFFF); \ CAN_DATA23 = (ulValue >> 16) & 0xFFFF; \ CAN_vWriteEN(ALL_DATA_VALID)

-> Datenbytes 0 bis 3 werden beschrieben

Erwähnenswert sind auch zwei wichtige globale Funktionen, die hier deklariert sind:

1

2

void CAN_vSetListCommand(ulong ulVal) -> Hier werden die Message-Objekten zu den Listen verknüpft und somit zu den Knoten verbunden

1

2

void CAN_vWriteAMData(ulong ulValue) -> Hier werden 32-Bit Data an den CAN Data-Registers 0 bis 3 geschrieben. Zur Hilfe wird dabei eine Union-Struktur verwendet.

CAN.C Datei

In dieser Datei werden die CAN-Register initialisiert. Vorläufig sind nur die Knoten-

Register und das „P1 ALTSEL“-Register konfiguriert. Am Ende der Datei finden Sie den

Quellcode, der die Knoten für die Busteilnahme aktiviert.

2.2 Konfiguration der CAN-Knoten

15

2.2.3 Vergleich von DAvE-Code und selbstgeschriebenem Code

In diesem Kapitel wird der von DAvE generierter Code mit einem gleichwertigen

eigenhändig erstellten Code verglichen.

2.2.3.1 CAN_NCRx - Node Control Register

NCRx – Node x Control Register Reset Value: 0000 0001h

31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

CALM CCE 0 CANDIS ALIE LECIE TRIE INIT

DAvE-Code

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

//-----------CAN_NCR0 = 0x00000041-------------------------------------

CAN_vWriteCANAddress(CAN_NCR0); // Addressing CAN_NCR0 CAN_DATA0 = 0x41; // load NODE 0 control register[7-0] CAN_vWriteEN(D0_VALID); // Data0 is Valid for transmission //-----------CAN_NCR1 = 0x00000041-------------------------------------

CAN_vWriteCANAddress(CAN_NCR1); // Addressing CAN_NCR1 CAN_DATA0 = 0x41; // load NODE 0 control register[7-0] CAN_vWriteEN(D0_VALID); // Data0 is Valid for transmission

// -----------------------------------------------------------------------

// Start the CAN Nodes:

// -----------------------------------------------------------------------

// - -----------CAN_NCR0---------------------------------------------------

CAN_vWriteCANAddress(CAN_NCR0); // Addressing CAN_NCR0 CAN_vReadEN(); // Read Mode is Enabled CAN_DATA0 &= ~0x41; // reset INIT and CCE CAN_vWriteEN(D0_VALID); // Data0 is Valid for transmission and Write is Enabled

Selbstgeschriebener Code

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

/**** Knoten 0 - Initialisierung ****/

CAN_ADLH=CAN_NCR0; CAN_DATA0=0x41; // -stop trafic CAN_ADCON=0x11; while(CAN_ADCON&0x02){;} /**** Knoten 1 - Initialisierung ****/ CAN_ADLH=CAN_NCR1; CAN_DATA0=0x41; CAN_ADCON=0x11; while(CAN_ADCON&0x02){;}

/**** Starten der CAN-Knoten ****/ CAN_ADLH=CAN_NCR1; // Knoten 1 CAN_ADCON=0x00; CAN_DATA0 &= ~0x41; CAN_ADCON=0x11; while(CAN_ADCON&0x02){;}

2.2 Konfiguration der CAN-Knoten

16

2.2.3.2 CAN_NPCRx - Node Port Control Register

NPCRx – Node x Port Control Register Reset Value: 0000 0000h

31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

LBM RXSEL

DAvE-Code

1

2

3

4

5

6

7

8

9

10

//-----------CAN_NPCR0 = 0x00000000-------------------------------------

CAN_vWriteCANAddress(CAN_NPCR0); // Addressing CAN_NPCR0 CAN_DATA0 = 0x00; // Pin P1.0 is used as RXDC0_0 input CAN_DATA1 = 0x00; // Loop-back mode is disabled CAN_vWriteEN(D0_VALID+D1_VALID); //-----------CAN_NPCR0 = 0x00000003-------------------------------------

CAN_vWriteCANAddress(CAN_NPCR1); // Addressing CAN_NPCR1 CAN_DATA0 = 0x03; // Pin P1.4 is used as RXDC1_3 input CAN_DATA1 = 0x00; // Loop-back mode is disabled CAN_vWriteEN(D0_VALID+D1_VALID);

Selbstgeschriebener Code

1

2

3

4

5

6

7

8

9

10

11

12

13

/**** Knoten 0 - Initialisierung ****/ CAN_ADLH=CAN_NPCR0; CAN_DATA0=0x00;// wähle P1.0, P1.1 CAN_DATA1=0x00;// kein Loopback

CAN_ADCON=0x31; while(CAN_ADCON&0x02){;} /**** Knoten 1 - Initialisierung ****/ CAN_ADLH=CAN_NPCR1; CAN_DATA0=0x03;// RXSEL=3 (gemäß DAVE) CAN_DATA1=0x00;// kein Loopback CAN_ADCON=0x31; while(CAN_ADCON&0x02){;}

2.2 Konfiguration der CAN-Knoten

17

2.2.3.3 CAN_BTRx - Node Bit Timing Register

NBTRx – Node x Bit Timing Register5 Reset Value: 0000 0000h

31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

DIV8 TSEG2 TSEG1 SJW BRP

DAvE-Code

1

2

3

4

5

6

7

8

9

10

//-----------CAN_NPCR0 = 0x00000000-------------------------------------

// - required baud rate = 100,000 kbaud

// - real baud rate = 100,000 kbaud

// - there are 9 time quanta before sample point

// - there are 2 time quanta after sample point

//-----------CAN_NBTR0 = 0x00001867-------------------------------------

CAN_vWriteCANAddress(CAN_NBTR0); // Addressing CAN_NBTR0 CAN_DATA0 = 0x67; // load NBTR0_SJW, BRP CAN_DATA1 = 0x18; // load NBTR0_DIV8, TSEG2, TSEG1 CAN_vWriteEN(D0_VALID+D1_VALID);

Selbstgeschriebener Code

1

2

3

4

5

6

/**** Knoten 0 - Initialisierung ****/ CAN_ADLH=CAN_NBTR0; CAN_DATA0=0x6F; // 100 kBaud CAN_DATA1=0x34;

CAN_ADCON=0x31; while(CAN_ADCON&0x02){;}

5 Die unterschiedlichen Daten erklären sich dadurch, dass DAvE andere Werte für die Zeitsegmente Tseg1, Tseg2 annimmt als der selbstgeschriebene Code und somit auch die Quantendauer variiert.

2.3 Konfiguration der verketteten Liste der Nachrichtenobjekte

18

2.3 Konfiguration der verketteten Liste der Nachrichtenobjekte

Die Hauptaufgaben der drei Listen sind es, die Nachrichtenobjekte den beiden Knoten

zuzuordnen.

In Liste 0 sind die Nachrichtenobjekte, welche keinem CAN-Knoten zugehörig sind.

In Liste 1 sind die Nachrichtenobjekte mit Zuordnung zum CAN-Knoten 0

In Liste 2 sind die Nachrichtenobjekte mit Zuordnung zum CAN-Knoten 1

Als erstes werden die verwendeten Register vorgestellt. Anschließend wird gezeigt, wie

die Register mit Hilfe von DAvE konfiguriert werden. Zum Schluss wird der von DAvE

erzeugte Quellcode mit einem gleichwertigen „von Hand“ eingetippten Quellcode

verglichen. So kann ein direkter Vergleich gezogen werden und der Unterschied ist

besser zu erkennen.

2.3.1 Verwendete Register

2.3.1.1 CAN_PANCTR – Panel Control Register

PANCTR –Panel Control Register Reset Value: 0000 0301h

31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16

PANAR2 PANAR1

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

RBUSY BUSY PANCMD

Funktion

Einzelne Nachrichtenobjekte den beiden CAN-Knoten zuzuordnen oder wieder zu

entfernen.

Wichtige Bits

PANCMD: Befehlsauswahl. Z.B. PANCMD==2 -> Erlaubt eine neue Zuordnung der

Nachrichtenobjekte zu den Listen.

PANAR1: Definiert das zu verwendende Nachrichtenobjekt

PANAR2: Definiert, welcher Liste dem Objekt zugeordnet wird.

2.3 Konfiguration der verketteten Liste der Nachrichtenobjekte

19

2.3.2 Konfiguration der Register mit DAvE

Im Reiter „Lists“ kann die Zuordnung der Nachrichtenobjekte zu den Listen

vorgenommen werden. Ziehen Sie hierzu das Objekt „MO0“ von Liste 0 zu Liste 1.

Danach ziehen Sie das Objekt „MO1“ von Liste 0 zu Liste 2. Die unterschiedlichen

„Levels“ regeln die Priorität der Nachrichtenobjekte, sind aber für dieses

Beispielsprogramm unbedeutend.

Abbildung 10: Listenkonfiguration

2.3 Konfiguration der verketteten Liste der Nachrichtenobjekte

20

2.3.3 Vergleich von DAvE-Code und selbstgeschriebenem Code

In diesem Kapitel wird der von DAvE generierter Code mit einem gleichwertigen

manuell erstellten Code verglichen.

2.3.3.1 CAN_PANCTR – Panel Control Register

PANCTR –Panel Control Register Reset Value: 0000 0301h

31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16

PANAR2 PANAR1

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

RBUSY BUSY PANCMD

DAvE Code

1

2

3

4

5

6

7

8

// -----------------------------------------------------------------------

// Configuration of the CAN Message Object List Structure:

// -----------------------------------------------------------------------

CAN_vWriteCANAddress(CAN_PANCTR); // Addressing CAN_PANCTR // Allocate MOs for list 1:

CAN_vSetListCommand(0x01000002); // MO0 for list 1 // Allocate MOs for list 2:

CAN_vSetListCommand(0x02010002); // MO1 for list 2

Selbstgeschriebener Code

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

/**** Zuweisung Knoten zu Liste ****/ // Message Object 0 zu List 1

CAN_ADLH=CAN_PANCTR; CAN_DATA0=0x02; CAN_DATA1=0x00; CAN_DATA2=0x00; CAN_DATA3=0x01; CAN_ADCON=0xF1; while(CAN_ADCON&0x02){;}

do {

CAN_ADCON &=0xFE; while(CAN_ADCON&0x02){;}

}while(CAN_DATA1 & 0x01); // Message Object 1 zu List 2

CAN_ADLH=CAN_PANCTR; CAN_DATA0=0x02; CAN_DATA1=0x00; CAN_DATA2=0x01;

CAN_DATA3=0x02; CAN_ADCON=0xF1; while(CAN_ADCON&0x02){;} do {

CAN_ADCON &=0xFE; while(CAN_ADCON&0x02){;}

}while(CAN_DATA1 & 0x01);

2.4 Konfiguration der Nachrichtenobjekte

21

2.4 Konfiguration der Nachrichtenobjekte

In diesem Kapitel werden die Nachrichtenobjekte konfiguriert. Erst werden die

verwendeten Register vorgestellt. Anschließend wird gezeigt, wie die Register mit Hilfe

von DAvE konfiguriert werden. Zum Schluss wird der von DAvE erzeugte Quellcode mit

einem gleichwertigen „von Hand“ eingetippten Quellcode verglichen. So kann ein

direkter Vergleich gezogen werden und der Unterschied ist besser zu erkennen.

2.4.1 Verwendete Register

2.4.1.1 MOCTRn – Message Object Control Register6

MOCTRx –Message Object Control Register x Reset Value: 0100 0000h

31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16

SET -> DIR TXEN1 TXEN0 TXRQ RXEN RTSEL MSGVAL MSGLST NEWDAT RXUPD TXPND RXPND

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

RESET -> DIR TXEN1 TXEN0 TXRQ RXEN RTSEL MSGVAL MSGLST NEWDAT RXUPD TXPND RXPND

Funktion

Freischalten des Nachrichtenobjekts zur Teilnahme an der CAN-Kommunikation

Nachrichtenobjekt als Empfangspuffer oder Sendepuffer festlegen

Freischalten der Versendung oder des Empfangs der Nachricht

Wichtige Bits

DIR: Sendeobjekt, wenn das Bit den Wert 1 hat, sonst Empfangsobjekt

TXEN0 und TXEN1: Freischaltbits für die Versendung

RXEN: Freischaltbit für den Empfang

MSGVAL: Gültigkeit des Objekts –> Gültig wenn 1

TXRQ: „Hauptschalter“ zum Versenden einer Nachricht

NEWDAT: Wird gesetzt, falls nach seinem letzten Reset eine neue Nachricht

empfangen wurde

RXUPD: Zeigt an, ob das Nachrichtenobjekt aktuell vom CAN-Knoten erneuert wird

6 MOCTRn wird verwendet, um einzelne dedizierte Bits in das Register CAN_MOSTAT zu setzen oder zu löschen, da das CAN_MOSTAT nicht direkt beschrieben werden kann.

2.4 Konfiguration der Nachrichtenobjekte

22

2.4.1.2 MOFCRn – Message Object Function Control Register

MOFTRn – Message Object Function Control Register n Reset Value: 0000 0000h

31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16

0 DLC STT SDT RMM FRREN 0 OVIE TXIE RXIE

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

0 DATC DLCC IDC GDFS 0 MMC

Funktion

Angabe der Länge der Nutzdaten

Message Objekt Typ festlegen

Interrupt beim Versenden oder Empfangen einer Nachricht aktivieren

Wichtige Bits

MMC: 0 -> Standard Message Object

DLC: Nutzdatenlänge festlegen

TXIE: TX-Interrupt Enable

RXIE: RX-Interrupt Enable

2.4.1.3 MOIPRn – Message Object Interrupt Pointer Register n

MOIPRn – Message Object Interrupt Pointer Register n Reset Value: 0000 0000h

31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16

CFCVAL

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

MPN TXINP RXINP

Funktion

Selektion der Interrupt-Knoten für Sendeereignisse und für Empfangsereignisse.Es

kann zwischen 8 Interrupt-Quellen gewählt werden, die auf unterschiedlichen

Interrupt-Knoten liegen. Zum Beispiel liegt CANSRC0 auf dem Interrupt-Knoten 5,

während CANSCR4 auf dem Interrupt-Knoten 10 liegt.7,8

Wichtige Bits

TXINP: Festlegung der Interrupt-Knoten beim Versenden

RXINP: Festlegung der Interrupt-Knoten beim Empfangen

7 Siehe Kap. 5.2 im Handbuch. 8 Achtung: gemäß [INF10] ist MultiCAN Node 0 mit Knoten 5 verbunden. Damit ist aber nicht der CAN-Knoten 0 gemeint, sondern der Interrupt-Trigger CANSRC0 liegt auf dem Interrupt-Knoten 5. Das gleiche gilt natürlich für MultiCAN Node 1 auf Knoten 6.

2.4 Konfiguration der Nachrichtenobjekte

23

2.4.1.4 MOARn – Message Object Arbitration Register n

MOARn – Message Object Arbitration Register n Reset Value: 0000 0000h

31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16

PRI IDE ID-Standard ID-EX

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

ID-EX

Funktion

Festlegung des Identifiers des Nachrichtenobjektes

Festlegung der Nachrichtenpriorität

Wichtige Bits

ID: Identifier des Nachrichtenobjektes

PRI: Nachrichtenpriorität festlegen

2.4 Konfiguration der Nachrichtenobjekte

24

2.4.2 Konfiguration der Register mit DAvE

Im Reiter „MOs“ kann man zwischen 32 Nachrichtenobjekten wählen und diese per

Mausklick konfigurieren (siehe Abbildung 11).

Abbildung 11: Nachrichtenobjekte

Als erstes wird Message Objekt 0 konfiguriert. Klicken Sie auf den Button „MO 0“. In dem

sich öffnenden Fenster aktivieren Sie den Reiter „Object„ und bearbeiten Sie die

folgenden Felder (siehe Abbildung 12):

Enable message object 0 -> Häkchen setzen

Message Direction -> „Transmit data frames“ auswählen

Data Length Code (DLC) -> 1 Byte auswählen

Identifier 11-bit -> 4 eintippen

Priority Class -> „list order“ auswählen

Die anderen Einstellungen können so übernommen werden

Für Message Objekt 1 gehen Sie analog vor. Nur bei „Message Direction“ müssen Sie jetzt

„Receive data frames“ auswählen.

2.4 Konfiguration der Nachrichtenobjekte

25

Abbildung 12: Message Objekt 0 konfigurieren

In diesem Beispiel wird nur der Interrupt beim Empfangen einer Nachricht aktiviert.

Wählen Sie im Menü für Message Objekt 1 den Reiter „Interrupt“ aus und setzen Sie das

Häkchen bei „Enable receive interrupt“.9 Unter „Receive interrupt node pointer“ wählen

Sie „Use CAN SRN 4“ aus.10

Abbildung 13: Message Objekt 1 konfigurieren

9Message Objekt 1 ist ja ein Empfangsobjekt. 10 Damit wird Message Objekt 1 mit der Interrupt-Quelle CANSCR4 verknüpft, die wiederum mit Interrupt Knoten 10 (XINTR10) verbunden ist.

2.4 Konfiguration der Nachrichtenobjekte

26

2.4.3 Vergleich von DAvE-Code und selbstgeschriebenem Code

In diesem Kapitel wird der von DAvE generierter Code mit einem gleichwertigen

manuell erstellten Code verglichen.

2.4.3.1 CAN_MOCTRn – Message Object Control Register

MOCTRx –Message Object Control Register x Reset Value: 0100 0000h

31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16

SET -> DIR TXEN1 TXEN0 TXRQ RXEN RTSEL MSGVAL MSGLST NEWDAT RXUPD TXPND RXPND

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

RESET -> DIR TXEN1 TXEN0 TXRQ RXEN RTSEL MSGVAL MSGLST NEWDAT RXUPD TXPND RXPND

DAvE Code

1

2

3

4

5

6

7

//--------------MOCTR0 = 0x0EA80000---------------------------------------

CAN_vWriteCANAddress(CAN_MOCTR0); // Addressing MO0 control register CAN_vWriteAMData(0x0EA80000); // load MO0 control register //--------------MOCTR1 = 0x00A00000---------------------------------------

CAN_vWriteCANAddress(CAN_MOCTR1); // Addressing MO1 control register CAN_vWriteAMData(0x00A00000); // load MO1 control register

Selbstgeschriebener Code

1

2

3

4

5

6

7

8

9

10

11

12

/**** Message Object 0 - Initialisierung ****/ CAN_ADLH=CAN_MOCTR0; CAN_DATA2=0x20; CAN_DATA3=0x0E; CAN_ADCON=0xC1; while(CAN_ADCON&0x02){;} /**** Message Object 1 - Initialisierung ****/ CAN_ADLH=CAN_MOCTR1; CAN_DATA2=0xA0; CAN_DATA3=0x00;

CAN_ADCON=0xC1; while(CAN_ADCON&0x02){;}

2.4.3.2 MOFCRn – Message Object Function Control Register

MOFTRn – Message Object Function Control Register n Reset Value: 0000 0000h

31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16

0 DLC STT SDT RMM FRREN 0 OVIE TXIE RXIE

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

0 DATC DLCC IDC GDFS 0 MMC

2.4 Konfiguration der Nachrichtenobjekte

27

DAvE Code

1

2

3

4

5

6

7

8

//--------------MOFCR0 = 0x01000000---------------------------------------

CAN_vWriteCANAddress(CAN_MOFCR0); // Addressing MO0 control register CAN_vWriteAMData(0x01000000); // load MO0 function control register //--------------MOFCR1 = 0x01010000---------------------------------------

// enable receive interrupt; bit RXPND is set after successful reception of a frame

CAN_vWriteCANAddress(CAN_MOFCR1); // Addressing MO0 control register CAN_vWriteAMData(0x01010000); // load MO1 function control register

Selbstgeschriebener Code

1

2

3

4

5

6

7

8

9

10

11

12

13

/**** Message Object 0 - Initialisierung ****/ CAN_ADLH=CAN_MOFCR0; CAN_DATA2=0x00; CAN_DATA3=0x01; CAN_ADCON=0xC1; while(CAN_ADCON&0x02){;} /**** Message Object 1 - Initialisierung ****/

CAN_ADLH=CAN_MOFCR1; CAN_DATA2=0x01; // Rx-Interrupt Enable CAN_DATA3=0x01; CAN_ADCON=0xC1; while(CAN_ADCON&0x02){;}

2.4.3.3 MOIPRn – Message Object Interrupt Pointer Register

MOIPRn – Message Object Interrupt Pointer Register n Reset Value: 0000 0000h

31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16

CFCVAL

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

MPN TXINP RXINP

DAvE Code

1

2

3

4

5

6

7

8

//--------------MOIPR0 = 0x00000000---------------------------------------

CAN_vWriteCANAddress(CAN_MOIPR0); // Addressing MO0 control register CAN_vWriteAMData(0x00000000); // load MO0 interrupt pointer register //--------------MOIPR1 = 0x00000104---------------------------------------

// receive interrupt node pointer: MultiCAN SRN 4

CAN_vWriteCANAddress(CAN_MOIPR1); // Addressing MO1 control register CAN_vWriteAMData(0x00000104); // load MO1 interrupt pointer register

Selbstgeschriebener Code

1

2

3

4

5

6

7

/**** Message Object 0 - Initialisierung ****/

// keine Einstellungen

/**** Message Object 1 - Initialisierung ****/ CAN_ADLH=CAN_MOIPR1; CAN_DATA0=0x04; CAN_ADCON=0x11; while(CAN_ADCON&0x02){;}

2.4 Konfiguration der Nachrichtenobjekte

28

2.4.3.4 MOARn – Message Object Arbitration Register n

MOARn – Message Object Arbitration Register n Reset Value: 0000 0000h

31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16

PRI IDE ID-Standard ID-EX

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

ID-EX

DAvE Code

1

2

3

4

5

6

//--------------MOAR0 = 0xC0100000---------------------------------------

CAN_vWriteCANAddress(CAN_MOAR0); // Addressing MO0 control register CAN_vWriteAMData(0xC0100000); // load MO0 arbitration register //--------------MOAR1 = 0xC0100000---------------------------------------

CAN_vWriteCANAddress(CAN_MOAR1); // Addressing MO1 control register

CAN_vWriteAMData(0xC0100000); // load MO1 arbitration register

Selbstgeschriebener Code

1

2

3

4

5

6

7

8

9

/**** Message Object 0 - Initialisierung ****/ CAN_ADLH=CAN_MOAR0; CAN_DATA2=0x10; // ID 0x04 CAN_DATA3=0xC0; // CAN_ADCON=0xC1; while(CAN_ADCON&0x02){;}

/**** Message Object 1 - Initialisierung ****/ // gleiche Einstellungen wie für Message Objekt 0

2.5 Funktionsfähiges Beispielprogramm

29

2.5 Funktionsfähiges Beispielprogramm

Die Konfiguration der CAN-Register ist jetzt abgeschlossen. Damit das

Beispielprogramm funktionsfähig wird, müssen einige Codefragmente ergänzt werden.

In diesem Kapitel wird erst der „Timer 0“ mit Hilfe von DAvE initialisiert. Anschließend

werden einige Hilfsfunktionen aufgelistet, die von DAvE generiert werden. Zum Schluss

wird noch der fehlende Quellcode für die nötige Programmlogik bereitgestellt.

Das Programm soll folgendes tun: Die Zustände der Taster T1, T2 und T3 werden

zyklisch alle 10 ms an den Portpins P2.0, P2.1 und P2.2 eingelesen und über

Nachrichtenobjekt 0 und CAN-Knoten 0 übertragen. Der Empfang erfolgt auf CAN-

Knoten 1 und Nachrichtenobjekt 1. In Folge des Empfangs wird der zugehörige

Interrupt des Objektes 1 ausgelöst. Die ausgelesenen Nutzdaten modifizieren Port P3: Ist

Taster 1 gedrückt, so werden die „ungeraden“ LEDs eingeschaltet, ist Taster 2 gedrückt,

so werden die „geraden“ LEDs eingeschaltet und Taster 3 schaltet sämtliche LEDs aus

und besitzt Priorität gegenüber den anderen Tastern.

2.5.1 Timer 0 konfigurieren mit DAvE

Timer 0 ist mit Hilfe von DAvE sehr schnell konfiguriert. Durch einen Klick auf die

Timer-Einheit (T0/T1) im Hauptfenster11 wird das Konfigurationsfenster geöffnet

(siehe Abbildung 14). Im Reiter „Timer 0“ bearbeiten Sie die folgenden Felder:

Timer Mode -> Häkchen setsen bei Mode 1: 16-bit Timer

Timer Registers-> Im Feld TL0 0xA0 eintragen

Timer Registers-> Im Feld TH0 0x15 eintragen

Timer Options -> Häkchen setzen bei „Turn on timer“

Interrupt Control -> Häkchen setzen bei „ET0“

Zum Schluss muss im Reiter „Functions“ bei „T01_vInit“ das Häkchen gesetzt werden,

damit die Dateien T01.H und T01.C erstellt werden.

11 Siehe Abbildung 6

2.5 Funktionsfähiges Beispielprogramm

30

Abbildung 14: Timer 0

2.5.2 Hilfsfunktionen mit DAvE erstellen

Folgende sinnvollen Funktionen können zusätzlich von DAvE erstellt werden:

Um CAN-Nachrichten zu senden:

1

2

3

4

5

6

7

8

ubyte CAN_ubRequestMsgObj(ubyte ubObjNr); -> Hier wird überprüft ob das Objekt beschreibbar ist oder aktuell verwendet wird.

void CAN_vLoadData(ubyte ubObjNr, ulong *ulpubData); -> Hier werden Datenwerte in das gewählte Nachrichtenobjekt geladen. void CAN_vTransmit(ubyte ubObjNr); -> Hier werden die Daten auf dem Bus gelegt in dem das Bit TXRQ gesetzt wird.

Um CAN-Nachrichten zu empfangen:

1

2

ulong CAN_ulGetCANData(void) -> Hier werden die Datenwerte im gewählten Nachrichtenobjekt als Rückgabewert verwendet.

Erstellen Sie die Funktionen, indem Sie im Konfigurationsfenster der MultiCAN-Einheit

unter den Reitern „Functions“ und „Functions2“ die entsprechenden Funktionen

aktivieren.

2.5.3 Programmlogik hinzufügen

Als letzter Schritt werden die generierten Dateien mit benutzerdefinierter Quellcode

ergänzt.12 Damit alle 10 ms eine CAN-Nachricht übertragen wird, fügen Sie folgenden

Quellcode innerhalb der Funktion T01_viTmr0() hinzu:

DAvE Code

1

2

3

4

ulong can_content0=0x00; static ubyte zaehler=0x00; TL0 = 0xA0;

TH0 =0x15;

12 Achtung: Wie in der Anleitung schon erwähnt, dürfen Sie nur Quellcode innerhalb eines „USER CODE BEGIN - USER CODE END“-Abschnittes hinzufügen.

2.5 Funktionsfähiges Beispielprogramm

31

5

6

7

8

9

10

11

12

13

14

15

16

17

18

zaehler++; if(zaehler==2) //10 ms Raster {

zaehler=0; // Einlesen der Tasterstellungen

can_content0|=(ubyte)TASTER_1 + ((ubyte)TASTER_2<<1) + ((ubyte)TASTER_3 <<2); //Nutzdaten in CAN-Objekt

if(CAN_ubRequestMsgObj(0)) { CAN_vLoadData(0,&can_content0);

} //Versende: TXRQ als Main-Switch

CAN_vTransmit(0); }

Zum Vergleich der gleichwertige eigenhändige erstellte Code

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

unsigned char can_content0=0x00; static unsigned char zaehler=0x00; TL0 = 0xA0; TH0 =0x15;

zaehler++; if(zaehler==2) //10 ms Raster {

zaehler=0; // Einlesen der Tasterstellungen

can_content0|=(unsigned char)TASTER_1 + ((unsigned char)TASTER_2<<1) + ((unsigned char)TASTER_3 <<2); CAN_ADLH=CAN_MODATAL0; CAN_DATA0=can_content0; CAN_ADCON=0x11; while(CAN_ADCON&0x02){;}

CAN_ADLH=CAN_MOCTR0; CAN_DATA3=0x01; //Versende: TXRQ als Main-Switch CAN_ADCON=0x81; while(CAN_ADCON&0x02){;}

}

Die CAN-Nachricht wird auf CAN-Knoten 1 und Nachrichtenobjekt 1 empfangen. Fügen

Sie folgenden Quellcode am Ende der Datei MAN.C hinzu:

DAvE Code

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

void isr_can(void) interrupt 10 {

SFR_PAGE(_su3, SST0); // switch to page 3 IRCON3 &= ~(ubyte)0x02; // clear CANSRC4 SFR_PAGE(_su3, RST0); // restore the old SCU page unsigned long can_receive=0; do {

//Clear NEWDAT-Bit

CAN_vWriteCANAddress(CAN_MOCTR1); // Addressing CAN_MOCTR1

CAN_DATA0=0x08; CAN_vWriteEN(D0_VALID); //Lese Nutzdaten

CAN_vWriteCANAddress(CAN_MODATAL1); // Addressing CAN_MODATAL1 can_receive=CAN_ulGetCANData(); CAN_vWriteCANAddress(CAN_MOCTR1); // Addressing r-Reg.CAN_MOSTAT1 (same address as w-Reg. MOCTR1) CAN_vReadEN();

} while((CAN_DATA0&0x0C)); //Check RXUPD und NEWDAT if(can_receive&0x04)// P2.2 abfragen

{ P3_DATA=0x00;

} else {

2.5 Funktionsfähiges Beispielprogramm

32

28

29

30

31

32

33

34

35

if(can_receive&0x01) {

P3_DATA|=0xAA; } if(can_receive&0x02) {

P3_DATA|=0x55; }

} }

Zum Vergleich der gleichwertige eigenhändige erstellte Code

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

void isr_can(void) interrupt 10 {

unsigned char can_receive=0; IRCON3 &= ~(ubyte)0x02; // clear CANSRC4 do {

//Clear NEWDAT-Bit

CAN_ADLH=CAN_MOCTR1; CAN_DATA0=0x08; CAN_ADCON=0x11; while(CAN_ADCON&0x02){;} // Lese Nutzdaten

CAN_ADLH=CAN_MODATAL1; CAN_ADCON=0x00; while(CAN_ADCON&0x02){;} can_receive=CAN_DATA0;

CAN_ADLH=CAN_MOCTR1; CAN_ADCON=0x00; while(CAN_ADCON&0x02){;}

}while((CAN_DATA0&0x0C)); // check RXUPD und NEWDAT if(can_receive&0x04)// P2.2 abfragen {

P3_DATA=0x00; } else {

if(can_receive&0x01)

{ P3_DATA|=0xAA;

} if(can_receive&0x02) {

P3_DATA|=0x55; }

} }

In der Datei main.h müssen noch folgende Aliasnamen hinzugefügt werden, damit die

drei Taster an den Portpins P2.0 bis P2.2 zugewiesen sind:

1

2

3

4

/**** SFR-Definition ****/ sbit TASTER_1=0xA0; sbit TASTER_2=0xA1; sbit TASTER_3=0xA2;

Zum Schluss muss noch Port 3 als Ausgang und Port 2 als Eingang definiert werden.

Diese Einstellungen finden am Anfang der Funktion main_vinit() in der Datei main.c

statt.

1 // ***** Konfiguration der Ports ******

2.5 Funktionsfähiges Beispielprogramm

33

2

3

4

5

6

7

8

9

10

SFR_PAGE(_pp1, noSST); // switch to page 1 P3_PUDEN =0; SFR_PAGE(_pp0, noSST); // switch to page 0 P3_DIR=0xFF; // Taster T1, T2, T3 auf P2.0, P2.1, P2.2

SFR_PAGE(_pp1, noSST); // switch to page 1 P2_PUDEN=0; SFR_PAGE(_pp0, noSST); // switch to page 0 P2_DIR=0x00;

Die Einstellungen sind jetzt abgeschlossen.

2.5.4 Testen des Beispielprogramms auf realer Hardware

Verbinden Sie jetzt das Evaluierungsboard mit dem Rechner und laden Sie das

Beispielprogramm auf den Microcontroller. Die CAN-Knoten 0 und 1 können mit Hilfe

der 6-poligen Stiftleiste miteinander verbunden werden. Dabei werden die CAN-Low-

Stifte bzw. CAN-High-Stifte verbunden (siehe Abbildung 15) oder aber alternativ für

CAN-Knoten 1 die Pins 2 (CAN-Low) und 7 (CAN-High) der Sub-D-Buchse verwendet.

Abbildung 15: CAN-Knoten verbinden

2.5.5 Testen des Beispielprogramms auf im Simulationsmodus

Leider ist im Simulationsmodus der Loop-Back-Modus in der Form fehlerhaft, dass

Nachrichten nicht von CAN-Knoten 0 auf CAN-Knoten 1 geroutet werden. Deshalb muss

das Beispielprogramm für den Simulationsmodus in der Art verändert werden, dass

sowohl Message Object 0 als auch Message Object 1 auf CAN-Knoten 0 gelegt werden.

CANL1

CANH1

2.5 Funktionsfähiges Beispielprogramm

34

Die entsprechende Anpassung wird in DAVE in der verketteten Liste vorgenommen

werden, siehe Abbildung 16: Platzierung beider Message Objects auf Knoten 0. Weitere

Änderungen sind nicht vorzunehmen.

Abbildung 16: Platzierung beider Message Objects auf Knoten 0

3.1 A1 - Vorbereitung

35

3 Laborversuche

3.1 A1 - Vorbereitung

Erstellen Sie das Beispielprogramm aus Kapitel 2 mit Hilfe von DAvE13. Validieren Sie

das Programm im Simulationsbetrieb. Achten Sie darauf, dass Sie im Simulationsbetrieb

die Einstellungen aus Abschnitt 2.5.5 übernehmen.

3.2 A2 – Lauflicht und Siebensegmentanzeige

Es soll ein Programm erstellt werden mit folgender Funktionsweise:

1. Die Datenrate beträgt 500 kbit/s und die Menge der Nutzdaten ist 1 Byte.

2. Über den Timer 0 wird im Sekundentakt ein Lauflicht (siehe Abbildung 17) über

Nachrichtenobjekt 0 und CAN-Knoten 0 auf den CAN-Bus gelegt. Das Lauflicht wird

aber nur bei gedrücktem Taster T2 verschickt. Der Zustand des Tasters T2 wird an

den Portpin P2.0 eingelesen. Der Identifier ist mit 0x0A festgelegt. Der Empfang

erfolgt auf CAN-Knoten 1 und Nachrichtenobjekt 1 (MO1). MO1 ist mit der Interrupt-

Quelle CANSCR2 verknüpft, die beim Empfang einer Nachricht ausgelöst wird. Die

ausgelesenen Nutzdaten aus MO1 sollen auf Port P3 ausgegeben werden, so dass der

Inhalt des Signals auf der LED-Leiste sichtbar wird.

Abbildung 17: Lauflicht

13 Zur Installation von DAvE laden Sie die Datei dave.zip von \\ads\DFS\MMT\public\Mitarbeiter\Kriesten\60_Microcomputertechnik\DAvE herunter und folgen Sie die Anleitung in der Datei Hinweis.txt.

0x1h

0x2h

0x4h

0x8h

0x10h

0x20h

0x40h

0x80h

0x40h

0x20h

3.3 A3 – Kombiinstrument

36

3. Ein Zähler soll an der Siebensegmentanzeige realisiert werden: Beim Drücken des

Tasters T1, dessen Zustand am Portpin P2.1 eingelesen wird, wird eine Variable um

eins inkrementiert. Beim Erreichen des Wertes 100, wird die Variable auf den Wert 0

zurückgestellt. Der Wert dieser Variable wird zyklisch alle 50 ms über

Nachrichtenobjekt 3 und Knoten 1 übertragen. Der Identifier ist mit 0x14 festgelegt.

Der Empfang erfolgt auf Knoten 0 und Nachrichtenobjekt 4. MO4 ist mit der

Interrupt-Quelle CANSCR6 verknüpft, die beim Empfang einer Nachricht ausgelöst

wird. Die ausgelesenen Nutzdaten aus MO4 werden auf der Siebensegmentanzeige

angezeigt.

3.3 A3 – Kombiinstrument

In diesem Versuch werden Sie vorgegebene Dateien verwenden und ergänzen. Diese

Dateien werden mit Hilfe von DAvE erzeugt. Erstellen Sie ein neues Keil-Projekt und

importieren sie folgende Dateien:

MAIN.C und MAIN.H

CAN.C und CAN.H

Timer0.C und Timer0.H

ADC.C und ADC.H

Diese Dateien beinhalten die Initialisierungen der einzelnen Controller-Komponenten,

sowie fertige Teile des Programmcodes.

Aufgabe A3.1: Warnblinker

Ziel dieser Teilaufgabe ist das Ein- bzw. Ausschalten des Warnblinkers des Mercedes

Benz Kombiinstruments mittels Tastendruck. Erweitern Sie zunächst den Quellcode

durch die Beantwortung der folgenden Fragestellungen:

1. Welche Vorladewerte für den Timer 0 (TL0, TLH) sind notwendig, um einen

Timerinterrupt mit einer Frequenz von 200Hz zu realisieren? Tragen Sie die

ermittelten Werte an den entsprechenden Stellen im Programmcode ein.

Innerhalb des Timer0-ISR sind über Kommentare 3 Codestellen gegeben. An diesen

Stellen wird im Folgenden ein Programmcode von Ihnen erzeugt, welcher im

entsprechenden Raster aufgerufen wird.

2. Erstellen Sie innerhalb des Timers 0‐ISR ein Schleifenkonstrukt, so dass der

Programmcode in der jeweils vorgegebenen Rasterung aufgerufen wird. Verwenden

Sie die bereits vorgegebenen Countervariablen in der Datei Timer0.C

3.3 A3 – Kombiinstrument

37

3. Weiterhin soll in dieser Teilaufgabe der Botschaftsversand von Botschaft 1 und

Botschaft 2 (Details siehe unten) innerhalb der 100ms und 660ms Task angestoßen

werden (der Inhalt der 10ms‐Task erfolgt erst in der Aufgabe 2.2).

4. Erweitern Sie das Programm um die Funktion einer Tasterauswertung. Bei

gedrücktem Taster wird die Botschaft 2 mit der angegeben Zykluszeit versendet.

Verwenden Sie hierfür einen beliebigen Pin des Port 3.

Hinweis:

Botschaft 1 ist in Message Object MO0 gespeichert, Botschaft 2 in Message Object MO2.

Beide Message Objects sind hierbei bereits vorkonfiguriert.

Versorgen Sie für den Programmtest das Kombiinstrument mit den notwendigen

Klemmenspannungen (KL. 30, KL.15) aus dem Tischnetzteil sowie mit dem D‐Sub

Verbinder Ihrer Controllerkarte.

Botschaft1:

Klemmenstatus

Identifier: 0x1h

Byteanzahl: 8

Zyklus: 100ms

Byte 0: 0x4h

Die Botschaft kann über folgenden Funktionsaufruf versendet werden:

CAN_Transmit(0x0). Mit dieser Botschaft wird dem Kombiinstrument die aktuelle

Stellung des Zündschlüssels übermittelt. Der Wert 0x4h signalisiert den Systemen

„Zündung EIN“.

Botschaft2:

Warnblinker

Identifier: 0x29h

Byteanzahl: 3

Zyklus: 660ms

Byte 0: 0xE0h

Byte 1: 0x22h

Die Botschaft kann über folgenden Funktionsaufruf versendet werden:

CAN_Transmit(0x2). Mit dieser Botschaft wird dem Kombiinstrument die Information

über den Status des Warnblinkers übermittelt. Um die typische Blinkfrequenz zu

erzielen, muss die Botschaft mit einer Zykluszeit von 660ms versendet werden.

3.3 A3 – Kombiinstrument

38

Aufgabe A3.2: Fahrzeuggeschwindigkeit

Neben dem Warnblinker soll zusätzlich der Fahrgeschwindigkeitsanzeiger in Betrieb

genommen werden. Dieser benötigt zur Berechnung der aktuellen

Fahrzeuggeschwindigkeit mindestens zwei von vier Raddrehzahlsignalen. Diese Signale

werden in der folgenden Botschaft dem Kombiinstrument übermittelt:

Raddrehzahlimpulse

Identifier: 0x203h

Byteanzahl: 8

Zyklus: 10ms

Impulsgeber VL:

Byte 0: Bit 0-5

Byte 1: Bit 0-8

Impulsgeber VR:

Byte 2: Bit 0-5

Byte 3: Bit 0-8

Der Botschaftsversand erfolgt über Message Object MO1. Die simulierten

Raddrehzahlimpulse werden automatisch über den Analog‐Digital‐Umsetzer am Port

P2.7 eingelesen und in den Variablen rpm_l und rpm_h gespeichert.

5. Speichern Sie die linken Raddrehzahlimpulse in den CAN_DATA Registern

CAN_DATA0 (rpm_h) und CAN_DATA1 (rpm_l) und die rechten Raddrehzahlimpulse

in den Registern CAN_DATA2 (rpm_h) und CAN_DATA3 (rpm_l) ab. Sowohl für den

linken als auch für den rechten Sensor soll also der gegebene AD‐Wert verwendet

werden. Versenden Sie die Botschaft im 10ms Raster und testen Sie Ihr Programm

auf Funktionsfähigkeit.

Hinweis:

Über den AD‐Wandler wird ein 8‐Bit großer Wert eingelesen, auf dem CAN‐Bus sind

aber 14‐Bit Genauigkeit für den AD‐Wert verlangt sowie eine „andere Darstellung“. Das

Mapping des 8‐Bit Wertes des AD‐Wandlers auf die 14‐Bit auf dem CAN‐Bus erfolgt über

die beiden bereits (von uns in den) Code integrierten Anweisungen (dieses Mapping ist

so gestaltet, dass die Drehung am AD‐Wandler ein Geschwindigkeitsintervall abdeckt,

das vom Kombi vollständig angezeigt werden kann).

1

2

rpm_h = ADC_RESR0H>>4; rpm_l = ADC_RESR0H<<4;

3.3 A3 – Kombiinstrument

39

4 Abbildungsverzeichnis

Abbildung 1: CAN-Transceiver 2

Abbildung 2: Schematischer Aufbau der Multi-CAN-Einheit [ddd] 2

Abbildung 3: Startup-Dialog 6

Abbildung 4: Fenster „New Project“ 7

Abbildung 5: Projekt Settings 7

Abbildung 6: Hauptfenster 8

Abbildung 7: Multi-CAN-Modul 12

Abbildung 8: Pin-Festlegungen für Knoten 0 12

Abbildung 9: Initialisierungseinstellungen für Knoten 0 13

Abbildung 10: Listenkonfiguration 19

Abbildung 11: Nachrichtenobjekte 24

Abbildung 12: Message Objekt 0 konfigurieren 25

Abbildung 13: Message Objekt 1 konfigurieren 25

Abbildung 14: Timer 0 30

Abbildung 15: CAN-Knoten verbinden 33

Abbildung 16: Platzierung beider Message Objects auf Knoten 0 34

Abbildung 17: Lauflicht 35

Abbildung 18: Umwandlung des AD-Registers auf die CAN-Datenregister (gegeben) 41

Abbildung 19: Signalbelegung auf dem CAN-Bus 41

Abbildung 20: Funktionsweise des AD-Wandlers 42

3.3 A3 – Kombiinstrument

40

5 Literaturverzeichnis

[ETS08] Etschberger Konrad: Controller-Area-Network, Grundlagen, Protokolle, Bausteine, Anwendungen, 4.Auflage, Hanser-Verlag, München, 2008.

[INF10] Infineon: XC886/888CLM, XC886/888LM User´s Manual, 8-Bit Single Chip Microcontroller, XC88xCLM_um_v1_3.pdf, URL: http://www.infineon.com/dgdl/XC88xCLM_um_v1_3.pdf?folderId=db3a304412b407950112b408e8c90004&fileId=db3a304412b407950112b40c53da0b0b, 2013.

[INF11e] Infineon: DAVE – Digital Application Virtual Engineer, URL: http://www.infineon.com/dave, 2013.

[KRI12] Kriesten Reiner: Embedded Programming, Basiswissen und Anwendungsbeispiele der Infineon XC800-Familie, 1.Auflage, Oldenbourg-Verlag, München, 2012.

[LAW11] Lawrenz Wolfhard, Obermöller Nils: CAN: Controller Area Network: Grundlagen, Design, Anwendungen, Testtechnik, VDE-Verlag, Berlin, 2011.

[VEC11] Vector-Informatik: Einführung in CAN, E-Learning Portal Vector-Informatik, https://www.vector.com/vl_einfuehrungcan_portal_de.html, 2011.

6.1 Anhang A – AD-Wandlung

41

6 Anhang

6.1 Anhang A – AD-Wandlung

Das genaue Mapping ist in den folgenden Abbildungen illustriert:

Abbildung 18: Umwandlung des AD-Registers auf die CAN-Datenregister (gegeben)

Abbildung 19: Signalbelegung auf dem CAN-Bus

6.1 Anhang A – AD-Wandlung

42

Ein AD-Wandler liest eine Spannung – hier im Bereich [0V, 5V] – ein und wandelt diese

Spannung linear in einen 12-Bit Wert um, also einen Wert im Bereich {0,1,28=255}.

Abbildung 20: Funktionsweise des AD-Wandlers