close

Anmelden

Neues Passwort anfordern?

Anmeldung mit OpenID

im WS 2014/15 - TU Ilmenau

EinbettenHerunterladen
Technische Universität Ilmenau
Fakultät für Maschinenbau
Fachgebiet Rechneranwendung im Maschinenbau
Univ.-Prof. Dr.-Ing. habil. M. Weiß
Lehrmaterial zur Lehrveranstaltung "Mikrorechnertechnik"
im WS 2014/15
Zielstellung: Programmieren mit C++
Inhalt
Seite
Microsoft Visual Studio 2012
Hilfestellung und erste praktische Schritte zur
Einarbeitung in das Microsoft Visual Studio 2012.
2
Aufgabe 1:
Datentypen, mathematische
Funktionen
Inhalt des Praktikums ist die Berechnung
mathematischer Formeln. Dabei soll die
Benutzung der C++ Datentypen und der Ein-/ und
Ausgaben über Tastatur und Bildschirm geübt
werden.
5
Aufgabe 2:
Tonerzeugung
In diesem Praktikum sollen
Hardwarekomponenten des PCs, speziell der
Zähler-/Zeitgeberschaltkreis (CTC) angesprochen
werden. Ziel ist die Erzeugung von Tönen über
den PC-Lautsprecher
6
Aufgabe 3:
Peripheriesteuerung mit
einem Sensor-Aktor-Modul
Der Versuch soll die Aspekte der
Hardwareprogrammierung von PeripherieBaugruppen am Beispiel eines Sensor-AktorModuls verdeutlichen.
9
Aufgabe 4:
C-Dateiarbeit
Das Einlesen und Abspeichern von Textdateien
und Binärdateien sind immer wiederkehrende
Aufgaben für Programmierer. In diesem Versuch
sollen die Grundlagen der Dateiarbeit anhand der
Bearbeitung einer beispielhaften Messwertdatei
vermittelt werden.
16
Aufgabe 5:
Klassen in C++ und Nutzung
des .NET-Frameworks
C++ bietet einen objektorientierten
Programmieransatz. Unter Verwendung des
.NET-Frameworks soll dieser Versuch auf die
Verwendung von Klassen und Objekten eingehen.
17
Lehrmaterial
C++ - Demoprogramme und Syntax-Hinweise
21
C++ Programmentwicklung mit Microsoft Visual Studio 2012
Einführung
Start:
Jedes Programm besteht aus mehreren Dateien, die in einem Projekt zusammengefasst
werden.
Mehrere Projekte werden in einer Solution abgespeichert.
Also muss zuerst ein neues Projekt angelegt werden. Die dazu notwendigen Arbeitsschritte
sind:
File  NewProject
Wie abgebildet, ist "Visual C++ - General" und "Empty Project" auszuwählen.
Name: Ein selbst gewählter Projektname, hier z.B. Volumen
Location: Bitte hier unbedingt C:\Kopie eintragen.
Solution name: Visual Studio schlägt hier automatisch den Projektnamen vor. Das lassen wir so.
Weiter: "Ok".
Hinweis zu den entstehenden Verzeichnissen:
Mit dem Anlegen des Projektes wird in C:\Kopie das Verzeichnis Volumen erzeugt. Dieses
Verzeichnis heißt Solutionverzeichnis. Innerhalb des Solutionverzeichnisses liegt ein
Verzeichnis, das ebenfalls den Namen Volumen hat. Dies ist das Projektverzeichnis.
Ein wichtiges Fenster im Visual Studio ist der Solution
Explorer. Im Solution Explorer ist die entstandene Struktur zu
erkennen: Es gibt eine Solution, die ein Projekt enthält. Noch
sind alle Unterordner im Solution Explorer leer (siehe
Abbildung).
2
TU Ilmenau, Fakultät für Maschinenbau
Univ.-Prof. Dr.-Ing. habil. M. Weiß
20.10.2014
Im nächsten Schritt werden die Quellcodedateien (Source Files) zum Projekt hinzugefügt.
Im ersten Beispiel ist das die vorbereitete Beispieldatei VOLUMEN.CPP. Die Datei steht im
Verzeichnis "Aushang\VisualC++". Wir kopieren die Datei in das gerade neu entstandene
Projektverzeichnis "C:\Kopie\Volumen\Volumen" und addieren die Datei VOLUMEN.CPP zu den
Source Files des Projektes (Rechter Mausklick auf Source Files).
Durch Doppelklicken auf die Datei VOLUMEN.CPP im Solution Explorer wird der Editor geöffnet
und die Datei angezeigt.
Dann kann die Datei VOLUMEN.CPP editiert, kompiliert und gebunden werden.
Starten Sie das Programm über Debug  Start Without Debugging (Ctrl+F5) oder
Debug  Start Debugging (F5)!
3
Programmieraufgabe "Rechteck":
1. Ausgabe des Textes "Ich lerne C++" auf dem Bildschirm
2. Erstellen einer Funktion Rechteck(), an die die Seitenlängen als double-Zahlen
übergeben werden und die den Flächeninhalt eines Rechtecks berechnet und zurückgibt
3. Einlesen der Seitenlängen über die Tastatur
4. Aufrufen der Funktion Rechteck() in der Funktion main()
5. Anzeigen des Flächeninhalts auf dem Bildschirm
Im zweiten Beispiel wird ohne Musterdatei gearbeitet. Alles wird neu angelegt. Wir bilden
zunächst ein ganz neues Projekt mit dem Namen "Rechteck". Dazu sind die Schritte zum
Anlegen des Projektes wie im ersten Beispiel zu verwenden.
Neu ist die Eingabe des Quellcodes (des Programms). Ein Programm steht in einer Datei. Also
muss eine neue Datei angelegt werden. Der Dialogaufruf zum Öffnen einer neuen Datei erfolgt
durch Auswahl des Ordners Source Files im Solution Explorer und Wählen von Add New Item im
Kontextmenü (Drücken der rechten Maustaste).
Zu wählen ist als File Typ: C++ File und ein File Name: hier z.B. Rechteck. Die
Dateinamenserweiterung (.cpp) wird automatisch angehängt.
Ist das Programm fertig eingegeben, wird der Menüpunkt "Build" gewählt, und durch Anwahl
des Unterpunktes "Build <Projektname>" das Programm fertig erstellt. Nach einem Compileund Link-Prozess entsteht das Programm - hier Rechteck.exe. Der Projektname ist also auch der
Programmname.
4
TU Ilmenau, Fakultät für Maschinenbau
Univ.-Prof. Dr.-Ing. habil. M. Weiß
20.10.2014
Aufgabe 1
Tastatureingabe, Bildschirmausgabe, Formelberechnung, Datentypen
Kopieren Sie das unter Aushang\VisualC++ bereitgestellte Gerüst A1_Funktionen nach C:\Kopie
und öffnen Sie die Solution.
Programmieren Sie die Lösung folgender Aufgabe:
Für ein Kreissegment mit dem Radius r und dem Winkel α ist der Flächeninhalt A zu berechnen
(siehe Skizze).
Über die Tastatur sollen eingegeben werden:
 Radius des Kreises r in m
 Winkel für Kreissegment α in Grad.
Die Eingabe soll solange wiederholt werden, solange ein Winkel größer als 180° eingegeben wird.
Die Fläche A in m² soll nach folgender Formel (α in rad) berechnet und auf dem Bildschirm
angezeigt werden.
2
 = ∙ ( − sin( α))
2
5
Aufgabe 2: Tonerzeugung
Mit Hilfe des Zeitgeberschaltkreises 8253 und des Lautsprechers des PCs sollen Töne (Hardware
siehe unten) erzeugt werden.
Aufgabe:
Erzeugen Sie eine einfache Melodie (8 -12 Töne), wobei die Notenfrequenzen (Tonhöhe) und die
Notenlängen in Feldern abgespeichert werden sollen (Hinweise zu Feldern siehe Lehrmaterial).
Für die Notendauer ist die Funktion Sleep() zu benutzen  siehe C++-Hilfe.
Hardwarebeschreibung
In jedem PC befindet sich ein CTC-Schaltkreis 8253. CTC heißt Counter-Timer-Circuit also ZählerZeitgeber-Schaltkreis. An den Clock Eingängen dreier, voneinander unabhängiger, Kanäle ist ein
konstantes Rechtecksignal mit der Frequenz f0 angeschlossen. An den Ausgängen OUT kann
eine (kleinere) Frequenz f entnommen werden. Diese ergibt sich aus der Division der
Eingangsfrequenz f0 durch die programmierbare Zeitgeberkonstante n. n ist eine 16-Bit Zahl
vom Datentyp unsigned short int. Für die Tonerzeugung steht der Kanal 2 zur Verfügung.
Controlregister Adresse 0x43
Eingangsfrequenz (Quarz)
f0= 1193180 Hz
Clock0 Gate0
Clock1 Gate1
Kanal0
Kanal1
Adresse 0X40 Adresse 0X41
Clock 2 Gate2
Kanal2
Adresse 0X42
OUT1
(Baustein wird vom Betriebssystem konfiguriert)
PortB:Adresse 0X61
Zeitgeberschaltkreis 8253
OUT2= 1193180 Hz / n
n-Zeitgeberzeitkonstante
OUT0
Paralleler E/A-Baustein
8255
PortB Bit0
PortB Bit1
OUT2
1 heißt Ton freigeschaltet
Ausgangsfrequenz
f= 1193180 Hz /n
zum InterruptController
zum DMAController
AND
Schwingquarzfrequenz
f0 = 1,19318 106 Hz
T0=1/f0
Frequenz f des Ausgangssignals
in Betriebsart 3 bei n=4.
Am Eingang Gate muß
Highpegel anliegen.
6
Tn=1/f
Lautsprecher
TU Ilmenau, Fakultät für Maschinenbau
Univ.-Prof. Dr.-Ing. habil. M. Weiß
20.10.2014
Beispielfrequenzen für ausgewählte Töne
Ton
Frequenz in Hz
c
262
d
294
e
330
f
349
g
392
a
440
h
494
c²
523
Beispiele für Notendauern
Note
Dauer in ms
ganze Note
2560
halbe Note
1280
viertel Note
640
achtel Note
320
sechzehntel Note
160
zweiunddreißigstel Note 80
vierundsechzigstel Note 40
Programmierung des CTC-Schaltkreises 8253
Zur Erzeugung der gewünschten Ausgangsfrequenz f muss der Schaltkreis programmiert werden.
Dies erfolgt durch Ausgabe eines Bytes an das Control-Register des Schaltkreises. Das ControlRegister hat die Adresse 0X43. Die einzelnen Bits dieses Bytes ergeben sich aus folgender Tabelle.
Controlregister ( Portadresse 0X43 )
Bit 7
Bit 6
Bit 5
Bit 4
Bit 3
Bit 2
Bit 1
Bit 0
0 = Binär
1 = BCD
0
0
0
0
1
0
0
1
1
0
0
1
0
1
0
1
=
=
=
=
0
0
1
1
0
0
1
0
1
0
=
=
=
=
=
Betriebsart 0
Betriebsart 1
Betriebsart 2
Betriebsart 3
Betriebsart 4
Inhalt Counterregister -> Latchregister
Nur MSB lesen/schreiben
Nur LSB lesen/schreiben
Erst LSB, dann MSB lesen/schreiben
0 = Kanal 0 programmieren
1 = Kanal 1 programmieren
0 = Kanal 2 programmieren
Zur Erzeugung einer Frequenz f mit dem Tastverhältnis 1:1 wird der Kanal 2 in Betriebsart 3, Binär
betrieben.
Der Teilerfaktor n ist eine 16 Bit-Zahl. Es müssen also zwei 8 Bit-Werte, erst LSB ( least significant
byte ), dann MSB ( most significant byte ) auf die Portadresse 0X42 geschrieben werden.
7
Hardwarezugriff unter Windows 7 64 Bit
Der Zugriff auf Hardwareressourcen ist unter Windows nur über entsprechende Treiber möglich.
Für den Zugriff auf die Ports des Zeitgeberschaltkreises wird für diesen Versuch der Treiber mit
den zugehörigen Bibliotheken WinRing0 benutzt. WinRing0 ermöglicht den Hardwarezugriff unter
Windows mit Hilfe der Funktionen
WriteIoPortByte() und ReadIoPortByte().
Für die Nutzung des Treibers im Rechnerlabor MB (Treiber wurde installiert und automatisch
gestartet.) wird das Projekt A2_Tonerzeugung unter Aushang\VisualC++ bereitgestellt. Kopieren
Sie den Ordner A2_Tonerzeugung nach C:\Kopie und öffnen Sie die Solution.
Beispielcode
#include <stdio.h>
#include <windows.h>
#include "OlsApi.h" // Deklaration der Funktionen
void main(void)
{
InitializeOls();
int retval = 0;
retval = GetDllStatus();
printf("\nRueckgabewert: %d\n",retval); // 0 heißt o.k.
//....
WriteIoPortByte(0x43,0xB6); // Ausgabe des Steuerworts an den Port 43H
unsigned char b = 0;
b = ReadIoPortByte(0x61);// Lesen von Port 61H
//....
DeinitializeOls();
}
8
TU Ilmenau, Fakultät für Maschinenbau
Univ.-Prof. Dr.-Ing. habil. M. Weiß
20.10.2014
Aufgabe 3: Peripheriesteuerung mit einem Sensor-Aktor-Modul
Aufgaben
1. Prüfen Sie, ob die Funktion OpenSam() eine gültige Gerätenummer aus dem Bereich 1…25
liefert. Wenn ja, zeigen Sie diese an, wenn nein, beenden Sie das Programm mit einer
Fehlermeldung.
2. Setzen Sie die Betriebsart "Gleichstrommotor" und warten Sie anschließend, bis die
entsprechenden Bits im Gerätestatus die Betriebsart "Gleichstrommotor" anzeigen.
3. Ermitteln Sie die Betriebsspannung Ub des Sensor-Aktor-Moduls und zeigen Sie diese an.
4. Der Nutzer soll eine Motorspannung in Volt ( Maximalwert ist die Betriebsspannung U b,
Minimalwert ist –Ub ! ) über die Tastatur eingeben. Das Programm soll diesen Wert am
Motor des Sensor-Aktor-Moduls einstellen und die sich ergebende Drehzahl in
Umdrehungen pro Minute unter Nutzung des Zählers der Encoderimpulse ermitteln. Zeigen
Sie die aus den beiden Brückenspannungen berechnete tatsächliche Motorspannung in Volt
und die Motordrehzahl in U/min auf dem Bildschirm an. Dieser Programmteil soll wiederholt
werden, solange der Nutzer einen gültigen Wert für die Motorspannung vorgibt.
9
Hardwarebeschreibung
Übersicht
Der Versuch 3 benutzt ein Sensor-Aktor-Modul (SAM), welches eine Vielzahl von Baugruppen
enthält. Davon sind im folgenden Bild 1 nur die für die obige Aufgabenstellung relevanten
Baugruppen dargestellt.
8 LEDs
8 Schalter
Mikrocontroller XE167
Infineon
DIO (Ports)
LED
Peripheriekomponenten
SWITCH
M
.
.
MotorEndstufe
Gleichstrommotor
Soll-
DCM_VOLTAGEA
DCM_VOLTAGEB
MODE
STATUS
UB
DCM_SETVALUE
spannung
Encoderimpulse
LC-Display
2 x 20
Zeichen
USB
DCM_COUNTER
DCM_CLEAR
MES_POTI
ADC
ADC – Analog/Digital Converter
USIC – Universal Serial Interface Channel
DIO – Digital Input/Output
PWM – Pulse Width Modulation
WriteText()
USIC
Encoder
PWM
Brückenspannung B
Counter
…
ADC
Brückenspannung A
OpenSAM()
CloseSAM()
WriteValue()
ReadValue()
ReadData()
WriteData()
Potentiometer
Bild 1: Programmiermodell des Sensor-Aktor-Moduls
Das Sensor-Aktor-Modul arbeitet wahlweise in einer von vier Betriebsarten (siehe Tab. 1). Nach
dem Einschalten ist die Betriebsart 0 (Analog) voreingestellt. Zur Nutzung des Gleichstrommotors muss auf die Betriebsart 3 umgeschaltet werden.
Hinweis: Die Umschaltung dauert ca. 1s, d.h. ihr Programm kann erst fortgesetzt werden, wenn
der eingelesene Status (siehe Tab. 1) auch die Betriebsart 3 zurückliefert.
Schalter, LEDs und das Potentiometer können unabhängig von der Betriebsart benutzt werden.
Display des Sensor-Aktor-Moduls
Hinweis: Beachten Sie nach dem Einschalten bitte die Anzeige auf dem Display, drehen Sie,
wenn nötig, am Potentiometer zum Verlassen des Diagnosemodus.
Zur Textausgabe steht ein 40 Zeichen (2 Zeilen zu je 20 Zeichen) LC-Display zur Verfügung. Der
Nutzer kann mit der Funktion WriteText() eigene Texte ausgeben oder die automatische
Zustandsanzeige nutzen.
10
TU Ilmenau, Fakultät für Maschinenbau
Univ.-Prof. Dr.-Ing. habil. M. Weiß
20.10.2014
Stromversorgung
Die Stromversorgung des Sensor-Aktor-Moduls erfolgt über die USB-Schnittstelle. Die
Betriebsspannung Ub ist nicht konstant und hängt vom USB-Anschluß und von der konkreten
Belastung durch die Hardware ab. Die aktuelle Betriebsspannung Ub wird auf dem SensorAktor-Modul mit Hilfe einer bekannten Referenzspannung bestimmt und kann abgefragt
werden.
Gleichstrommotorsteuerung und Encodernutzung
Die Baugruppe Gleichstrommotorsteuerung soll im Folgenden näher erläutert werden.
Motorspannung
A/D-Wandler
PWM-Signal
µC
Motorendstufe
PWM-Einheit
A.
B
Gleichstrom-
. motor mit
integriertem
Encoder
Counter
2 um 90⁰ phasenverschobene Impulsfolgen
Bild 2: Prinzip der Gleichstrommotorsteuerung
Der Mikrocontroller erzeugt mit Hilfe einer Capture-Compare-Einheit ein pulsweitenmoduliertes Signal (PWM) für die Motorendstufe (siehe Bild 2). Die Hardware wurde so
konfiguriert, dass die Pulsweite PW in 4096 Stufen eingestellt werden kann, bei Pulsweite
PW = 0 liegt die negative Betriebsspannung –Ub am Motor an und bei Pulsweite PW= 4095 liegt
die positive Betriebsspannung +Ub am Motor an (siehe Bild 3).
Die Periodendauer T beträgt 4095 Zeiteinheiten = ca. 50µs, so dass sich auf Grund der
Motorinduktivität ein Stromverlauf im Motor entsprechend der roten Linie im Bild 3 einstellt.
i,u
Ub
i,u
Ub
PW
T
T
PW
-Ub
t
t
-Ub
Bild 3: Klemmenspannung und Stromverlauf am Motor bei Ansteuerung mit zwei
verschiedenen PWM-Signalen, T=4095 Zeiteinheiten
Fall a: PW>2048 (>50% von T), Motor dreht sich vorwärts;
Fall b: PW<2048 (<50% von T), Motor dreht sich rückwärts
Die Daten zum Setzen der Motorstellgröße über das Kommando DCM_SETVALUE können nach
folgendem Diagramm ermittelt werden. Aus der Motorstellgröße berechnet der
Mikrocontroller durch Addition von 2048 (Motor steht bei PW=2048) die Pulsweite PW.
11
UM
Ub
0
-2047
2047
Stellgröße
-Ub
Bild 4: Motorspannung UM in Abhängigkeit von der Stellgröße für das Kommando DCM_SETVALUE
An der Welle des Gleichstrommotors ist ein inkrementaler Impulsgeber - kurz: Encoder befestigt. Dieser Encoder liefert zwei phasenverschobene Rechteckspannungsfolgen - die
Encoderimpulse. Pro Umdrehung enthält jede Rechteckspannungsfolge 16 Rechteckperioden.
Die Zähleinheit - der Counter - für die Encoderimpulse realisiert eine Drehrichtungserkennung
und eine Vierfachauswertung (Zählen aller Rechteckflanken). Damit werden pro Umdrehung 64
Inkremente richtungsabhängig gezählt und im Counter gespeichert.
A/D – Wandlung
Analoge Spannungen werden zur Verarbeitung im Rechner mit Hilfe eines A/D-Wandlers in
digitale Größen umgewandelt. Die analogen Spannungen werden in Abhängigkeit von der
Bitbreite des Wandlers auf einen bestimmten Wertebereich abgebildet. Im Sensor-Aktor-Modul
wird ein 10Bit A/D-Wandler verwendet. Damit beträgt der Wertebereich 0…1023. Der Wert
1023 entspricht der Betriebsspannung am Sensor-Aktor-Modul.
Digitaler A/D-Wert AD
1023
ADx
0
Ux
Analoge Spannung U
Ub
Bild 5: Wertebereich für die 10Bit A/D-Wandlung
Kommunikation zwischen dem PC und dem Mikrocontroller auf dem Sensor-Aktor-Modul
PC
USB
USB to
Serial
µC
Bild 6: Datenfluss für das Beispiel der LED-Steuerung
12
LED
TU Ilmenau, Fakultät für Maschinenbau
Univ.-Prof. Dr.-Ing. habil. M. Weiß
20.10.2014
Auf dem Sensor-Aktor-Modul befindet sich ein Mikrocontroller (µC), der die externe Hardware
(z.B. im Bild 6 die LEDs) ansteuert. Zur Ablaufsteuerung und zur Kommunikation mit dem
Nutzer dient der PC. Die Kommunikation erfolgt über eine USB-Schnittstelle.
Die auf dem Mikrocontrollerboard enthaltene Hardware realisiert die Umwandlung der USBSignale in ein asynchrones serielles Protokoll (USB to Serial). Die Software für den PC muss
ihrerseits die serielle Kommunikation über einen virtuellen COM-Port realisieren.
Im Mikrocontroller dient eine Tabelle (ein Feld) von 16-Bit Zahlen (in C++ in Visual Studio
dementsprechend short int, entspricht short) als Datenschnittstelle. Sowohl der
Mikrocontroller als auch der PC können Daten in diese Tabelle schreiben bzw. auslesen. Die
Position in der Tabelle - also der Feldindex - bestimmt dabei die Bedeutung der Daten. Um die
Nutzung durch den Programmierer zu erleichtern, wird in der Tabelle 1 (s.u.) der Feldindex
durch symbolische Konstanten, nachfolgend als Kommandos bezeichnet, angegeben. Aus dem
entsprechenden Kommando ergibt sich die Bedeutung der übertragenen Daten (beachte: Lesen
von Daten aus der Mikrocontroller-Tabelle oder Schreiben von Daten in die MikrocontrollerTabelle).
Anwendungsbeispiel:
Sendet der PC z.B. eine neue Stellgröße (VALUE) für den Gleichstrommotor (DCM), so wird
dieser Wert in der Mikrocontroller-Tabelle an der Position DCM_SETVALUE gespeichert und
außerdem wird die Software darüber informiert, dass ein neuer Sollwert vorliegt und die
Steuerung entsprechend reagieren muss.
Statusinformationen und Messwerte werden vom Mikrocontroller ebenfalls in der
Mikrocontroller-Tabelle abgelegt und zyklisch aktualisiert. Der PC kann diese Daten jederzeit
abrufen.
Visual Studio C++ Projekteigenschaften und Sensor-Aktor-Funktionsbibliothek (LIB und DLL)
Für die Kommunikation des PC‘s mit dem Mikrocontroller des Sensor-Aktor-Moduls werden
Funktionen bereitgestellt, die die asynchrone serielle Kommunikation realisieren. Die
Funktionen wurden zu einer DLL zusammengefasst, die in das aktuelle Projekt eingebunden
werden muss.
Ein Projekt für Visual Studio 2012, das alle notwendigen Dateien und Einstellungen enthält, liegt
auf AUSHANG\VisualC++ und heißt A3_SensorAktorModul.
Nutzen Sie dieses vorbereitete Visual Studio Projekt!
Bereitgestellte Funktionen zur Kommunikation mit dem Sensor-Aktor-Modul
In einer DLL (Funktionsbibliothek) werden für Ihr Programm folgende Funktionen, die für die
Ansteuerung des Sensor-Aktor-Moduls notwendig sind, bereitgestellt (command und data siehe
Tabelle 1):
1. Verbindung zum Modul herstellen bzw. trennen
int OpenSAM(void);
Nach Programmstart muss die Verbindung einmalig mit OpenSAM(); hergestellt werden.
Der Rückgabewert dieser Funktion ist die Gerätenummer.
13
void CloseSAM(void);
Am Ende des Programms muss die Verbindung getrennt werden.
2. Einen Wert an das Modul senden
int WriteValue(unsigned char command, short data);
Beispiel: Schreiben des Wertes 3 für das Kommando MODE = Betriebsart setzen
WriteValue(MODE,3);
3. Einen Wert vom Modul lesen
int ReadValue(unsigned char command, short* data);
Beispiel: Lesen des Status und Speichern des Wertes auf der Variablen status
short status;
ReadValue(STATUS,&status);
4. Schreiben und Lesen von Datenfeldern
int WriteData(unsigned char destinationindex, unsigned char count,
unsigned char* buffer); // count in Byte, max. 126
int ReadData(unsigned char sourceindex, unsigned char count,
unsigned char* buffer); // count in Byte, max. 126
Beispiel: Lesen der Drehzahlmesswertetabelle
short drehzahl[60];
ReadData(R2_TABLE,120,(unsigned char *)drehzahl);
5. Nutzung des Sensor-Aktor-Displays
int WriteText(int x, int y, char* buffer, int count);
Durch Ausgabe des Sonderzeichens 0x0E wird die automatische Zustandsanzeige
eingeschaltet. Das Sonderzeichen 0x0F löscht die Anzeige.
Beispiel: Löschen des Displays und Anzeige des Textes Maschinenbau
char loeschen = 0x0F;
WriteText(0, 0, &loeschen, 1); // Display löschen
char buffer[] = "Maschinenbau";
WriteText(0, 0, buffer, sizeof(buffer));
Wenn der Rückgabewert einer der genannten Funktionen negativ ist, ist ein Fehler
aufgetreten.
14
TU Ilmenau, Fakultät für Maschinenbau
Univ.-Prof. Dr.-Ing. habil. M. Weiß
20.10.2014
Übersicht aller möglichen Kommandos
Kommandos für die Funktion WriteValue(…)
Kommando
(command)
MODE
Bedeutung
LED
DCM_SETVALUE
LEDs setzen
Stellgröße (Spannung) Motor
setzen
DCM_CLEAR
Zähler Encoder löschen
Betriebsart setzen
Daten
(data)
0 Analog (Standard)
1 Lautsprecher
2 Schrittmotor
3 Gleichstrommotor
Bitmuster (Bit 0…7)
12-Bit PW
-2047 = -Ub (Betriebsspannung)
2047 = Ub
0 = Zähler löschen
Kommandos für die Funktion ReadValue(…)
Kommando
(command)
STATUS
VERSION
Bedeutung
SWITCH
UB
MES_POTI
Schalter lesen
Betriebsspannung lesen
Spannung am Drehpotentiometer lesen
Brückenspannung A lesen
Brückenspannung B lesen
DCM_VOLTAGEA
DCM_VOLTAGEB
DCM_COUNTER
Gerätestatus lesen
Firmwareversion lesen
Zähler der Encoderimpulse
lesen
Daten
(data)
Bit 0,1 enthalten die Betriebsart
Bit13..15: Hauptversion, Bit 8..12: Unterversion
Bit0..7: Geräte-ID
Bitmuster (Bit 0…7)
in mV
in Inkrementen des 10 Bit A/D-Wandlers
UA in Inkrementen des 10 Bit A/D-Wandlers
UB in Inkrementen des 10 Bit A/D-Wandlers
UMotor = UB - UA
64 Impulse pro Umdrehung
Argumente für die Funktion ReadData(…)
Startindex in der µC-Tabelle
(sourceindex)
R2_TABLE
Bedeutung
Startadresse des Verlaufs der
Motordrehzahl (in U/min)
Daten
(buffer)
60 Werte (short int) werden
nach der Vorgabe eines neuen
PWM-Wertes für den Gleichstrommotor gespeichert (10
Werte pro s, neue Messung
wird nur gestartet, wenn
vorherige beendet wurde).
Tabelle 1: Sensor-Aktor-Kommandos
15
Aufgabe 4: C-Dateiarbeit
Ziel des Programms sind das Lesen und Schreiben von Textdateien und das Lesen und Schreiben
von Binärdateien.
Vorgegeben ist die Textdatei "Durchmesser.txt". Sie liegt sowohl im Projektverzeichnis als auch auf
"Aushang\VisualC++\Text_und_Binaerdateien".
Sie speichert eine Menge von Durchmesser - Messwerten einschließlich Zusatzinformationen. Jede
Zeile enthält das Datum, eine Nummer und den Messwert in mm. Der Dateiaufbau entspricht
folgendem Muster:
17.09.2014
17.09.2014
18.09.2014
…….
315
316
317
20.032
19.997
20.018
Aufgaben:
1. Anzeige des Inhalts der Textdatei auf dem Bildschirm. Die Formatierung der Datei soll erhalten
bleiben.
2. Einlesen der Textdatei und Auswertung der Messwerte
a. Erzeugen Sie eine neue Textdatei "Ausschuss.txt".
In dieser Datei sollen alle Zeilen von "Durchmesser.txt" gespeichert werden, deren
Messwerte außerhalb einer Toleranz von ±0.05 mm um den Nennwert 20.0 mm liegen.
Zeigen Sie die Anzahl der Zeilen mit Ausschuss an.
b. Erzeugen Sie eine neue Binärdatei "Messwerte.bin".
In dieser Datei sollen nur die Messwerte abgespeichert werden, die in der
vorgegebenen Toleranz liegen.
3. Ermitteln Sie den arithmetischen Mittelwert der Messwerte aus der Datei "Messwerte.bin"
und zeigen Sie diesen auf dem Bildschirm an.
Ein Projekt für Visual Studio 2012 liegt auf "Aushang\VisualC++" und heißt A4_Dateiarbeit.
16
TU Ilmenau, Fakultät für Maschinenbau
Univ.-Prof. Dr.-Ing. habil. M. Weiß
20.10.2014
Aufgabe 5: Klassen in C++ und Nutzung des .NET Frameworks
Aufgabe:
Erstellen Sie ein Programm zur Berechnung von Dreiecken, das folgende Teilaufgaben realisiert:
1. Einlesen der Seitenlängen (in mm) über die Tastatur
2. Prüfen, ob die eingegebenen Seitenlängen ein gültiges Dreieck ergeben
3. Wiederholung der Eingabe, solange die Seiten kein Dreieck ergeben
4. Prüfen, ob das Dreieck rechtwinklig ist und Anzeigen des Ergebnisses
5. Berechnen und Anzeigen des Flächeninhalts des Dreiecks
Zur Lösung der Aufgabe ist ein Programmgerüst, das Projekt A5_Klassen, vorgegeben. Dieses
können Sie von AUSHANG\VISUALC++ kopieren.
Das Projekt A5_Klassen enthält die 3 Dateien

Triangle.h – Klassendeklaration

Triangle.cpp – Klassenimplementation

Start.cpp – Hauptprogramm
Wenn Sie das Projekt neu erstellen wollen, müssen Sie folgende Hinweise beachten:



Erstellen Sie ein leeres C++ Projekt
Schalten Sie ProjectPropertiesConfiguration PropertiesGeneralCommon
Language Runtime support ein (/CLR)
Kopieren Sie die vorgegebenen Dateien in das Projektverzeichnis und fügen Sie diese zu
Ihrem Projekt hinzu (Alternativ: Add Class zum Erzeugen einer neuen Klasse).
17
Triangle.h – Klassendeklaration
#pragma once
ref class Triangle
{
private:
double sideA;
double sideB;
double sideC; // auf diese Variable wird immer die größte Seite geladen
double area;
void CalculateArea();
public:
Triangle(void);
~Triangle(void);
bool SetValues(double sA, double sB, double sC);
bool IsOrthogonal();
property double Area
{
double get()
{
CalculateArea();
return area;
}
/* set-Zweig hier nicht erforderlich
void set(double value)
{
area=value;
}
*/
}
};
18
TU Ilmenau, Fakultät für Maschinenbau
Univ.-Prof. Dr.-Ing. habil. M. Weiß
20.10.2014
Triangle.cpp – Klassenimplementation
using namespace System;
#include "Triangle.h"
//Konstruktor
Triangle::Triangle(void)
{
// Initialisieren der privaten Felder (Membervariablen) mit 1.0
// und Berechnung des Flächeninhalts
}
//Destruktor
Triangle::~Triangle(void)
{
}
bool Triangle::SetValues(double sA, double sB, double sC)
{
// die Werte sortieren, so dass der größte Wert in sC steht
// Prüfen, ob die eingegebenen Seiten ein Dreieck ergeben
// wenn die Seiten ein Dreieck ergeben, die übergebenen Werte auf die
// privaten Membervariablen setzen
}
bool Triangle::IsOrthogonal()
{
// Prüfen, ob das Dreieck rechtwinklig ist
}
void Triangle::CalculateArea()
{
// Berechnen des Flächeninhalts
// Flächeninhalt für beliebiges Dreieck:
// A=sqrt(s*(s-a)*(s-b)*(s-c)) mit s=(a+b+c)/2
}
19
Start.cpp – Hauptprogramm
// Datei: Start.cpp
// Versuch 5: Klassen in C++
// C++ Console Projekt mit .NET
// C++ .NET - muss in den Projekteigenschaften eingeschaltet werden
// --> Common language runtime support einschalten! siehe Anleitung
using namespace System;
#include "Triangle.h"
void main(void)
{
String^ message="Programm zur Berechnung von Dreiecken";
Console::WriteLine(message);
// Ein Objekt der Klasse Triangle anlegen
//
//
//
//
Seitenlängen über Tastatur eingeben mit Hilfe der Funktion
Console::ReadLine()
So lange wiederholen, bis die eingegebenen Seitenlängen ein
gültiges Dreieck ergeben
// Prüfen, ob das Dreieck rechtwinklig ist und Anzeigen des Ergebnisses
// Berechnen und Anzeigen des Flächeninhalts des Dreiecks
Console::ReadKey();
}
20
// Warten auf Tastendruck
TU Ilmenau, Fakultät für Maschinenbau
Univ.-Prof. Dr.-Ing. habil. M. Weiß
20.10.2014
Lehrmaterial
Datentypen und Konstanten in C++
Typname
Byte- Kommentar
anzahl
Konstante
(Beispiele)
Ganzzahlige Typen = integrale Typen
char /
signed char
unsigned char
1
8-Bit mit Vorzeichen
-128 bis +127
8-Bit ohne Vorzeichen
0 bis 255
16-Bit mit Vorzeichen
-32.768 bis 32.767
16-Bit ohne Vorzeichen
0 bis 65.535
32-Bit mit Vorzeichen
-2.147.483.648 bis 2.147.483.647
32-Bit ohne Vorzeichen
0 bis 4.294.967.295
32-Bit mit Vorzeichen ( in C# 8 Byte ! )
-2.147.483.648 bis 2.147.483.647
32-Bit ohne Vorzeichen
0 bis 4.294.967.295
64-Bit mit Vorzeichen ( 19 Stellen )
- 9.223.372.036.854.775.808 bis
+9.223.372.036.854.775.807
64-Bit ohne Vorzeichen ( 19 Stellen )
0 bis 18.446.744.073.709.551.615
'A', '\n'
'\x1B' = Escape
0xFF (hexadezimal)
short int
2
unsigned short
int
int /
signed int
unsigned int
2
±1.5 × 10-45 bis ±3.4 × 1038
7 Stellen
±5.0 × 10-324 bis ±1.7 × 10308
15 Stellen
2.34F
2.34f
2.34
12E-2, 1.67e5
2
Ein 16-Bit Zeichen aus der
Unicodetabelle,
0 - 65535
L'A', L'\n'
1
Schlüsselworte: true, false
true
1
4
4
long int /
4
signed long int
unsigned long int 4
long long /
signed long long
8
unsigned long
long
8
2345
2345U
2345u
2345
2345U
2345u
2345L
2345l
2345UL
2345ul
Gleitkommatypen
float
4
double
8
Unicodezeichen
wchar_t
Wahrheitswerte
bool
21
Funktionen zur Anzeige auf dem Bildschirm - printf() und zur Tastatureingabe - scanf()
Einlesen formatierter Daten von der Tastatur und formatierte Anzeige auf dem Bildschirm
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
void main()
{
int
double
char
i;
x;
text[80];
printf("Geben Sie eine int-Zahl ein: ");
scanf("%d", &i);
printf("Geben Sie eine double-Zahl ein: ");
scanf("%lf", &x);
printf("Geben Sie eine Zeichenkette ein: ");
scanf("%s", text);
printf("Inhalt der Daten: %d %lf %s\n", i, x, text);
}
Nutzung von _kbhit() und _getch() sowie der Taste Esc (Escape)
#include <conio.h>
#include <stdio.h>
void main()
{
bool ende = false; // Taste Esc setzt ende auf true
int taste = 0;
do
{
// Hier kommt das gesamte Programm
printf("Ich rechne noch …\n");
if(_kbhit() != 0)
//
{
//
taste =_getch(); //
if(taste == 0x1B) //
ende = true;//
}
}
while(ende == false);
}
22
Test auf Tastendruck
Ja, es wurde eine Taste gedrückt
Taste lesen
War es die Esc-Taste?
Ja, dann Ende der while-Schleife
TU Ilmenau, Fakultät für Maschinenbau
Univ.-Prof. Dr.-Ing. habil. M. Weiß
20.10.2014
Felder und Strukturen
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <conio.h>
#include <string.h>
void main()
{
char anzeigetext[80]; // Ein Feld für 80 Zeichen = Zeichenkette
strcpy(anzeigetext,"Anzeige der Quadratzahlen von 0 bis 19\n");
int quadratzahlen[20]; // Ein Feld für 20 int-Zahlen
for(int i=0; i<20; ++i) // Index läuft von 0 bis 19
quadratzahlen[i]=i*i; // Füllen des Feldes
printf("%s",anzeigetext);
for(int i=0; i<20; ++i)
printf("%d x %d = %d\n",i,i,quadratzahlen[i]);
_getch();
}
Anzeige:
Anzeige
0 x 0 =
1 x 1 =
2 x 2 =
…
der Quadratzahlen von 0 bis 19
0
1
4
#include <stdio.h>
#include <conio.h>
#include <string.h>
struct student // Strukturdeklaration
{
int matrikelNr;
double bafoeg;
};
void main()
{
student meier; //Definition der Struktur meier vom Typ student
meier.matrikelNr = 12345; // Zugriff auf eine Komponente der Struktur
meier.bafoeg = 512.50;
printf("Der Student mit der Matrikelnummer %d erhaelt %.2lf Euro Bafoeg.\n",
meier.matrikelNr,meier.bafoeg);
_getch();
}
Anzeige:
Der Student mit der Matrikelnummer 12345 erhaelt 512.00 Euro Bafoeg.
23
Funktionen zur Dateiarbeit
Formatiertes Schreiben und Lesen einer Datei im Textmodus (vergleiche: printf() und scanf() )
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
FILE *stream1, *stream2;
int
i, zeilenzahl=0;
double x;
char
name[80];
if((stream1=fopen("test.txt", "rt" )) == NULL)
{
printf("Datei konnte nicht geoeffnet werden!\n");
return(-1);
}
while(fscanf(stream1,"%d%lf%s", &i, &x, name) != EOF)
++zeilenzahl;
printf("%d Zeilen wurden gelesen.\n", zeilenzahl);
rewind(stream1); //Filepointer wieder an den Anfang der Datei setzen
fscanf(stream1,"%d%lf%s", &i, &x, name);
fclose(stream1);
if((stream2=fopen("erstezeile.txt", "wt" )) == NULL)
{
printf("Datei konnte nicht erzeugt werden!\n");
return(-2);
}
fprintf(stream2,"%s: %lf\n", name, x);
fclose(stream2);
return(0);
}
Aufbau der Datei "test.txt":
1
…
27
27.5
Temperatur
1026
Druck
Aufbau der Datei "erstezeile.txt":
Temperatur: 27.500000
24
TU Ilmenau, Fakultät für Maschinenbau
Univ.-Prof. Dr.-Ing. habil. M. Weiß
20.10.2014
Schreiben und Lesen im Binärmodus
Demo 1: Ein Feld von 10 int-Zahlen schreiben und lesen und anzeigen
#define _CRT_SECURE_NO_WARNINGS
#include < stdio.h >
#include <conio.h>
void main ()
{
FILE *fp;
int
testout[10], testin[10], i;
for ( i = 0 ; i < 10 ; ++i )
testout[i] = 276 + i ;
// Feld füllen (Demo Werte)
fp = fopen ( "C:\\Kopie\\test.bin", "wb" );
// Datei im Binärmodus
// hier wird als Demo das ganze Feld
// (10 int-Zahlen = 40 Byte) auf einmal geschrieben
fwrite ( testout, sizeof (testout), 1, fp );
fclose ( fp );
fp = fopen ( "C:\\Kopie\\test.bin", "rb" );
for (i=0; i<10; ++i)
// hier wird als Demo jede int-Zahl = 4 Byte einzeln gelesen
fread (&testin[i], sizeof (int), 1, fp );
fclose ( fp );
// Anzeigen
for ( i = 0 ;
printf
_getch();
i < 10 ;
( "%d %d
++i )
%d \n", i, testout[i], testin[i]);
}
Demo 2: Schreiben und Lesen eines Feldes aus Strukturen
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
struct messwert
{
int nr;
char zeit[12];
double wert;
};
void main()
{
struct messwert feld[5]={
{1,"12:27",3.45},
{2,"13:35",1.78},
{3,"10:56",5.96},
{4,"9:17",11.73},
{5,"14:27",-3.01}};
FILE * fp;
fp=fopen("messwerte.bin","wb");
fwrite(feld, sizeof(feld), 1, fp); // ganzes Feld schreiben
fclose(fp);
//nur die erste Struktur einlesen
fp=fopen("messwerte.bin", "rb");
struct messwert zeile;
fread(&zeile, sizeof(zeile), 1, fp);
printf("Erster Messwert: %lf\n", zeile.wert);
fclose(fp);
}
25
Ablaufsteuerung
do-while-Schleife
Syntax:
do
{
< Anweisungen >
}
while ( < Bedingungstest > ) ;
int k ;
k = 12 ;
do
{
printf( " k = % d \n " , k );
k = k-1;
} while( k > 8 );
while-Schleife
Syntax:
while ( < Bedingungstest > )
{
< Anweisungen >
}
int k = 12;
while( k > 8 )
{
printf( "k = %d \n", k );
k = k-1;
}
for-Schleife
Syntax:
for ( < Initialisierung > ; < Bedingungstest > ; < Modifizierung > )
{
< Anweisungen >
}
for( int k = 12 ; k > 8 ; --k)
{
printf("k = %d \n", k );
}
26
TU Ilmenau, Fakultät für Maschinenbau
Univ.-Prof. Dr.-Ing. habil. M. Weiß
20.10.2014
if-Anweisung
Syntax:
if ( < Bedingungstest > )
{
< Anweisungen >
}
if - else
Syntax:
if ( < Bedingungstest
{
/* Test liefert
< Anweisungen 1
}
else
{
/* Test liefert
< Anweisungen 2
}
> )
wahr */
>
falsch */
>
taste = _getch( );
if( taste == 'p' )
printf("Ein kleines p !");
else
printf("Kein kleines p !");
switch-Anweisung
Syntax:
switch ( < ganzzahliger Ausdruck > )
{
case < ganzzahliger Ausdruck >:< Anweisungen >
break;
default :
< Anweisungen >
break;
}
#include <stdio.h>
#include <conio.h>
void main()
{
int taste;
printf("Bitte Taste betaetigen ");
taste = _getch();
switch( taste )
{
case 'p' : printf("Taste p\n");
break ;
case '\r': printf("Enter Taste! \n");
break ;
default :
printf("Ende !");
break ;
}
_getch();
}
27
Die Anweisung break
ist in folgenden Fällen anwendbar
- mit break kann man eine (nicht zwei) Schleife verlassen
- wirkt bei switch, while, do - while und for
- wirkt nicht auf if oder else
#include <stdio.h>
#include <conio.h>
void main()
{
int taste;
int flag = 1;
printf("Druecken Sie eine Taste ( Ende mit der Tabulatortaste! )\n");
while(flag == 1)
{
taste = _getch();
if( taste == '\t' )
{
printf("Das war die Tabulatortaste!\n\a");
break;
}
}
}
Die Anweisung continue
- mit continue kann man einen Schleifendurchlauf abbrechen
- man springt zum Anfang (zur Modifizierung) der Schleife zurück
#include <stdio.h>
void main()
{
int i;
for ( i = 0 ; i < 10 ; ++i )
{
if ( i > 3 )
continue ;
printf( " i = %d \n ", i );
}
printf(" i = %d \n ", i );
printf(" ok ! ");
}
28
TU Ilmenau, Fakultät für Maschinenbau
Univ.-Prof. Dr.-Ing. habil. M. Weiß
20.10.2014
Arithmetische Operatoren
*
/
%
+
-
Multiplikation
Division
Modulo (Rest der ganzzahligen Division)
Addition
Subtraktion
x=5*y
x = x/y
x = 19 % 3
(Ergebnis: x = 1 )
Vergleichsoperatoren
<
<=
>
>=
==
!=
kleiner als
kleiner gleich
größer als
größer gleich
Test auf Gleichheit ( Verwechselungsgefahr mit dem Zuweisungsoperator = )
Test auf Ungleichheit
Inkrement- und Dekrementoperatoren
++
--
bedeutet Inkrementieren des Operanden um eine Einheit,
bedeutet Dekrementieren des Operanden um eine Einheit
aber: Die Stellung der Operatoren ist zu beachten:
- Präfixinkrementierung
int x, y;
x = 3;
y = ++x ;
//
//
x = x + 1, y = x
also x = 4, y = 4
//
//
y = x, x = x + 1
also y = 3, x = 4
- Postfixinkrementierung
int x, y;
x = 3
y = x++ ;
Bitweise Operatoren
&
|
^
<<
>>
~
UND
( Bits löschen, Bits ausblenden, Bits maskieren )
ODER
( Bits setzen, Bits einblenden )
exklusives ODER
Linksschieben
Rechtsschieben
Einerkomplement
29
unsigned char x=0x3; //binär: x = 0000 0011
unsigned char y=0x2; //
y = 0000 0010
unsigned char z;
z = x & y;
011
& 010
z = 010 = 2
z = x | y ;
011
| 010
z = 011 = 3
z = x ^ y ;
011
^ 010
z = 001 = 1
unsigned char w = 0;// binär: w=0000 0000
w = ~w;
//
w=1111 1111
w = w >> 2;
//
w=0011 1111=0x3F=63(um 2 Bit nach rechts schieben)
Beispiel: Die Funktion liefert die Anzahl der Einsen in einem Byte.
int AnzahlEins ( unsigned char wert )
{
int anzahl=0;
for ( int i = 0; i < 8; ++i )
{
if ( (wert & 0X80) != 0 )
++anzahl;
wert = 2 * wert;
}
return anzahl;
}
Logische Operatoren
&&
||
!
logisches UND
logisches ODER
logische Negation
Beispiel: Test, ob eine Zahl z der Code eines ASCII-Buchstabens ist
int busta(int z)
{
if( z >= 'a' && z <= 'z' || z >= 'A' && z <= 'Z' )
return (1) ;
else
return (0) ;
}
30
TU Ilmenau, Fakultät für Maschinenbau
Univ.-Prof. Dr.-Ing. habil. M. Weiß
20.10.2014
Adreßoperatoren
&
liefert die Speicheradresse eines Operanden
*
- beeinflusst den Speicherinhalt, der unter einer Speicheradresse zu finden ist
- beeinflusst also den Wert unter Benutzung der Adresse eines Operanden
sizeof – Operator
Der sizeof – Operator liefert die Anzahl der in seinem Operanden enthaltenen Bytes.
x = sizeof (int);
// x = 4 bei 32/64-Bit-Windows
char text [] = "C++";
x = sizeof (text);
// x = 4 da 3 ASCII-Zeichen und das Endekennzeichen '\0'
new und delete - Operatoren zur dynamischen Anforderung von Speicher
Beispiel: Speicher für eine double Zahl anfordern, nutzen und freigeben
double * px;
px = new double;
*px = 6.285;
delete px;
Beispiel: Speicher für 10000 Byte anfordern, nutzen und freigeben
char * pc;
pc = new char [10000];
strcpy( pc, "Neuer Speicher!");
printf("%s\n", pc);
delete [] pc;
31
weitere Bibliotheksfunktionen
(Beachte: einige Funktionen benötigen #define _CRT_SECURE_NO_WARNINGS)
Mathematische Funktionen, benötigte Headerdatei: #include <math.h>
#define _USE_MATH_DEFINES vor #include <math.h> ermöglicht die Benutzung der Konstanten M_PI für π
Funktion
Beispiel
Betrag einer int-Zahl
Betrag einer double-Zahl
Aufrunden
Ganzzahliger Anteil einer
double-Zahl (Abrunden)
Rest einer Division
Kosinus
Sinus
Tangens
Arkuskosinus
Arkussinus
Arkustangens
Arkustangens mit
Berücksichtigung des
Quadranten
natürliche
Exponentialfunktion,
e-Funktion  
natürlicher Logarithmus,
 
dekadischer Logarithmus,
10 
Potenzfunktion,  
int abs(int x);
double fabs(double x);
double ceil(double x);
double floor(double x);
int value1 = abs(-3); //value1 = 3
double value2 = fabs(-3.1); //value2 = 3.1
value2 = ceil(3.4); //value2 = 4.0
value2 = floor(3.6); //value2 = 3.0
double
double
double
double
double
double
double
double
value2
value2
value2
value2
value2
value2
value2
value2
value2
Quadratwurzel
32
Parameter in Bogenmaß
Beschreibung
fmod(double x, double y);
cos(double x);
sin(double x);
tan(double x);
acos(double x);
asin(double x);
atan(double x);
atan2(double x, double y);
=
=
=
=
=
=
=
=
=
fmod(4.1,2.0); //value2 = 0.1
cos(0.0); //value2 = 1.0
sin(0.0); //value2 = 0.0
tan(0.0); //value2 = 0.0
acos(1.0); //value2 = 0.0
asin(0.0); //value2 = 0.0
atan(1.0); //value2 = 0.7853.. -->45°
atan2(-1.0,1.0); //value2 = -0.7853.. -->-45°
atan2(1.0,0.0); //value2 = 1.570.. -->180°
double exp(double x);
value2 = exp(1.0); //value2 = 2.718281..
double log(double x);
value2 = log(2.718281); //value2 = 1.0
double log10(double x);
value2 = log10(1000.0); //value2 = 3.0
double pow(double x, double y);
value2 = pow(2.0,3.0); //value2 = 8.0
value2 = pow(27.0,1.0/3.0); //3. Wurzel aus 27: value2 = 3.0
value2 = sqrt(16.0); //value2 = 4.0
double sqrt(double x);
Zeichenketten-Funktionen, benötigte Header-Datei: #include <string.h>
Beschreibung
Funktion
Beispiel
Anlegen einer Variable zum
Speichern von Zeichenketten
Zeichenkette in eine andere
kopieren
Zeichenkette an eine andere
anhängen
Zeichenketten vergleichen
-
char str[80]; //Zeichenkette mit bis zu 79 Zeichen (+
Stringendekennzeichen)
char *strcpy(char *ziel, const char *quelle);
strcpy(str, "Hallo "); //str = "Hallo ", evtl. vorhandener
//Inhalt wird überschrieben
char *strcat(char *ziel, const char *quelle);
strcat(str, "Welt!"); //str = "Hallo Welt!"
int strcmp(const char *str1,
const char *str2);
Prüfen, ob ein Zeichen in
einer Zeichenkette vorhanden
ist
Prüfen, ob Zeichenkette in
einer anderen enthalten ist
Länge einer Zeichenkette
ermitteln
char *strchr(const char *str, int c);
int result = strcmp("Affe","Affe"); //result = 0
result = strcmp("Affe","affe");
//result = -1
result = strcmp("Affe","Zebra");
//result = -1
result = strcmp("Zebra","Affe");
//result = 1
char *pos = strchr(str,'x'); //pos = NULL, da kein 'x' vorh.
pos = strchr(str,'e'); //pos != NULL, "Adresse" von 'e'
int index = pos – str; //Index von 'e' innerhalb von str ermitteln
char *strstr(char *str1, const char *str2);
pos = strstr(str,"Affe"); //Bedeutung von pos: siehe strchr()
int strlen(const char *str);
int len = strlen(str); //len = 11 (Länge ohne Stringendekennz.)
Sonstige Funktionen, benötigte Header-Dateien: für a: #include <windows.h> für b-e: #include <stdlib.h>
Beschreibung
a
b
c
d
e
Funktion
Beispiel
Wartezeit, Programm
anhalten
Zufallsgenerator
initialisieren
Zufallszahl erzeugen
void Sleep(DWORD milliSeconds);
Sleep(500); //wartet 500ms
void srand(unsigned int seed);
srand(20); //Zufallszahlengenerator wird auf "pseudo"zufälligen Startwert gesetzt
int rand(void);
Zeichenkette in doubleZahl konvertieren
Zeichenkette in int-Zahl
konvertieren
double atof(char *str);
int zuf = rand(); //zuf = Zufallszahl zwischen 0 und 32767
zuf = rand() % 100; //zuf = Zufallsz. zw. 0 und 99
double wert = atof("3.141"); //wert = 3.141
int atoi(char *str);
int wert2 = atoi("128"); //wert2 = 128
33
Funktionen zur Dateiarbeit, benötigte Headerdatei: #include <stdio.h>
Für alle Dateien
Beschreibung
Funktion
Beispiel
Eine Datei öffnen
FILE * fopen(const char * DateiName,
const char * Modus);
Eine Datei schließen
Dateizeiger an Dateianfang
setzen
Dateizeiger an beliebige Stelle
setzen
int fclose(FILE *DateiZeiger);
void rewind(FILE *DateiZeiger);
FILE * fp = fopen("Messwerte.bin","rb"); //binär lesen
FILE * fp2 = fopen("Messwerte.bin","wb"); //binär schreiben
FILE * fp3 = fopen("Messwerte.txt","rt"); //Textdatei lesen
FILE * fp4 = fopen("Messwerte.txt","wt"); //Textd. schreiben
fclose(fp);
rewind(fp);
int fseek(FILE *DateiZeiger,
long offsetInByte,
int origin);
fseek(fp, 24L, SEEK_SET); //Dateizeiger auf Byte 24 (vom
//Dateianfang aus) setzen
fseek(fp, -8L, SEEK_CUR); //Dateizeiger 8 Byte zurücksetzen
size_t fwrite(const void *daten,
size_t GroeßeInByte,
size_t Anzahl,
FILE *DateiZeiger);
double messwert = 12.3;
double alleWerte[5] = { 2.4, 3.5, 7.2, 8.1, 9.9};
Rückgabewert = Anzahl geschriebener Elemente
//Ein ganzes Feld aus Double-Zahlen auf einmal schreiben
fwrite(alleWerte, sizeof(alleWerte), 1, fp2);
//Eine Double-Zahl lesen
fread(&alleWerte[0], sizeof(double), 1, fp);
Nur für Binärdateien
In eine Binärdatei schreiben
Aus einer Binärdatei lesen
size_t = unsigned int
size_t fread(const void *daten,
size_t GroeßeInByte,
size_t Anzahl,
FILE *DateiZeiger);
Rückgabewert = Anzahl gelesener Elemente.
Rückg.w. = 0: kein Wert gelesen, z.B. am Dateiende.
34
//Eine Double-Zahl schreiben
fwrite(&messwert, sizeof(double), 1, fp2);
//Ein ganzes Feld aus Double-Zahlen auf einmal lesen
fread(alleWerte, sizeof(alleWerte), 1, fp);
//Solange eine Double-Zahl gelesen werden konnte, ...
while (fread(&messwert, sizeof(double), 1, fp) > 0)
...
Nur für Textdateien
In eine Textdatei schreiben
Aus einer Textdatei lesen
int fprintf(FILE *DateiZeiger,
const char *format);
int fscanf(FILE *DateiZeiger,
const char *format);
int i = 1;
fprintf(fp4, "%d. Messwert: \t %lf \n", i, 23.67);
//Eine Zeile mit obigem Aufbau lesen
unsigned char text[200];
fscanf(fp3, "%d %s %lf", &i, text, &wert);
//Ein Zeichen aus Textdatei lesen, solange Dateiende
//noch nicht erreicht ist
unsigned char zeichen;
while( fscanf(fp3, "%c", &zeichen) != EOF) ...
Funktionen für Bildschirmausgaben und Tastaturnutzung, benötigte Headerdateien: #include <stdio.h> #include <conio.h>
Bildschirmausgaben
Beschreibung
Funktion
Beispiel
Formatierte Ausgabe auf dem
Bildschirm
int printf(const char *text [,
argumente]);
int tag = 15;
printf("Heute ist Mittwoch, der %d.%d.%d\n", tag, 10, 2014);
wichtige Escape-Sequenzen
\n
neue Zeile
\t
Tabulator
\b
„Backspace“
\r
Cursor Zeilenanfang
Ein Zeichen ausgeben
Tastaturnutzung
Formatiertes einlesen über die
Tastatur (Eingaben müssen mit
<Enter> abgeschlossen
werden)
Ein Zeichen lesen (wartet auf
Drücken einer Taste!)
Prüfen, ob überhaupt eine
Taste gedrückt wurde
und Platzhalter
%d
Integer-Zahl
%lf
Double-Zahl
%s
Zeichenkette
%c
einzelnes (ASCII)-Zeichen
int putch(int zeichen);
putch(0x34); //Gibt die Ziffer 4 aus
putch('a'); //Gibt ein kleines a aus
int scanf(const char *text [,
argumente]);
double eingabe1, eingabe2;
scanf("%lf", &eingabe1);
scanf("%lf %lf", &eingabe1, &eingabe2); //Leerzeichen notw.
int _getch(void);
int taste = _getch(); //ASCII-Zeichen steht in taste
if(_getch() == 'a') ... else ... // Wenn 'a' gedrückt, ...
if(_kbhit() != 0)
taste = _getch(); //_getch() nur aufrufen, wenn Taste gedr.
int _kbhit(void);
35
C++ - Klassendemo
Schritt 1: Klassendeklaration
ref class CDate
// die Klasse heisst also CDate
{
private:
// drei private- Membervariablen vom Typ int
int tag;
int monat;
int jahr;
public:
CDate();
// Konstruktor
~CDate();
// Destruktor
void set_werte( int t, int m, int j ); //eine Methode der Klasse
void display();
// noch eine Methode
int pub;
// eine public- Membervariable vom Typ int
property int Jahr
// eine property für jahr
{
int get()
{
return jahr;
}
void set(int value)
{
jahr=value;
}
}
};
Schritt 2: Methodendefinition
// Konstruktor, Aufgabe: Initialisierung aller Membervariablen
CDate::CDate()
{
pub=0;
tag=1;
monat=1;
jahr=2012;
}
// Destruktor, hat in diesem Beispiel keine Aufgabe
CDate:: ~CDate()
{
}
36
TU Ilmenau, Fakultät für Maschinenbau
Univ.-Prof. Dr.-Ing. habil. M. Weiß
20.10.2014
// Eine Methode (Funktion) zum Setzen der privaten Variablen
void CDate::set_werte( int t, int m, int j )
{
tag=t;
monat=m;
jahr=j;
}
// Eine Methode zur Anzeige der privaten Variablen
void CDate::display()
{
System::Console::WriteLine("tag={0} monat={1} jahr={2}",
tag, monat, jahr);
}
Schritt 3: Klassennutzung
using namespace System;
void main()
{
// Ein Objekt der Klasse CDate wird angelegt
// Das Objekt heisst datum
// Der Konstruktor wird automatisch abgearbeitet
CDate datum;
// Test: Anzeige des Initialisierungswertes von m_pub
Console::WriteLine("Feld pub ist initialisiert mit:{0}",datum.pub);
// Methodenaufruf durch Nutzung des Punktoperators
datum.display();
// Änderung aller Werte
datum.pub = 7;
// Einlesen von der Tastatur mit Hilfe von .NET Klassen
int jahreingabe;
String^ input;
Console::WriteLine("Bitte geben Sie das Jahr ein:");
input= Console::ReadLine();
jahreingabe=Convert::ToInt32(input);
datum.set_werte( 1, 5, jahreingabe);
// Anzeige der geänderten Werte
Console::WriteLine("Das Feld pub hat den Wert: {0}",datum.pub);
Console::WriteLine("Das Feld jahr hat den Wert: {0}",datum.Jahr);
Console::ReadKey(); //Warten auf Tastendruck
}
// Der Destruktor wird automatisch abgearbeitet
37
Document
Kategorie
Technik
Seitenansichten
10
Dateigröße
1 073 KB
Tags
1/--Seiten
melden