Upload
others
View
7
Download
0
Embed Size (px)
Citation preview
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.
08. Januar 2015
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 Erstellen von Sende- und Empfangsfunktionen ...........................................30
2.5.4 Programmlogik hinzufügen ...................................................................................32
2.5.5 Testen des Beispielprogramms auf realer Hardware ...............................34
2.5.6 Testen des Beispielprogramms im Simulationsmodus ............................35
3 Laborversuche ................................................................................................................... 36
3.1 Vorbereitung ..................................................................................................................................36
3.2 Lauflicht und Siebensegmentanzeige ................................................................................36
3.3 A3 – Kombiinstrument ..............................................................................................................37
4 Abbildungsverzeichnis ................................................................................................... 40
5 Literaturverzeichnis........................................................................................................ 42
6 Anhang ................................................................................................................................. 43
6.1 Anhang A – AD-Wandlung .......................................................................................................43
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):
a. CAN-Controller - genannt “CAN-Node 0” und “CAN-Node 1”.
▪ Schnittstelle zu den Transceivern und mit Intelligenz ausgestattet.
b. 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).
c. 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
d. 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)
e. Clock-Control –Einheit
▪ Gibt den Takt des CAN-Kernels vor
f. 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:
a. Wenn das untenstehende Startup-Fenster erscheint
- > Mouse-Click auf „Create a new project“
Abbildung 3: Startup-Dialog
b. Navigationsleiste „File“ -> New
c. Ü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“ wird ein Häkchen gesetzt bei “Initalize the CAN Node 0” (siehe
Abbildung 9). Das Häkchen bei “Enable the Loop-Back Mode” wird für dieses
Beispielprogramm nicht gesetzt. Ebenso 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 Erstellen von Sende- und Empfangsfunktionen
Nach der Konfiguration der CAN-Peripherie sind während des eigentlichen Ablaufs der
Programmlogik – also nach der „Initialisierungs-Phase“ – lediglich noch folgende
Aktionen in direkter Kooperation mit der CAN-Peripherie-Einheit zu erledigen (die
restlichen Anweisungen des Programmes werden über den Core und mit Hilfe der
anderen Peripherie-Einheiten abgewickelt):
Senden von Daten auf den CAN-Bus,
Empfang von Daten über den CAN-Bus.
2.5 Funktionsfähiges Beispielprogramm
31
Unter Verwendung der Hilfsfunktionen aus 2.5.2 können diese Aufgaben in individuelle
Funktionen zum Senden und Empfangen von CAN-Nachrichten gekapselt werden. Die
Erklärung der Funktionen findet sich in den Kommentaren zu Beginn der Funktions-
definition wieder. Wichtig für die weitere Übung ist hierbei ist weniger das genaue
Verständnis, welche Register innerhalb der dargestellten Sende- und Empfangsfunktion
gesetzt werden und wie dies genau erfolgt. Vielmehr geht es darum, diese Funktionen im
Rahmen des eigenen Codes sinnvoll einzusetzen, also aufzurufen, und so den
Gesamtablauf der Übung zu garantieren zu können.
//**************************************************************************** // @Function void CAN_SendUserData_HSKA(ulong * ul_data, unsigned char mo_number) // //---------------------------------------------------------------------------- // @Description This is a HS Karlsruhe Function which writes 8 bytes of user data // to a message object and transmits this message object to the CAN bus // Note: not necessarily all of the 8 user bytes are transmitted // depending on the configured message length of the message object //---------------------------------------------------------------------------- // @Returnvalue void // //---------------------------------------------------------------------------- // @Parameters - ulong * ul_data // Pointer to an array storing the 8-Byte value which is going to be // transmitted. // Example input array: ulong data[2]; // total array length of 8 Byte // - unsigned char mo_number // number of the message object (only number, not address), range: 0..31 // //---------------------------------------------------------------------------- // @Date 18.12.2014 // //**************************************************************************** void CAN_SendUserData_HSKA(ulong * ul_data, unsigned char mo_number) { if(CAN_ubRequestMsgObj(mo_number)) { CAN_vLoadData(mo_number, ul_data); } CAN_vTransmit(mo_number); }
//**************************************************************************** // @Function void CAN_ReceiveUserData_HSKA(ulong * ret_variable, unsigned char mo_number) // //---------------------------------------------------------------------------- // @Description This is a HS Karlsruhe Function which reads the 8 Byte of // CAN user data out of a message object. Thus for the pointer // ret_variable a dedicated array must be provided by the calling function //---------------------------------------------------------------------------- // @Returnvalue void // //---------------------------------------------------------------------------- // @Parameters // - unsigned char mo_number: INPUT parameter // number of the message object (only number, not address), range: 0..31 // - ulong * ul_data: OUTPUT PARAMETER // Pointer to the programm memory which has to be provided by the calling function //---------------------------------------------------------------------------- // @Usage Exmple // ** CALLING FUNCTION // ulong get_can_value[2]={0x00000000,0x00000000}; // CAN_ReceiveUserData_HSKA(get_can_value, 10); // receive from MO10 //---------------------------------------------------------------------------- // @Date 08.01.2015 // //****************************************************************************
2.5 Funktionsfähiges Beispielprogramm
32
void CAN_ReceiveUserData_HSKA(ulong * ret_variable, unsigned char mo_number) { unsigned char i; ulong mo_data_adresse; ulong mo_ctrl_adresse; // ermittle Adresse der unteren 4 Byte des MO_DATA Registers, ableitbar aus CAN.H mo_data_adresse= 0x0404 + 8*mo_number; // ermittle Adresse des zugehörigen MO_CRTL Registers, ableitbar aus CAN.H mo_ctrl_adresse=0x407+8*mo_number; for (i=0; i<=1; i++,mo_data_adresse++) // loop due to code-size limit KEIL version { // Read lower 4 Bytes of MO user data according to user-manual page 15-28 do{ // Clear Newdat-Bit CAN_vWriteCANAddress(mo_ctrl_adresse); CAN_DATA0=0x08; CAN_vWriteEN(D0_VALID+D1_VALID+D2_VALID+D3_VALID); // Lese Nutzerdaten CAN_vWriteCANAddress(mo_data_adresse); ret_variable[i]=CAN_ulGetCANData(); // Addressing r-Reg.CAN_MOSTAT1 (same address as w-Reg. MOCTR1): CAN_vWriteCANAddress(mo_ctrl_adresse); CAN_vReadEN(); }while(CAN_DATA0&0x08); // check NEWDAT // Remark: RXUPD not checked as bit sometimes "buggy" in Keil-simulation mode } }
2.5.4 Programmlogik hinzufügen
Als letzter Schritt werden die generierten Dateien mit benutzerdefiniertem Quellcode
ergänzt.12 Damit alle 10 ms eine CAN-Nachricht übertragen wird, fügen Sie folgenden
Quellcode innerhalb der Funktion T01_viTmr0() hinzu:
void T01_viTmr0(void) interrupt T0INT { // USER CODE BEGIN (T01_IsrTmr0,2) ulong can_content[2]={0x00000000, 0x38394041}; // Dummy-Wert für obere 4 Bytes // ulong can_content0=0x00; static ubyte zaehler=0x00; T01_vLoadTmr(0, 0x15A0); // Reload-Wert zaehler++; if(zaehler>=2) { zaehler=0; // Einlesen der Tasterstellungen can_content[0]|=(((ubyte)TASTER_1)+((ubyte)TASTER_2<<1)+((ubyte)TASTER_3<<2)); // CAN-Nachrichtenübermittlung anstoßen CAN_SendUserData_HSKA(can_content, 0); // Sende Benutzerdaten } // USER CODE END } // End of function T01_viTmr0
}
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
33
Die CAN-Nachricht wird auf CAN-Knoten 1 und Nachrichtenobjekt 1 empfangen. Fügen
Sie folgenden Quellcode des CAN-Interrupts am Ende der Datei CAN.C hinzu:
DAvE Code
/*** Interrupt-Funktion CAN ***/ void isr_can(void) interrupt 10 { unsigned long can_receive[2]={0x00000000, 0x00000000}; EA=0; // disble Interrupt SCU_PAGE=3;// switch to page 3 IRCON3 &= ~(ubyte)0x02; // lösche Bit CANSRC4 SCU_PAGE=0; // restore the old SCU page EA=1; // restore Interrupt CAN_ReceiveUserData_HSKA(can_receive, 1); // can_receive = CAN_GetUserData_HSKA(0,1); // Lese CAN-Frame 1, untere 4 Byte // Evaluation of received data if(can_receive[0] & 0x04) //P2.2 abfragen { P3_DATA =0x00; } else { if(can_receive[0] & 0x01) { P3_DATA |=0xAA; } if(can_receive[0] & 0x02) { P3_DATA=0x55; } } }
Beachten Sie weiter, dass die Funktionen CAN_ReceiveUserData_HSKA() sowie
CAN_SendUserData_HSKA() noch geeignet in das Programm eingebunden werden
müssen. Diese Funktionen finden sich in der Datei CAN_AccessSendReceiveFunctions_-
HSKA.c, so dass sowohl diese als auch die zugehörige Header-Datei in das Projekt zu
integrieren ist: Project-Explorer Add existing files to Group… Bitte legen Sie diese
Dateien in denselben Ordner wie die anderen C-Sourcen, eine Inkludierung der Header-
Dateien erfolgt über den Befehl #include "CAN_AccessSendReceiveFunctions_HSKA.h". Dies
ist zu Beginn der Dateien T01.C sowie CAN.C vorzunehmen.
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;
Port 3 muss 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
2
3
4
// ***** Konfiguration der Ports ******
SFR_PAGE(_pp1, noSST); // switch to page 1 P3_PUDEN =0; SFR_PAGE(_pp0, noSST); // switch to page 0
2.5 Funktionsfähiges Beispielprogramm
34
5
6
7
8
9
10
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;
Zum Schluss muss noch der Interrupt-Knoten 10 aktiviert werden. Am Ende der
Funktion main_vinit() in der Datei main.c muss folgendes hinzugefügt werden.
1
2
3
4
// Enable MultiCAN Node 4 Interrupt IEN1 |= 0x10; // load interrupt enable register 1 //oder Alternativ // ECCIP0 =1;
Die Einstellungen sind jetzt abgeschlossen.
2.5.5 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
CANL1
CANH1
2.5 Funktionsfähiges Beispielprogramm
35
2.5.6 Testen des Beispielprogramms 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.
Die entsprechende Anpassung wird in DAVE in der verketteten Liste vorgenommen
werden, siehe Abbildung 16. Zusätzlich muss das Häkchen bei “Enable the Loop-Back
Mode” für beide CAN-Knoten gesetzt werden (siehe Abbildung 9). Weitere Änderungen
sind nicht vorzunehmen.
Abbildung 16: Platzierung beider Message Objects auf Knoten 0
3.1 Vorbereitung
36
3 Laborversuche
3.1 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.6 übernehmen.
3.2 Lauflicht und Siebensegmentanzeige
Es soll ein Programm erstellt werden mit folgender Funktionsweise: Die Datenrate
beträgt 500 kbit/s und die Menge der Nutzdaten ist 1 Byte.
a) Über den Timer 0 wird im Sekundentakt ein Lauflicht (siehe Abbildung 18) über
Nachrichtenobjekt 0 und CAN-Knoten 0 auf den CAN-Bus gelegt. Das Lauflicht wird
aber nur bei gedrücktem Taster T0 verschickt. Der Zustand des Tasters T0 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 (Interrupt-Knoten 6) 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.
Achten Sie darauf, dass die Interrupt-Routine des Timers so klein wie möglich
gehalten wird, indem Sie mit Hilfe eines „Flags“ (binärwertige Variable) namens
task_1000 das für die Aufgabe notwendige Programmkonstrukt jede Sekunde
innerhalb der main-Routine ausführen:
Abbildung 17: Implementierung des T0-Interrupts.
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.
3.3 A3 – Kombiinstrument
37
Abbildung 18: Lauflicht
b) Stellen Sie sicher, dass Ihr Programm aus Teilaufgabe a. lauffähig ist. Danach soll
dieses Programm in folgender Art und Weise modifiziert und erweitert werden: das
Lauflicht soll nur noch zwischen den Ports 3.0 bis 3.6 laufen (unten den weiter
geltenden Voraussetzungen von Teilaufgabe a.). Zusätzlich soll beim Drücken des
Tasters T1 dessen Zustand an dem Portpin P2.1 eingelesen werden. Nach jedem
neuen Tasterdruck soll Portpin 3.7 getoggelt werden. Somit ist Portpin 3.7 unabhän-
gig von den Portpins 3.0 bis 3.6 betrieben.
Hinweise:
Achten Sie darauf, dass das Leuchtlicht unabhängig vom Toggeln des Ports 3.7
läuft, d.h. eventuelle Wartezeiten beim Auswerten des Tasterdrucks dürfen
das Leuchtlicht „nicht stilllegen“.
Achten Sie darauf, dass Sie im Simulationsbetrieb die Einstellungen aus
Abschnitt 2.5.6 übernehmen.
3.3 A3 – Kombiinstrument
In diesem Versuch werden Sie vorgegebene Dateien verwenden und ergänzen. Diese
Dateien wurden 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.
0x1h
0x2h
0x4h
0x8h
0x10h
0x20h
0x40h
0x80h
0x40h
0x20h
3.3 A3 – Kombiinstrument
38
In den folgenden Teilen werden Sie eigenen Programmcode hinzufügen. Hierzu sollen
Sie die Versendung von Nachrichten wie folgt vornehmen:
Die Versendung der Nachricht erfolgt mit der vorgefertigten Funktion
CAN_Transmit(), das Laden von Daten in ein Message Objekt nehmen sie manuell
mit Hilfe des Access Mediator vor.
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:
a. Welche Vorladewerte für den Timer 0 (TL0, TLH) sind notwendig, um einen Timer-
Interrupt 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.
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
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).
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.
Das Anstoßen des Botschaftsversands kann alternativ zu der „erlernten Methode“ nach
dem folgenden Schemata erfolgen. Dieses führt dieselben Aktionen auf den Registern
aus wie die konventionelle Methode, allerdings sind diese Aktionen in Funktionen
„verpackt“. Die verwendeten Funktionen sind natürlich in dem generierten Code
wiederzufinden:
1
2
3
// Lade Adresse von niederwertigen Datenbytes des MO0 in CAN_ADLH
CAN_vWriteCANAddress(CAN_MODATAL0); // Beschreibe CAN_DATA0, CAN_DATA1, CAN_DATA3 mit Werten
3.3 A3 – Kombiinstrument
39
4
5
6
7
8
9
10
// in diesem Beispiel bleibt CAN_DATA2 unverändert
CAN_DATA0 =0x55; CAN_DATA1= 0xAA; CAN_DATA3=0x01; CAN_vWriteEN(D0_VALID+D1_VALID+D3_VALID); // Übertrage die Datenwerte an CAN_MODATAL0 CAN_Transmit(0x0); // Sende Inhalt von MO0 auf den Bus // (Parameter: Message-Object Number)
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.
Aufgabe A3.2: Fahrzeuggeschwindigkeit
Neben dem Warnblinker soll zusätzlich der Fahrgeschwindigkeitsanzeiger in Betrieb
genommen werden. Dieser benötigt zur Berechnung der aktuellen
3.3 A3 – Kombiinstrument
40
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.
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;
4 Abbildungsverzeichnis
Abbildung 1: CAN-Transceiver 2
3.3 A3 – Kombiinstrument
41
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 34
Abbildung 16: Platzierung beider Message Objects auf Knoten 0 35
Abbildung 17: Implementierung des T0-Interrupts. 36
Abbildung 18: Lauflicht 37
Abbildung 19: Umwandlung des AD-Registers auf die CAN-Datenregister (gegeben) 43
Abbildung 20: Signalbelegung auf dem CAN-Bus 43
Abbildung 21: Funktionsweise des AD-Wandlers 44
3.3 A3 – Kombiinstrument
42
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
43
6 Anhang
6.1 Anhang A – AD-Wandlung
Das genaue Mapping ist in den folgenden Abbildungen illustriert:
Abbildung 19: Umwandlung des AD-Registers auf die CAN-Datenregister (gegeben)
Abbildung 20: Signalbelegung auf dem CAN-Bus
6.1 Anhang A – AD-Wandlung
44
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 21: Funktionsweise des AD-Wandlers