Praktikumsanleitung CAN Projektpraktikum

Werbung
CAN Projektpraktikum
Praktikumsanleitung
Studiengang FZT
Technische Universität Ilmenau - Fachgebiet Rechnerarchitektur
Stand: 14. Mai 2012
Dr.-Ing. Alexander Fleischer
[email protected]
Inhaltsverzeichnis
1 Über diese Anleitung
2
2 Hardware des Praktikumssystems und Funktionen zur Ansteuerung
2.1 Übersicht . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.2 Adreßraum Ein- und Ausgabeeinheiten . . . . . . . . . . . . . . .
2.3 Ausgabeeinheiten . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.4 Eingabeeinheiten . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.5 CAN-Controller . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
3
3
3
4
5
5
3 Beschreibung der Software
3.1 PC Software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2 Entwicklungsumgebung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3 Programmierung des Praktikumssystems . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6
6
7
8
4 Aufgabenstellung
4.1 Vorbreitung . . . . . . . . . . . . .
4.2 Aufgabe 1 – CAN-Empfang . . . .
4.3 Aufgabe 2 – CAN-Kommunikation
4.4 Belegung der Schalter und Tasten .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
8
8
9
9
10
5 Vorgehen bei Problemen
10
6 Anhang: Übersicht der vordefinierten Funktionen
11
7 Anhang: Prgrammiersprache C
7.1 Programmieren in C – Verweis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.2 Beispielcode mit Erläuterungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
12
12
12
8 Vorbereitung zum Praktikum
14
1 Über diese Anleitung
Diese Anleitung beinhaltet die allgemeine Beschreibung der Praktikumshardware, Praktikumssoftware
und die Aufgabenstellungen für das CAN Projektpraktikum. Zusätzlich zu dieser Anleitung benötigen
Sie die Dokumentation des CAN-Controllers, welches in der Datei “Beschreibung des CAN - Interfaces
des C164” enthalten ist.
Eine ausführlichere Beschreibung der Hardware des Praktikumssystems finden Sie in der Datei “Hardwarebeschreibung”, die für das Praktikum wichtigen Teile sind auch in dieser Anleitung enthalten.
Diese Dateien erhalten Sie im entsprechenden Bereich im E-Learning System des Fachgebietes Rechnerarchitektur, welches über die Fachgebietsseite http://www.tu-ilmenau.de/ra erreichbar ist.
Dort finden Sie auch noch weitere Dateien, beispielsweise die komplette Beschreibung des verwendeten
C164, welche optionale Zusatzinformationen enthalten, aber für das Praktikum nicht benötigt werden.
Die Beispiele sowie die kursiv gesetzten Erläuterungen zu den Aufgaben beziehen sich auf die Vorgabedateien. Dieser vorgegebene Rahmen dient der Strukturierung und Vereinfachung der einzelnen Aufgaben.
Eigene Lösungen, unabhängig von diesen Vorlagen, sind selbstverständlich auch möglich.
2
2 Hardware des Praktikumssystems und Funktionen zur Ansteuerung
Die ausführliche Dokumentation zur Hardware des Praktikumssystems finden Sie im Dokument “Hardwarebeschreibung“. In den folgenden Abschnitten finden Sie eine Zusammenfassung der für das Praktikum
relevanten Funktionen.
2.1 Übersicht
Das Praktikumssystem besteht aus folgenden Komponenten:
• Prozessormodul nanoModul-164
– Prozessor Infineon C164CI
∗ 16bit CPU
∗ Full CAN 2.0B Controller
∗ 6 parallele I/O-Ports verschiedener Breite
∗ General Purpose Timer, Watchdog, Real Time Clock, A/D-Wandler
∗ asynchrone und synchrone serielle Schnittstelle
– 256 kB SRAM
– 256 kB Flash
• Adressdekoder 74HC154 (am Port P1H )
• Eingabeeinheiten mit Bustreiber 74HCT573, Ausgänge der Bustreiber am Datenbus (Port P1L)
• Ausgabeeinheiten mit Bustreiber (74HCT563, mit D-Latch), Eingänge der Bustreiber am Datenbus
(Port P1L)
Es ist über eine serielle Schnittstelle mit einem PC verbunden, auf welchem die Entwicklungsumgebung läuft. Alle Praktikumssysteme sind untereinander über den CAN-Bus verbunden. Zusätzlich ist am
CAN-Bus noch ein Busmonitor angeschlossen, welcher es erlaubt, die Übertragungen auf dem Bus zu
beobachten.
2.2 Adreßraum Ein- und Ausgabeeinheiten
Zur Adressierung der Ein- und Ausgabeeinheiten werden folgende Adressen verwendet:
3
symb. Name
SEG2
SEG1
SEG4
SEG3
SEG6
SEG5
SEG8
SEG7
DIL1
DIL2
DIL3
DIL4
TASTER
SCHALTER1
SCHALTER2
Adresse
10H
20H
30H
40H
50H
60H
70H
80H
90H
A0H
B0H
C0H
D0H
E0H
F0H
Peripheriebauelement
A1/1
A1/2
A2/1
A2/2
A3/1
A3/2
A4/1
A4/2
DIL1
DIL2
DIL3
DIL4
Taster
SW1
SW2
Erläuterung
2. Stelle von links
1. Stelle von links
4. Stelle von links
3. Stelle von links
6. Stelle von links
5. Stelle von links
8. Stelle von links
7. Stelle von links
1. DIL-Schalterblock
2. DIL-Schalterblock
3. DIL-Schalterblock
4. DIL-Schalterblock
von
von
von
von
links
links
links
links
oberer Schalterblock
unterer Schalterblock
Die symbolischen Namen werden in dem Rahmenprogramm definiert und können statt der Adressen
verwendet werden.
Mit Ausgabe der jeweiligen Adresse auf dem Adressbus wird die entsprechende Baugruppe aktiviert und
nimmt Daten vom Datenbus entgegen und gibt diese aus bzw. legt den Eingabewert auf den Datenbus.
2.3 Ausgabeeinheiten
Jedem der Segmente der 7-Segment-Anzeige ist ein Bit in dem auszugebenden Byte zugeordnet. Durch
das Ausgeben einer “1” an der jeweiligen Bitposition leuchtet das dieser Bitposition zugeordnete Segment,
bei Ausgabe einer “0” bleibt es dunkel. Den Bits sind folgende Segmente zugeordnet:
Bitposition
0
1
2
3
4
5
6
7
Hexadezimal
01H
02H
04H
08H
10H
20H
40H
80H
Segment
A
B
C
D
E
F
G
H
Für die Ansteuerung der Ausgabe sind im Rahmenprogramm folgende Funktionen vordefiniert, welche
Sie direkt verwenden können:
• void led ausgabe(unsigned char stelle, unsigned char ziffer)
Gibt an der angegebenen Displaystelle die übergebene Ziffer aus. Der Wert für “stelle” muss zwischen 0 und 7 liegen, der Wert für “ziffer” zwischen 0 und 17. Dabei haben die Werte folgende
Bedeutung:
Wert
0 .. 9
10 .. 15
16
17
Bedeutung
Ziffern 0 - 9
Hexadezimalziffern “A”...“F”
“-”
Stelle löschen
Beispiel: led ausgabe(1,4)
• void led hex(unsigned char stelle,unsigned char zahl)
4
Gibt die angegebene Zahl (Bereich 0 .. 255) auf der angegebenen und der folgenden Stelle hexadezimal aus. Stelle muss im Bereich von 0 .. 6 sein.
2.4 Eingabeeinheiten
Bei allen Schalterblöcken ist das niederwertigste Bit (Bit 0) jeweils der Schalter ganz links, das höchstwertige Bit (Bit 7) ganz rechts.
Der linke obere Taster ist Bit 0 (niederwertigstes Bit), der rechts daneben liegende Bit 1. Der linke untere
Taster ist Bit 4, der rechte untere Taster Bit 7. Damit ergeben sich entsprechend der Anordnung auf der
Platine folgende Werte für die einzelnen Taster:
obere Reihe
untere Reihe
01H
10H
02H
20H
04H
40H
08H
80H
Für die Ansteuerung der Eingabe sind im Rahmenprogramm folgende Funktionen vordefiniert, welche
Sie direkt verwenden können:
• unsigned char schalter eingabe(unsigned char adresse)
Gibt die aktuelle Belegung eines Schalterblocks zurück. Als Adresse ist der symb. Name oder die
Adresse aus der Tabelle “Adressraum” anzugeben. Die zurückgegebene Belegung entspricht der
binären Codierung, jedes “1” - Bit im zurückgegebenen Wert entspricht einem eingeschalteten
Schalter, das niederwertigste Bit entspricht dem jeweils linken Schalter. Beispielsweise wird bei
der Schalterstellung (v.l.n.r) AUS-AUS-EIN-AUS-AUS-AUS-EIN-EIN der Wert C4h (196 dezimal,
11000100 binär) zurückgegeben. Es ist auch möglich, mit dieser Funktion den aktuellen Zustand
der Tasten abzufragen, dabei wird jedoch nicht auf einen Tastendruck gewartet.
Beispiel: unsigned char wert = schalter eingabe(SCHALTER1);
• unsigned char warte taste()
Die Funktion wartet, wenn eine Taste gedrückt ist, auf das Loslassen der Taste und gibt die Belegung
der Tasten als Byte (analog zu den Schaltern) oder 0, wenn keine Taste gedrückt wurde, zurück.
• unsigned char bit test(unsigned int wert, unsigned char bitposition)
Gibt zurück, ob das entsprechende Bit (0..7) im angegebenen Wert gesetzt ist.
Beispiel: if (bit test(wert, 0)) { ...
2.5 CAN-Controller
Die komplette Beschreibung des CAN-Controllers (Originaldokumentation) finden Sie im Dokument
“Beschreibung des CAN - Interfaces des C164“.
Der CAN-Controller ist ein “Full CAN 2.0B” Controller, d.h. er kann mehrere Nachrichtenobjekte mit
unterschiedlichen Identifiern gleichzeitig verwalten. Zur Steuerung des CAN-Controllers werden verschiedene Register verwendet. Einerseits gibt es globale Register, welche sich auf alle Nachrichtenobjekte
beziehen (Beispielsweise die Baudrate und die Acceptance Mask), andererseits gibt es Register, welche
jeweils für ein Nachrichtenobjekt verwendet werden (z.B. Identifier, Modusregister, Datenlänge, Daten).
Folgende Funktionen sind zum Umgang mit dem CAN-Controller vordefiniert:
• void can init(unsigned int baudrate, unsigned int mask)
Initialisiert den Controller und stellt die Baudrate und Maske auf die angegebenen Werte ein.
Alle Nachrichtenobjekte werden initialisert, alle Bits im Message Control Register werden aud “0”
gesetzt.
• void can set mcr(unsigned char objekt, unsigned int wert)
5
Setzt oder löscht einzelne Bits im Message Control Register eines Nachrichtenobjektes. Die “objekt”
ist die Nummer des zu ändernden Nachrichtenobjektes (0 .. 14). Die zu setzenden / löschenden Bits
werden über folgende Konstanten festgelegt:
Bit
Message valid
setzen
SET MSGVAL
löschen
RES MSGVAL
New Data
SET NEWDAT
RES NEWDAT
CPU Update
SET CPUUPD
RES CPUUPD
SET TXRQ
RES TXRQ
Transmit Request
Beschreibung
Das aktuelle Nachrichtenobjekt ist gültig und
wird vom CAN-Controller verwendet
Neue Daten wurden in dieses Nachrichtenobejekt geschrieben
Neue Daten werden durch die CPU in dieses
Objekt geschrieben (stoppt die Übertragung
von Objekten, die gerade aktualisiert werden)
Das Nachrichtenobjekt soll gesendet werden.
Kann durch die CPU oder einen Remote Frame gesetzt werden.
Sollen mehrere Bits auf einmal gesetzt werden, so müssen die Konstanten bei Übergabe an die
Funktion mit bitweisem UND ( & ) verknüpft werden. Andere als die angegebenen Bits bleiben
unverändert.
Beispiel: can set mcr(0, SET MSGVAL & SET CPUUPD);
• unsigned int can test mcr(unsigned char objekt, unsigned int wert)
Prüft, ob das angegebene Bit im Message Control Register. Als “wert” muss eine der folgenden Konstanten verwendet werden: TEST MSGVAL, TEST NEWDAT, TEST CPUUPD, TEST TXRQ.
Beispiel: if (can test mcr(0, TEST NEWDAT)) { ...
• void can set identifier(unsigned char objekt, unsigned int identifier)
Setzt den Identifier für das angegebene Nachrichtenobjekt. Es werden nur 11 bit Identifier unterstützt.
• void can set mcfg(unsigned char objekt, unsigned char dlc, unsigned char direction)
Setzt die Datenlänge (in Bytes, 0...8) und die Übertragungsrichtung (0: Empfang; 1:Senden) für ein
Nachrichtenobjekt.
• void can set data(unsigned char objekt, unsigned char b0, unsigned char b1, unsigned char b2, unsigned char b3, unsigned char b4, unsigned char b5, unsigned char b6, unsigned char b7)
Setzt die zu übertragenden Daten für ein Nachrichtenobejkt. Sollten weniger als 8 Byte übertragen
werden, sind die anderen Bytes auf “0” zu setzen.
Beispiel: can set data(0, 123, 0,0,0,0,0,0,0);
• unsigned char can get data(unsigned char objekt, unsigned char bytenum)
Liefert das angegebene Byte der Daten des angegebenen Nachrichten-Objektes. “bytenum” kann
ein Wert zwischen 0 und 7 sein.
3 Beschreibung der Software
3.1 PC Software
Die PC Software für das Praktikum wird in einer virtuellen Maschine ausgeführt. Nach dem Login wird
ein Windows 98 gestartet, welches alle zum Praktikum benötigten Programme enthält. Innerhalb dieses
Windows 98 sind 2 Laufwerke definiert:
Laufwerk C: enthält das Windows, die Software und die erstellten Programme. Beim Abmelden / Absturz des Windows-Systems werden alle Daten auf diesem Laufwerk wieder in Ihren Ursprungszustand
6
zurückgesetzt.
Laufwerk D: bietet Ihnen die Möglichkeit, Ihre Daten und Programme zu sichern. Dazu befindet sich
bereits eine Verknüpfung zu einer Batch-Datei auf dem Desktop. Die Daten auf Laufwerk D: bleiben
auch bei einem Neustart des Windows erhalten, werden aber jeweils über Nacht gelöscht.
3.2 Entwicklungsumgebung
Im Praktikum wird eine Demoversion der TASKING Entwicklungsumgebung EDE verwendet. Diese
Demoversion hat u.A. folgende Einschränkungen:
• In der Workbench können maximal 5 Dateien gleichzeitig geöffnet sein
• Die Anzahl der Anweisungen pro Datei ist begrenzt (Fehlermeldung “Demo Limits exceeded“).
3.2.1 EDE Workbench
In diesem Programm geben Sie den Programmcode ein und starten die Übersetzung. Im linken Bereich
finden Sie eine Übersicht der im Projekt vorhandenen Dateien, welche Sie mit einem Doppelklick auf
den Dateinamen öffnen können. Eine neue Datei legen Sie an, indem sie mit der rechten Maustaste auf
die Bezeichnung des Projektes (“CAN“) klicken und im erscheinenden Kontextmenü “add new File...“
wählen.
Nach der Eingabe des Programmcodes müssen Sie das Programm übersetzen. Benutzen Sie dazu die
Schaltfläche “Make“. Beobachten Sie die Statusmeldungen im unteren Fenster (“Build“). Es können
sowohl Warnungen als auch Fehler auftreten. Warnungen geben Ihnen Hinweise auf eventuell falsche
Parameter, nicht verwendete Variablen, etc., führen aber nicht zum Abbruch der Übersetzung. Beim
Auftreten eines Fehlers wird die weitere Übersetzung abgebrochen und keine Ausgabedatei erstellt. Sind
Fehler aufgetreten, so können Sie mit einem Doppelklick auf die Fehlermeldung direkt zu der Stelle im
Quelltext springen, welche den Fehler verursacht hat und diesen berichtigen.
Bei fehlerfreier Beendigung des Übersetzungsvorganges wird eine Ausgabedatei “can.abs“ erstellt, welche
Sie dann mit Hilfe des Debuggers auf das Zielsystem laden und dort ausführen können. Den Debugger
starten Sie mit dem Lupensymbol in der Symbolleiste.
3.2.2 CrossView Pro Debugger
Nach dem erstmaligen Start des Debuggers baut dieser eine Verbindung zum Zielsystem auf. Damit
dies möglich ist, muß sich der Zielrechner im Bootloader-Modus befinden. Drücken Sie daher, sobald
das “Connecting“-Fenster erscheint, gleichzeitig die Tasten “Reset“ (Rot) und “Boot“ (Schwarz) am
Zielsystem, lassen Sie zuerst die “Reset“-Taste los, danach die “Boot“-Taste.
Es wird dann ein Monitorprogramm geladen, welches im Weiteren die Kommunikation zwischen Debugger
und Zielsystem ermöglicht.
Im Anschluß daran wird Ihr erstelltes Programm auf das Zielsystem geladen. Beim Start des Debuggers
geschieht dies automatisch. Sollten Sie den Debugger nicht beendet haben und möchten Ihr (verändertes)
Programm auf das Zielsystem laden, können Sie dies auch über die “LOAD“-Schaltfläche des Debuggers
tun.
Über die Schaltfläche “SRC“ des Debuggers können Sie jetzt Ihren Quelltext öffnen. Vor jeder Zeile, für
welche Code erzeugt wurde, wird eine Schaltfläche mit einem blauen Punkt angezeigt. Wenn Sie diese
Schaltfläche anklicken (roter Punkt) wird Ihr Programm bei der Abarbeitung vor Ausführung dieser Zeile
angehalten.
7
Ihr Programm können Sie mit Hilfe der folgenden Schaltflächen starten:
• “START“ - Ausführen des Programms von Anfang an, auch wenn bereits ein Teil abgearbeitet
wurde
• “GO“ - Fortsetzung der Ausführung des Programms an der aktuellen Stelle
• “STEP OVER“ - Ausführung einer Programmzeile, dabei werden evtl. vorkommende Funktionsaufrufe komplett ausgeführt
• “STEP INTO“ - Ausführung einer Programmzeile, wird eine Funktion aufgerufen, wird die Abarbeitung in der ersten Programmzeile der Funktion angehalten
Mit Hilfe der Schaltfläche “HALT“ können Sie Ihr Programm jederzeit anhalten.
Ist Ihr Programm angehalten, können Sie sich die Werte von Variablen anzeigen lassen. Am einfachsten
funktioniert dies, indem sie im Quelltext mit der Maus auf eine Variable zeigen. Es erscheint dann ein
Tooltip-Fenster, in welchem der aktuelle Wert angezeigt wird.
Über “Data“→“Evaluate Expression...“ (oder die “EXPR“-Schaltfläche) können Sie sich auch die Werte
von Variablen in einem extra Fenster anzeigen lassen (“Add Watch“) oder diese direkt ändern. Dort
können Sie auch das Anzeigeformat einstellen.
“Spezielle“ Variablen, wie beispielsweise die Register des CAN-Controllers, lassen sich nicht auf diese
Art und Weise anzeigen. Sollten Sie diese benötigen, können Sie sich mit “Debug“→“Memory Window
Setup...“ den Speicherbereich ab der Adresse 0xEF00h anzeigen lassen.
3.3 Programmierung des Praktikumssystems
Im vorgegebenen Programmrahmen sind bereits die Funktionen für den Zugriff auf die Hardware (siehe
Abschnitt 2) definiert. Durch die Benutzung dieser Funktionen ist es nicht mehr nötig, direkt über die
Ein- und Ausgabeports diese zu programmieren, dies wird bereits innerhalb der Funktionen realisiert.
Sie müssen im Praktikum ausschließlich die Funktion main() in der Datei main.c ergänzen. Die Ergänzung
eigener Funktionen ist möglich, aber nicht unbedingt erforderlich. Ergänzen Sie am Anfang der MainFunktion alles, was nur einmalig zur Initialisierung durchgeführt werden muss (vor dem while(1)). Innerhalb der Endlosschleife (while(1) { ... }) ergänzen Sie bitte die Funktionen, die zyklisch immer wieder
ausgeführt werden sollen.
4 Aufgabenstellung
4.1 Vorbreitung
• Lesen Sie die Dokumentation zum Experimentalsystem, insbesondere die Abschnitte zur Ansteuerung der Ein- und Ausgabeeinheiten.
• Machen Sie sich mit der Dokumentation des CAN-Controllers vertraut. Hier sind vor allem die
Abläufe zum Senden und Empfangen von Nachrichten und Remote - Frames zu beachten (Diagramme / Ablaufpläne in der Dokumentation).
• Drucken Sie das Blatt “Vorbereitung zum Praktikum” (letzte Seite) aus und beantworten Sie die
dort gestellten Fragen.
Am Ende dieser Anleitung finden Sie ein Arbeitsblatt mit einigen Fragen, welches Sie zur Vorbereitung
nutzen können.
8
4.2 Aufgabe 1 – CAN-Empfang
Initialisieren Sie den CAN-Controller mit der Baudrate 100 kBaud (entspricht dem Wert 0x34C9 für das
Baudratenregister). Setzen Sie die globale Maske so, das alle Bits des Identifiers verglichen werden.
Konfigurieren Sie ein Nachrichtenobject zum Empfang der Uhrzeit vom autonomen Experimentalsystem.
Den CAN - Identifier des autonomen Systems erhalten Sie zu Beginn des Praktikums. Solange der linke
Schiebeschalter der unteren Reihe eingeschaltet ist, soll beim Empfang einer Uhrzeit diese auf den LED
Anzeigen dargestellt werden. Die Uhrzeit wird mit 6 Datenbytes gesendet, jede Stelle der Zeit einzeln.
Beispielsweise würden um 15:27:05 Uhr folgende 6 Bytes gesendet werden: 01 05 02 07 00 05.
Der grundsätzliche Ablauf für das Initialisieren eines Empfangsobjektes und der Empfangsvorgang sind
im CAN-Manual im Diagramm “CPU Handling of Receive Objects” beschrieben. Die Initialisierung des
Message-Objektes sollte einmalig am Anfang des Programmes erfolgen, die Abfrage der empfangenen
Uhrzeit dagegen in regelmäßigen Abständen.
4.3 Aufgabe 2 – CAN-Kommunikation
4.3.1 Aufgabe 2.1 – eigenen Wert speichern und ändern
Definieren Sie in Ihrem Programm eine Variable zum Speichern einen eigenen Wertes. Erweitern Sie ihr
Hauptprogramm so, das, wenn der linke Schiebeschalter der unteren Reihe ausgeschaltet ist, dieser Wert
auf den ersten 2 Displaystellen angezeigt wird. Fragen Sie jetzt die Tasten ab, so das der Wert mit den
4 linken Tasten verändert werden kann (obere Reihe: +10H, +1, untere Reihe: -10H, -1).
Der grundsätzliche Ablauf für das Initialisieren eines Sendeobjektes und der Sendevorgang sind im CANManual im Diagramm “CPU Handling of Receive Objects” beschrieben.
4.3.2 Aufgabe 2.2 – Senden des eigenen Wertes auf Anforderung
Ermitteln Sie Ihre eigene Knotennummer (4 Bit) durch Auslesen des linken Blocks der DIL-Schalter
(DIL1). Ändern Sie die Einstellung dieser Schalter nicht ! Bilden Sie Ihren CAN-Identifier nach
folgendem Schema:
Bit
Wert
10
1
9
0
8
1
7
0
6
0
5
0
4
0
3 2 1
0
Knotennummer
Konfigurieren Sie ein weiteres Nachrichtenobjekt zum Senden des eigenen Wertes auf Anforderung
durch einen anderen Knoten (Remote Frame).
Es soll auf Anforderung ein Datenbyte gesendet werden, welches als Datenwert den in Aufgabe 2.1
definierten eigenen Wert enthält. Dieses soll bei einer Änderung des eigenen Wertes mit Hilfe der Tasten
auch aktualisiert werden.
Der grundsätzliche Ablauf für das Initialisieren eines Sendeobjektes und der Sendevorgang sind im CANManual im Diagramm “CPU Handling of Transmit Objects” beschrieben.
4.3.3 Aufgabe 2.3 – Senden des eigenen Wertes
Ergänzen Sie den Programmteil aus 2.2 um die Möglichkeit, den eigenen Wert durch einen Tastendruck
auf den rechten oberen Taster auch ohne Anforderung senden zu können.
9
4.3.4 Aufgabe 2.4 – Anfordern des Wertes eines anderen Knotens
Definieren Sie ein weiteres Nachrichtenobjekt zum Anfordern eines Wertes eines anderen Knoten. Der
Identifier des anderen Knotens soll dabei mit den linken 4 Schiebeschaltern der oberen Reihe einstellbar
sein (Bildung des Identifier wie be Aufgabe 3.2). Mit der Taste unten rechts soll das Senden des Remote
Frames ausgelöst werden. Stellen Sie die Antwort auf diesen Frame auf den letzten beiden Stellen des
LED dar.
4.3.5 Aufgabe 2.5 – Zykliches Anfordern des Wertes eines anderen Knotens (optional)
Falls der 2. Schiebeschalter von Links des unteren Blocks eingeschaltet ist, fragen Sie den Wert des
anderen Knoten zyklisch ab. Senden Sie dabei aber nicht mehr als 10 Anforderungen pro Sekunde.
4.4 Belegung der Schalter und Tasten
Im folgenden sind die Belegungen aller Schalter und Tasten entsprechend der Anordnung auf dem Board
nach Abschluss aller Aufgaben dargestellt.
Schalter:
1. Reihe:
0
2. Reihe:
0
Uhr/Wert
1
2
3
Identifier fremdes System
1
Zyklisch
2
3
4
5
6
7
4
5
6
7
Tasten (Entsprechend der Anordnung auf dem Board):
+10H
+1
Senden
-10H
-1
Anfordern
5 Vorgehen bei Problemen
1. Der Debugger reagiert nicht
• Wahrscheinlich wird gerade Ihr Programm ausgeführt. Während der Ausführung des Programms sind keine weiteren Befehle im Debugger möglich. Klicken Sie auf “HALT“, um die
Ausführung Ihres Programms zu unterbrechen.
2. Nach einer Änderung des Programmes wird weiterhin das “alte“ Programm ausgeführt
• Schauen Sie im Statusfenster der Workbench, ob ein Fehler bei der Übersetzung auftrat. Tritt
ein Fehler auf, wird die Ausgabedatei nicht erzeugt, die “alte“ allerdings auch nicht gelöscht.
Berichtigen Sie ggfs. angezeigte Fehler.
• Laden Sie das Programm erneut auf das Zielsystem.
• Beenden Sie den Debugger. Drücken Sie “Reset“ am Zielsystem. Starten Sie den Debugger
erneut.
3. Die Anzeige im Debugger bei schrittweiser Abarbeitung stimmt nicht mit den Ausgaben auf dem
Zielsystem überein
• siehe Punkt 2
10
6 Anhang: Übersicht der vordefinierten Funktionen
• void led ausgabe(unit8 stelle, unsigned char ziffer)
Gibt an der angegebenen Displaystelle die übergebene Ziffer aus.
stelle: 0..7, ziffer: 0..17 (0..9, A..F, ’-’, Leer)
• void led hex(unsigned char stelle,unsigned char zahl)
Gibt die angegebene Zahl auf der angegebenen und der folgenden Stelle hexadezimal aus.
stelle: 0..6, zahl: 0..255
• unsigned char schalter eingabe(unsigned char adresse)
Gibt die aktuelle Belegung eines Schalterblocks zurück.
adresse: DILx, SCHALTERx, TASTER
• unsigned char warte taste()
Die Funktion wartet, wenn eine Taste gedrückt ist, auf das Loslassen der Taste und gibt die Belegung
der Tasten als Byte (analog zu den Schaltern) oder 0, wenn keine Taste gedrückt wurde, zurück.
• unsigned char bit test(unsigned int wert, unsigned char bitposition)
Gibt zurück, ob das entsprechende Bit im angegebenen Wert gesetzt ist.
wert: 0..0xFFFF, bitposition: 0..15
• void sleep(unsigned int zeit)
Wartet die angegebene Zeitspanne.
zeit: 330 entspricht ca. 1s
• void can init(unsigned int baudrate, unsigned int mask)
Initialisiert den Controller und stellt die Baudrate und Maske auf die angegebenen Werte ein.
Alle Nachrichtenobjekte werden initialisert, alle Bits im Message Control Register werden aud “0”
gesetzt.
baudrate: 0..0xFFFF, zu setzender Wert für BTR
mask: 0..0x7FF, Bitmaske für den Vergleich des CAN-Identifiers
• void can set mcr(unsigned char objekt, unsigned int wert)
Setzt oder löscht einzelne Bits im Message Control Register eines Nachrichtenobjektes.
objekt: 0..14, wert: in MCR zu schreibender Wert, folgende Konstanten sind möglich: SET MSGVAL,
RES MSGVAL, SET NEWDAT, RES NEWDAT, SET CPUUPD, RES CPUUPD, SET TXRQ,
RES TXRQ
Sollen mehrere Bits auf einmal gesetzt werden, so müssen die Konstanten bei Übergabe an die
Funktion mit bitweisem UND ( & ) verknüpft werden.
• unsigned int can test mcr(unsigned char objekt, unsigned int wert)
Prüft, ob das angegebene Bit im Message Control Register.
objekt: 0..14, wert: 0..0xFFFF (TEST MSGVAL, TEST NEWDAT, TEST CPUUPD, TEST TXRQ)
• void can set identifier(unsigned char objekt, unsigned int identifier)
Setzt den Identifier für das angegebene Nachrichtenobjekt. Es werden nur 11 bit Identifier unterstützt.
objekt: 0..14, identifier: 0..0x7FF
• void can set mcfg(unsigned char objekt, unsigned char dlc, unsigned char direction)
Setzt die Datenlänge (in Bytes) und die Übertragungsrichtung (0: Empfang; 1:Senden) für ein
Nachrichtenobjekt.
objekt: 0..14, dlc: 0..8, direction: 0..1
• void can set data(unsigned char objekt, unsigned char b0, unsigned char b1, unsigned char b2, unsigned char b3, unsigned char b4, unsigned char b5, unsigned char b6, unsigned char b7)
Setzt die zu übertragenden Daten für ein Nachrichtenobejkt.
objekt: 0..14, b0..b7: 0..255
• unsigned char can get data(unsigned char objekt, unsigned char bytenum)
Liefert das angegebene Byte der Daten des angegebenen Nachrichten-Objektes.
objekt: 0..14, bytenum: 0..7
11
7 Anhang: Prgrammiersprache C
7.1 Programmieren in C – Verweis
Eine allgemeine Einführung in die Programmiersprache C findet man beispielsweise unter
http://de.wikibooks.org/wiki/C-Programmierung.
7.2 Beispielcode mit Erläuterungen
Der folgende Beispielcode dient nur zur Erläuterung der C Syntax und hat nicht direkt etwas mit den
Praktikumsaufgaben zu tun.
// Das i s t e i n Kommentar , w e l c h e r b e i // s t a r t e t und b i s zum Z e i l e n e n d e g e h t
/∗ s t a r t e t e i n e n m e h r z e i l i g e n Kommentar
w e l c h e r wie f o l g t b e e n d e t wird : ∗/
// D e f i n i t i o n
unsigned char
/∗ −−−−−−−−−−
Rückgabe−
typ
∗/
e i n e r Funktion
s w i n ( unsigned char
−−−−− −−−−−−−−−−−−−
Name Parameter−
typ
addr )
−−−−
Parameter−
name
// { b e g i n n t e i n e n Anweisungsblock , } b e e n d e t d i e s e n
{
// V a r i a b l e n d e k l a r a t i o n , muss d i r e k t nach { s t e h e n
unsigned char
wert
= 0;
// −−− Typ −− −− Name −− −− I n i t i a l i s i e r u n g , kann w e g g e l a s s e n werden
// Zuweisung e i n e s Wertes
P1H = addr ;
wert = P1L ;
// R ückgabewert d e r Funktion
return wert ;
}
void main ( void ) {
// v o i d −> k e i n R ückgabewert , main −> Hauptprogramm
unsigned char x , y ;
// Array−D e f i n i t i o n , d . h . 5 Werte g l e i c h e n Typs werden a n g e l e g t
unsigned char a r r a y [ 5 ] = { 2 , 6 , 9 , 1 , 4 } ;
/∗ −−−−−−−−−− −−−−− − −−−−−−−−−−−−−
Typ
Name |
I n i t i a l i s i e r u n g ( optional )
Anzahl d e r Elemente
∗/
// F u n k t i o n s a u f r u f , 0xE0 wird f ü r den Parameter addr e i n g e s e t z t
// H e x a d e z i m a l z a h l e n werden mit dem P r ä f i x 0x angegeben
x = s w i n ( 0 xE0 ) ;
//
//
//
if
B e d i n g t e Anweisung
z i f f o u t ( 0 , 0 ) wird nur a u s g e f ü h r t , wenn x N u l l i s t
S t a t t == f ü r g l e i c h g e h t auch != ( u n g l e i c h ) , >, <, <=, >=
( x==0) z i f f o u t ( 0 , 0 ) ;
12
// Mehrere Bedingungen
// && −> l o g i s c h e s UND, | | −> l o g i s c h e s ODER, ! l o g i s c h e N e g a ti o n
i f ( ( x==0) && ! ( y==1)) z i f f o u t ( 0 , 0 ) ;
// S t a t t e i n e r Anweisung kann d o r t auch w i e d e r e i n Block s t e h e n
i f ( x==0) {
ziff out (0 ,0);
ziff out (0 ,1);
}
// S c h l e i f e n
// S o l a n g e Bedingung e r f ü l l t
while ( x==0) {
x = s w i n ( 0 xE0 ) ;
}
ist . . .
// Z ä h l s c h l e i f e von 0 b i s 5 , y j e w e i l s um 1 erhöhen ( y++)
f o r ( y =0;y <6;y++) {
z i f f o u t (x , y ) ;
}
// Rechnen
y = ( y + x ) ∗ 2 + y / 4 ; // ”/” −> h i e r : g a n z z a h l i g e D i v i s i o n
y = x % 4 ; // ”%” −> Modulo , Rest b e i D i v i s i o n
// B i t o p e r a t i o n e n
x = 0 x95 ; // b i n ä r 1001 0101
y = x & 0x0F ; // 1001 0101 b i n ä r UND mit v e r k n ü p f t mit 0000 1111 −> 0000 0 1 0 1 , 0 x05
y = x | 0x0F ; // 1001 0101 b i n ä r ODER mit v e r k n ü p f t mit 0000 1111 −> 1001 1 1 1 1 , 0x9F
y = x >> 4 ; // 1001 0101 um 4 S t e l l e n nach r e c h t s g e s c h o b e n −> 0000 1 0 0 1 , 0 x09
y = x << 4 ; // 1001 0101 um 4 S t e l l e n nach l i n k s g e s c h o b e n −> 0101 0 0 0 0 , 0 x50
y = ˆx ; // B i t w e i s e Negation , 0110 1 0 1 0 , 0x6A
// Arrays
// D e f i n i t i o n s i e h e oben , Index b e g i n n t immer b e i 0 und g e h t b i s Anzahl −1
a r r a y [ 2 ] = 1 2 ; // 3 . Element a u f 12 s e t z e n
f o r ( y =0;y <5;y++) { // Elemente i n e i n e r S c h l e i f e ausgeben
z i f f o u t ( array [ y ] , y ) ;
}
} // Ende main ( )
13
8 Vorbereitung zum Praktikum
Name:
Matrikelnummer:
1. Schauen Sie sich folgendes Beispielprogramm an und eränzen Sie hinter jeder Zeile, was diese Anweisung bedeutet.
void main ( void ) {
unsigned char s c h a l t e r ;
unsigned char i ;
f o r ( i =0; i <8; i ++)
led ausgabe ( i , 17);
while ( 1 ) {
s c h a l t e r = s c h a l t e r e i n g a b e (SCHALTER1 ) ;
led hex (0 , schalter ) ;
i f ( b i t t e s t ( schalter , 0)) {
led ausgabe (8 , 8);
} else {
led ausgabe (8 ,17);
}
}
}
2. Wozu dient die globale Maske, und wie ist diese für die Anforderung im Praktikum zu setzen ?
3. Geben Sie die Befehle für die Definition eines Nachrichtenobjektes zum Senden / Empfangen eines
Wertes (1 Datenbyte) an ! Benutzen Sie die Funktionen set mcr und set mcfg.
Senden
Empfangen
4. Geben Sie an, welche Funktionsaufrufe für das Aktualisieren des Wertes in einem Sende-Nachrichtenobjekt
nötig sind !
5. Wie kann man bei einem Empfangs-Nachrichtenobjekt abfragen, ob neue Daten eingetroffen sind ?
Herunterladen