C Kurs mit dem XMC 2Go Evaluation Kit Labor Mikrocontroller der Studiengänge Elektrotechnik/Informationstechnik Technische Informatik Mechatronik Medizintechnik XMC 2Go (Quelle: www.infineon.com/xmc-dev) Dipl.-Ing.(FH), ING-PAED IGIP Joachim Hampel 4.8.2014 Version 8.2 Inhalt 1 2 3 Installation der Software ................................................................................................... 3 1.1 Treiber installieren .................................................................................................... 3 1.2 Keil uVision installieren ............................................................................................. 4 Das XMC 2Go Mikrocontroller Evaluation Kit .................................................................... 5 2.1 Funktionen des XMC 2Go ......................................................................................... 6 2.2 Die Laborumgebung ................................................................................................. 6 Die Entwicklungsumgebung (IDE) .................................................................................... 6 3.1 Die Entwicklungsumgebung Keil uVision4................................................................. 6 3.2 Die Ordnerstruktur .................................................................................................... 7 3.3 Keil µVision mit NWT_2Go_Blinky testen .................................................................. 8 3.4 Ausgaben der Kommunikationsschnittstelle anzeigen ............................................... 9 3.4.1 4 NWT_2Go_Vorlage................................................................................................. 11 3.6 Projekt säubern ....................................................................................................... 11 3.7 Projekt kopieren ...................................................................................................... 11 Elemente der Programmiersprache ................................................................................ 13 4.1 4.1.1 Variablen................................................................................................................. 13 Arrays ............................................................................................................................. 14 4.2 Anweisungen .......................................................................................................... 15 4.3 Anweisungsblock .................................................................................................... 15 4.4 Funktionen .............................................................................................................. 15 4.5 Die main Funktion ................................................................................................... 16 4.6 Mathematische Operatoren ..................................................................................... 17 4.6.1 4.6.2 4.6.3 4.7 4.7.1 4.7.2 4.8 4.8.1 4.8.2 4.8.3 4.8.4 4.8.5 4.8.6 5 Textdateien mit Excel verarbeiten .................................................................................. 10 3.5 Grundrechenarten .......................................................................................................... 17 Inkrementieren und Dekrementieren .............................................................................. 18 Vergleichsoperatoren ..................................................................................................... 18 Programmverzweigungen ....................................................................................... 18 Die if-Anweisung............................................................................................................. 18 Die switch-Anweisung .................................................................................................... 20 Schleifen ................................................................................................................. 21 Kopfgesteuerte Schleifen ............................................................................................... 21 while – Schleife............................................................................................................... 21 for - Schleife ................................................................................................................... 22 Fußgesteuerte Schleifen ................................................................................................ 23 do while - Schleife ......................................................................................................... 23 Schlüsselworte in Schleifen ............................................................................................ 23 Spezielle Funktionen für das XMC 2Go Board ................................................................ 25 5.1 5.1.1 5.1.2 5.1.3 5.1.4 Kommunikationsschnittstelle ................................................................................... 25 Ganze Zahlen (Integer) Werte senden ........................................................................... 25 Kommazahlen (Float Werte) senden............................................................................. 26 Zeichenketten senden .................................................................................................... 26 Eine neue Zeile beginnen ............................................................................................... 26 __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit -1- 5.2 5.2.1 5.2.2 5.2.3 6 XMC_2Go_NWT Modul ......................................................................................... 27 LEDs verwenden ............................................................................................................ 27 Drucktaster (Switch) auslesen ........................................................................................ 28 Warten ............................................................................................................................ 28 Port-Pins einsetzen......................................................................................................... 29 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 Port-Pins als digitale Eingänge ............................................................................... 30 Eingänge für aktive digitale Signale ............................................................................... 30 Eingänge für passive Signale ......................................................................................... 30 Einlesen der Eingangswerte ........................................................................................... 31 Anschluss eines Tasters ................................................................................................ 31 Port-Pins als digitale Ausgänge .............................................................................. 32 Ausgänge für aktive digitale Signale .............................................................................. 32 Ausgänge über die ein Strom fließen soll ...................................................................... 32 Anschluss einer Leuchtdiode ......................................................................................... 33 Anschluss eines Piezo-Schallwandlers .......................................................................... 34 Anschluss eines Motors ................................................................................................. 35 Port-Pins als analoge Eingänge einsetzen .............................................................. 35 Port-Pins als analoge Eingänge initialisieren ................................................................. 36 Analoge Spannungswerte in eine Zahl zwischen 0 und 4095 wandeln ......................... 36 Einlesen eines Potentiometers ....................................................................................... 36 Einsatz eines Ringspeichers .......................................................................................... 38 7 Der System-Timer .......................................................................................................... 40 8 Servos ............................................................................................................................ 42 9 Übungen ......................................................................................................................... 44 9.1 Fußgängerampel..................................................................................................... 44 9.2 FET- Fussball Ergebnis Tipper................................................................................ 44 9.3 Lern Timer .............................................................................................................. 44 10 Anhang Übersicht ........................................................................................................... 45 10.1 Datentypen ............................................................................................................. 45 10.2 NWT_UART Modul ................................................................................................. 45 10.3 XMC_2Go_NWT Modul ......................................................................................... 45 10.4 Port-Pins ................................................................................................................. 46 11 Literatur .......................................................................................................................... 46 __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit -2- 1 1.1 Installation der Software Treiber installieren Setup_JLinkARM_V480g.exe Um die virtuelle serielle Schnittstelle nutzen zu können, muss folgende Einstellung bei der Installation vorgenommen werden: Abbildung: virtuelle serielle Schnittstelle mit installieren Falls folgendes Fenster erscheint, NICHTS AUSWÄHLEN!! Abbildung: Die evtl. schon installierten Treiber dürfen nicht ersetzt werden Die Treiber sind nun erfolgreich installiert. __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit -3- 1.2 Keil uVision installieren MDK473.exe Es wird empfohlen, den Voreinstellungen zu folgen. Während der Installation wird gefragt, ob Beispielprojekte zur Projektliste hinzugefügt werden sollen. Hier sollte der Haken auf jeden Fall nicht gesetzt werden. Abbildung: Keine Beispielprojekte zur Projektliste hinzufügen Die Software steht jetzt zur Verfügung und kann genutzt werden. __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit -4- 2 Das XMC 2Go Mikrocontroller Evaluation Kit Prozessoren werden nicht nur in PCs, Laptops und Netbooks eingesetzt sondern auch in sehr vielen Geräten und Systemen, deren vordergründige Aufgabe nicht die Verarbeitung von Daten, sondern die eigentliche Funktion des Gerätes ist (z.B. Ausgabe von Getränken am Getränkeautomat, Drucken von Fahrkarten am Fahrkartenautomat). Diese Geräte sind für eine bestimmte Aufgabe konzipiert und erfüllen nur diese (im Gegensatz dazu können beispielsweise Computer für vielfältige Tätigkeiten eingesetzt werden). Prozessoren für diese Art der Anwendung werden Mikrocontroller (µC) genannt. Das zur Funktion nötige System (die Leiterplatte mit den erforderlichen Bauteilen) wird als eigenständiges System betrachtet, dass in ein Gerät integriert (eingebettet, engl. „embedded“) wird. Um die Funktionsweise und die Handhabung eines Mikrocontrollers zu erlernen, werden Testumgebungen (Evaluation Kits) verwendet. Beim XMC 2Go handelt es sich um eine solche Testumgebung. Der Kurs basiert auf dem Evaluation Kit der Firma infineon, das durch wenige Bauelemente ergänzt wurde. Ein Drucktaster, ein Reed-Sensor und ein Piezo-Schallwandler (Lautsprecher) ermöglichen die Umsetzung eigener kreativer Ideen. Der verwendete µC XMC110 verfügt über einen Cortex-M0-Controllerkern mit 8 kbytes boot ROM, 16 kbytes high-speed SRAM (enthält die Variablen) und 200 kbytes Flash program and data memory (enthält das Programm). Das USB-Interface versorgt das Board mit der benötigten Betriebsspannung, dient zum Programmieren und Debuggen der programmierten Software und stellt eine virtuelle Kommunikationsschnittstelle (COM-Port) bereit. Im Folgenden werden die Funktionen und die Programmierung des XMC 2Go erklärt. Abbildung : XMC 2Go mit weiterem Bedienelement Abbildung: Ausgabe über die Kommunikationsschnittstelle __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit -5- 2.1 Funktionen des XMC 2Go 2.2 Die Laborumgebung Am Laborarbeitsplatz erwartet Sie ein PC unter Windows und ein XMC 2Go, welches per USB-Kabel mit dem PC verbunden ist. PC USB-Kabel Abbildung: Aufbau des Laborarbeitsplatzes (schematisch) 3 Die Entwicklungsumgebung (IDE) Die IDE (engl.: „Integrated Development Environment“) „integriert“ alle Tools, die zur Programmierung des Boards benötigt werden (Compiler, Debugger, Flasher, …), in einem Programm (in unserem Fall Keil µVision 4). Sie steht als Demoversion zur Verfügung und kann somit auf jedem beliebigen PC installiert werden. Eingeschränkt ist lediglich die Größe des ausführbaren Programms (32kB) und die kommerzielle Verwendbarkeit. Die Software µVision4 für ARM kann bei Keil direkt heruntergeladen werden. https://www.keil.com/ 3.1 Die Entwicklungsumgebung Keil uVision4 Das Programm kann direkt gestartet werden (danach das gewünschte Projekt manuell über Project\Open Project öffnen) oder es wird im entsprechenden Ordner ein Doppelklick auf das Projektfile ausgeführt XXName.uvproj . __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit -6- 3.2 Die Ordnerstruktur Abbildung : Ordnerstruktur In einem Ordner NWT_2Go befinden sich alle benötigten Ordner und Dateien. Die Inhalte der Ordner, die mit einem _ (Underscore) beginnen, sind Systemordner, sie enthalten Dokumente und vorgegebene Dateien, die unbedingt zum Betrieb nötig sind. Sie dürfen nicht geändert werden. _Anleitung Hier finden Sie unter anderem dieses Dokument. _Documents Alle wichtigen Dokumente sind selbstverständlich auch online verfügbar, hier allerdings befinden sie sich in einem Ordner. Wie sicherlich bekannt ist werden alle Dokumente zum Cortex M0 von ARM veröffentlicht, die Dokumente zu dem verwendeten µC und zu dem XMC 2Go Evaluation Kit finden sich auf der Homepage des Hersteller infineon. _Driver _Module Es wird zwischen Treibern und Modulen unterschieden. Treiber stellen die Funktionalität der benötigten Peripherieeinheiten zur Verfügung. Darüber hinausgehende Funktionen zur Nutzung finden sich im entsprechenden Modul. NWT_2Go_Blinky NWT_2Go_Blinky ist das „Hello World“ der embedded Softwareentwickler. Da nicht immer ein Display zur Ausgabe bereit steht, aber in der Regel eine LED auf den Boards verbaut ist, ist die blinkende LED immer als Beispiel verfügbar. Im Laufe der Zeit wird sich der Ordner NWT_2Go mit weiteren Projektordnern füllen. Selbstverständlich kann auch das Projekt NWT_2Go_Blinky kopiert und weiterentwickelt werden. __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit -7- 3.3 Keil µVision mit NWT_2Go_Blinky testen Im Ordner NWT_2Go_Blinky befindet sich die Datei NWT_2Go.uvproj. Nach einem Doppelklick öffnet sich die Entwicklungsumgebung. Abbildung: Die Entwicklungsumgebung 1. Schritt Translate (Strg+F7) Die aktuelle Datei wird übersetzt (compiliert) und auf Fehler überprüft. Die aktuelle µVision Version verfügt aber auch über Dynamic Syntax Checking, d.h. die Fehler werden bereits beim Eingeben markiert. Die Markierung verschwindet, sobald die Zeile fertig geschrieben oder die Fehler korrigiert wurden. 2. Schritt Build (F7) Die zum Projekt gehörenden Dateien werden zu einem auf dem µC ausführbaren Programm zusammengefasst. 3. Schritt Download Das ausführbare Programm wird auf das XMC 2Go Board übertragen und gestartet. Bei den gewählten Einstellungen zum Übertragen in den internen Speicher des XMC 2Go startet das Programm nach der Übertragung automatisch. __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit -8- 3.4 Ausgaben der Kommunikationsschnittstelle anzeigen Die Kommunikationsschnittstelle, häufig UART (engl.: „Universal Asynchronous Receiver Transmitter“, Aussprache: ju art) genannt, dient zum Senden und Empfangen von Daten. Der Mikrocontroller benötigt hierfür allerdings nur einen Eingang und einen Ausgang sowie einen gemeinsamen Masseanschluss (GND). In der Regel werden 8 Bit Nutzdaten übertragen, die von 2-4 weiteren Bits eingerahmt werden. Die über den UART des Mikrocontrollers gesendeten Daten werden nun „Huckepack“ über die USBSchnittstelle übertragen. In unserem Fall beträgt die Geschwindigkeit 115200 Baud. Auf dem PC wird nun ein Programm benötigt, das die empfangenen Daten anzeigt. Hierzu verwenden wir NWT_2Go_Kommunikation.exe (im Ordner _Tools). Die Software ist nur zu Schulungszwecken gedacht. Abbildung: Kommunikationsschnittstelle Als erstes muss der COM-Port ausgewählt werden. Ein Klick auf „Kommunikationsschnittstelle suchen“ listet alle verfügbaren Ports auf. In der Regel werden nur ein oder zwei COM-Ports angezeigt. COM1 ist immer der im PC eingebaute COM-Port, der andere in der Regel der Port, der zum Board gehört. Falls mehr Ports angezeigt werden, einfach ausprobieren (COM-Port in der Liste auswählen und auf „Kommunikationsschnittstelle öffnen“ klicken), bis Ausgaben erscheinen. Ein Klick auf „Kommunikationsschnittstelle schließen“ bzw. auf „Beenden“ beendet die Ausgabe. Die empfangenen Daten können in zur späteren Auswertung in eine Textdatei geschrieben werden. Nach einem Klick auf „Werte loggen“ wird eine Textdatei erstellt, in die die Ausgabe der Kommunikationsschnittstelle geschrieben wird (dazu muss sie natürlich geöffnet sein). „Log beenden“ beendet den Vorgang und gibt die Datei zur weiteren Verwendung frei. Die Textdatei wird in der Reihenfolge des Empfangs gefüllt (umgekehrt zur Liste). Wir nur Integerwert pro Zeile gesendet, so können die empfangenen Werte auch gleich grafisch (Plot starten) dargestellt werden. Befehel um Werte grafisch darstellen zu können: UART_SendInt(ui32Wert); UART_Send_ENDL(); __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit -9- 3.4.1 Textdateien mit Excel verarbeiten Textdateien können zur Auswertung in Excel importiert werden. Nach einem Klick auf „Datei“ -> „Öffnen“ erscheint der „Öffnen“-Dialog. Standardmäßig werden nur Excel-Dateien angezeigt. Um Textdateien auszuwählen, muss die entsprechende Einstellung in der Auswahlliste rechts unten gemacht werden („Alle Dateien“ oder „Textdateien“). Nach einem Klick auf „Öffnen“ erscheint der Textkonvertierungs-Assistent. Hier muss in der Gruppe „Ursprünglicher Datentyp“ die Option „Feste Breite“ ausgewählt werden. In diesem Format stellt jede Textzeile eine Tabellenzeile dar. Die Spalten werden mit Leerzeichen getrennt. Mit „Fertig stellen“ werden die Daten importiert. Um ein Diagramm zu erstellen wählen Sie nun die Spalte aus, in der sich die Daten befinden (in der Regel „A“). Wählen Sie unter „Einfügen“ in der Gruppe „Diagramme“ den Diagrammtyp aus (typischerweise „Linie“ oder „Punkt“). Excel zeichnet nun ein Diagramm mit Ihren Daten. Um die Beschriftung zu ändern klicken Sie unter „Diagrammtools“ / „Entwurf“ auf „Daten auswählen“. Wählen Sie nun den obersten Eintrag der linken Liste (in der Regel „Datenreihe 1“) aus und klicken Sie auf „Bearbeiten“. Tragen Sie unter „Reihenname“ die gewünschte Bezeichnung ein und klicken Sie zweimal auf „OK“. Verwenden Sie „Datei“ -> „Speichern unter“ um die Arbeitsmappe samt Diagramm zu speichern. Abbildung: Import von Textdateien Abbildung: Textkonvertierungs-Assistent __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 10 - Abbildung: Fertiges Diagramm 3.5 NWT_2Go_Vorlage Es liegt auch ein Projekt mit dem Namen NWT_2Go_Vorlage bereit. Die Projektdatei heißt NWT_2GO.uvproj. Dieses Projekt eignet sich gut als Kopiervorlage für neue Projekte. 3.6 Projekt säubern Der translate- und build-Vorgang erzeugt viele Daten. Diese können vor einem Kopiervorgang aus dem Projekt entfernt werden durch den Aufruf von Project\Clean target. Abbildung: Unnötige Dateien aus Projekt entfernen 3.7 Projekt kopieren Es ist sinnvoll, die Entwicklung von Softwareprojekten (dazu gehören auch Übungen und Laboraufgaben) in Teilaufgaben zu unterteilen. Die Realisierung einer neuen Teilaufgabe sollte mit einer neuen Versionsnummer im Projekt begonnen werden. Zum Beispiel blinkt in der ersten Version V1 eine LED. In dem weiterentwickelten Projekt sollen nun zwei LEDs blinken. Hier wäre nun eine neue Version V2 sinnvoll. Die bereits lauffähige Version V1 muss nun VOR der weiteren Bearbeitung kopiert werden (ansonsten wird die alte Version überschrieben). Hierzu sollte ein Clean target ausgeführt und dann die IDE geschlossen werden. Nun kann der Projekt Ordner kopiert werden. Es wird üblicherweise eine Versionsnummer angehängt _V2 (Auf keinen Fall Leerzeichen in den Namen für Ordner oder Dateien verwenden!!). __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 11 - Abbildung: Kopierter Projektordner In dem Ordner NWT_2Go_Blinky_V2 kann nun wieder die Datei NWT_2Go.uvproj geöffnet werden. Es reicht aus, den Namen des Ordners zu ändern, der Name der Projektdatei kann beibehalten werden. Im Kopf der Datei, die die main() Funktion enthält, sollten nun aber Ergänzungen für die Version V2 hinzugefügt werden. /******************************************************************************* * Projektname: NWT_2Go_Blinky_V2 * Prozessor: Infineon XMC1100 * Funktion: Blinky * Erstellungsdatum: 5.3.2014 * Bearbeiter: Joachim Hampel * History: V1 LED1 blinkt * V2 LED 1 und 2 blinken *******************************************************************************/ Gelegentlich ist es nötig, Änderungen innerhalb eines Projekteteils zu sichern, oder es werden bei bereits lauffähigen Softwareteilen Verbesserungen vorgenommen. Hier ist es üblich z.B. auf eine Version 2.1 zu kopieren also hier z.B. Mein_Blinky_V2_1 Projekte sollten sorgfältig verwaltet werden! __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 12 - Elemente der Programmiersprache 4 4.1 Variablen Die von einem Programm verwendeten Daten müssen im Speicher (RAM) des Mikrocontrollers abgelegt werden. Der Speicher ist in Byte eingeteilt. Jede Speicherstelle (Byte) erhält eine eigene aufsteigende Adresse. In der Antike des Programmierens konnte nur über die Adresse (absolute Adressierung) auf den Speicher zugegriffen werden. Moderne Programmiersprachen stellen Datentypen zur Verfügung, mit deren Hilfe Variablen angelegt werden können. Variablen erleichtern den Zugriff auf den Speicher erheblich. Je nach Daten- und Prozessortyp belegen die Variablen unterschiedlich viel Platz im Speicher. Datentyp char int8_t uint8_t int16_t uint16_t int32_t uint32_t float Kennung c i8 ui8 i16 ui16 i32 ui32 f Größe 1 Byte 1 Byte 1 Byte 2 Byte 2 Byte 4 Byte 4 Byte 4 Byte double d 8 Byte Beschreibung Zeichen Zahlenwerte -128 bis 127 Zahlenwerte 0 bis 255 -32768 bis 32767 0 bis 65535 -2^31 bis 2^31-1 0 bis 2^32-1 Kommazahlen sehr rechenintensiv Kommazahlen extrem rechenintensiv Um eine Variable verwenden zu können, muss diese zunächst „eingeführt“ (deklariert) werden. Die Deklaration jeglicher Variablen besteht aus Datentyp und Variablennamen. Sie muss an erster Stelle im Programmcode stehen. Bei Variablennamen muss auf Groß-/Kleinschreibung geachtet werden! uint8_t i8MeineVariable; //Deklaration der Variablen i8MeineVariable uint8_t i8meinevariable; //Deklaration einer anderen(!) Variablen int8_t i8Zahl1,i8Zahl2; //Deklaration mehrerer Variablen gleichen Typs Es ist üblich, Variablennamen mit einer Kennung zu beginnen. Der eigentliche Name wird groß geschrieben. Typ: char uint8_t float Name: cBuchstabe; ui8Wert; fZahl; TIP Schlüsselworte Die folgenden Schlüsselworte dürfen nicht als Variablennamen verwendet werden, da sie für die Programmierung reserviert sind: asm, auto, break, case, char, const, continue, default, do, double, else, enum, extern, float, for, goto, if, int, long, register, return, short, signed, sizeof, static, struct, switch, typedef, union, unsigned, void, volatile, while Variablen können Werte zugewiesen werden. Dies kann an jeder Stelle im Programmcode geschehen. cBuchstabe = ‘a‘; //Zuweisung eines Zeichens ui8Wert = 12; i8MeineVariable = 10; fZahl = 0.123; //Kommazahlen werden mit einem Punkt dargestellt ui8Wert = i8MeineVariable; //ui8Wert hat jetzt den Wert 10 __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 13 - Variablen mit dem Datentyp char enthalten ein einzelnes Zeichen. Zeichen werden mit einfachen Anführungszeichen ausgedrückt (z.B. ‘a‘). Ein Text besteht aus mehreren Zeichen (Zeichenkette). In der Informatik bezeichnet man Zeichenketten als „Strings“. Die Datentypen Float und Double können Kommazahlen darstellen. Man sollte aber immer im Hinterkopf behalten, dass bei begrenztem Speicherplatz auch die Genauigkeit begrenzt ist. Für einen Float Wert werden 32 Bit verwendet: 1 Bit für das Vorzeichen, 8 Bit für den Exponenten zur Basis 2 und 23 Bit für die Mantisse (ebenfalls zur Basis 2). Insgesamt kann also eine Zahl mit 7 Stellen gespeichert werden. Die Platzierung des Kommas wird durch den Exponenten bestimmt. Für einen Double Wert werden 64 Bit verwendet. Eine Variable vom Datentyp Double ist also genauer, aber auch deutlich rechenintensiver. Umso größer die Zahl deshalb vor dem Komma wird, desto kleiner wird die Genauigkeit hinter dem Komma. Im Extremfall kann sich dies sogar auf Stellen vor dem Komma auswirken. Neben der Rechenintensivität ist dies ein weiterer Grund, möglichst auf Float und Double zu verzichten. Beispielsweise sollte ein Getränkeautomat lieber auf Cent- (150 ct) als auf Eurobasis (1,50 €) rechnen. Es ist möglich, den Wert einer Variablen einer anderen Variablen zuzuweisen. Dies gilt (eingeschränkt) auch für Variablen unterschiedlicher Datentypen. Allerdings sollte darauf geachtet werden, dass der Speicherbereich der Variablen nicht überschritten wird. Beispiel: int8_t i8Wert; int32_t i32Wert; i32Wert = 500; i8Wert = i32Wert; //int8_t geht max. bis 127 UART_SendInt(i32Wert); UART_Send_ENDL(); UART_SendInt(i8Wert); UART_Send_ENDL(); Ausgabe des Programms: 500 -12 4.1.1 Arrays Arrays sind eine Sonderform der Variablen. Sie stellen eine Liste mit Werten gleichen Datentyps dar. Genau wie „normale“ Variablen müssen sie vor der Verwendung deklariert werden. Dabei muss die Länge der Liste festgelegt werden. int8_t i8Array[10]; //Array vom Datentyp int8_t der Laenge 10 Alternativ kann der Inhalt der Liste direkt bei der Deklaration angegeben werden. In diesem Fall muss die komplette Liste angegeben werden! Die Länge des Arrays wird automatisch ermittelt. int8_t i8Fibonacci[] = {0, 1, 1, 2, 3, 5, 8}; //Array der Laenge 7 Nachdem das Array deklariert wurde, kann seine Länge nicht mehr verändert werden. Auf die einzelnen Elemente wird über deren Index zugegriffen. Der Index ist nullbasiert, d.h. das erste Element hat den Index 0. i8Element = i8Fibonacci[3]; //i8Element hat jetzt den Wert 2 i8Fibonacci[0] = 24; //Das erste Element hat jetzt den Wert 24 Eine Sonderform der Arrays sind Strings (Zeichenketten). Es handelt sich dabei um eine Liste von Zeichen (Chars). Ein String wird folgendermaßen angelegt: char cMeinText[] = “Hello World“; __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 14 - 4.2 Anweisungen Der Mikrocontroller erhält durch die Programmierung Aufgaben, die er durchführen soll. Die einzelnen Vorgänge nennt man Anweisungen. Anweisungen werden mit einem Semikolon abgeschlossen. ui8Wert=0; //Highscore zurücksetzen TIP Kommentare mit // beginnt ein einzeiliger Kommentar mit /* und */ kann man einen ganzen Block auskommentieren Kommentare werden vom Compiler ignoriert. Sie tragen zu einer besseren Verständlichkeit bei. Jeder Prozessor benötigt ständig Anweisungen. 4.3 Anweisungsblock Anweisungen können zu einem Block zusammengefasst werden. Ein Anweisungsblock beginnt mit einer geschweiften Klammer und endet auch mit einer solchen. Innerhalb eines Anweisungsblocks definierte Variablen verlieren am Blockende ihre Gültigkeit. { Uint8_t ui8Wert1, ui8Wert2, ui8Summe, ui8Produkt; ui8Wert1=5; ui8Wert2=10; ui8Summe = ui8Wert1 + ui8Wert2; ui8Produkt = ui8Wert1 * ui8Wert2; } 4.4 Funktionen In Funktionen werden Anweisungen zusammengefasst, die aus einem anderen Programmteil aufgerufen werden können. Funktionen geben entweder einen Wert oder void (also nichts) zurück. Einer Funktion können Parameter übergeben werden. Es gibt aber auch Funktionen, die keine Übergabeparameter benötigen. Der tatsächlich übergebene Wert wird Argument genannt. Der mit der Anweisung return zurückgegebene Wert wird Rückgabewert genannt. Eine Funktion setzt sich folgendermaßen zusammen: [Rückgabedatentyp] Name([Datentyp] [Parameter], …) { //Anweisungen } Beispiel: uint8_t Summe(uint8_t ui8Eingabe1, uint8_t ui8Eingabe2) { uint8_t ui8Erg; ui8Erg = ui8Eingabe1 + ui8Eingabe2; return ui8Erg; } Falls eine Funktion keine Parameter benötigt, kann in den () auch das Schlüsselwort „void“ stehen. Bevor diese Funktion benutzt werden kann, muss sie bekannt gemacht werden. Man spricht von einem Prototyp. Es handelt sich dabei einfach um den Funktionskopf. __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 15 - Beispiel: uint8_t Summe(uint8_t ui8Eingabe1, uint8_t ui8Eingabe2); //Semikolon! Der Prototyp darf nicht in einer Funktion stehen! Am besten ganz an den Anfang der Datei, die die Funktion enthält, setzen. Nun kann die Funktion verwendet werden: uint8_t i8EinsPlusVier = Summe(1, 4); //i8EinsPlusVier hat den Wert 5 Bei Funktionennamen muss (wie bei Variablennamen) auf Groß-/Kleinschreibung geachtet werden. 4.5 Die main Funktion Die Funktion main() stellt einen Sonderfall dar, da diese Funktion beim Programmstart aufgerufen wird. Das ist eine Konvention, die im Mikrocontroller eingespeichert worden ist. Bei anderen Prozessoren kann es sich um eine andere Funktion/Schreibweise handeln. Jedes Programm muss eine main() Funktion enthalten. Jeder Prozessor muss immer eine sinnvolle Anweisung nach der anderen Ausführen. Da unser XMC 2Go Board nicht über ein ständig laufendes Betriebssystem verfügt, wird dies durch eine „Endlosschleife“ realisiert werden. #include "init.h" uint8_t Summe(uint8_t ui8Eingabe1, uint8_t ui8Eingabe2); int main(void) { //----------------------------//Variablen //----------------------------uint8_t ui8Wert1, ui8Wert2, ui8Summe; //----------------------------//Einmalige Anweisungen //----------------------------//Grundeinstellungen vornehmen Board_Init(); //Variablen initialsieren ui8Wert1=5; ui8Wert2=10; ui8Summe = Summe(ui8Wert1, ui8Wert2); //Sonstige einmalige Anweisungen UART_SendText("**** Rechentest ****\r\n"); UART_SendText("Summe = "); UART_SendInt(ui8Summe); UART_Send_ENDL(); //----------------------------//Endlosschleife "magic loop" //----------------------------while(1) { } } uint8_t Summe(uint8_t ui8Eingabe1, uint8_t ui8Eingabe2) { uint8_t ui8Erg; ui8Erg = ui8Eingabe1 + ui8Eingabe2; return ui8Erg; } __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 16 - 4.6 Mathematische Operatoren 4.6.1 Grundrechenarten Die beschrieben Operationen werden hier auf Ganzzahlen angewandt, da es sich hierbei um die schnell ausführbaren Rechenoperationen handelt. Zahlen, die fest im Programm verwendet werden, bezeichnet man als Konstanten. 8 8.0 Integer (Ganzzahl) Konstante Float (Gleitkommazahl) Konstante + * / % = Addition Subtraktion Multiplikation Division Modulo (Rest) Zuweisungsoperator 2+3=5 7–3=4 9 * 3 = 27 10/ 3 = 3 (nicht gerundet) 10 % 3 = 1 Es gelten die mathematischen Vorrang- und Komma-Regeln. Achtung beim Rechnen mit ganzen Zahlen! Sind nur Ganzzahlen an einer Division beteiligt, wird diese als Ganzzahldivision ausgeführt. Möchte man bei einer Division von zwei Ganzzahlen dennoch eine Kommazahl als Ergebnis erhalten, muss mindestens eine der beiden Ganzzahlen in eine Kommazahl konvertiert werden. Beispiel: 95 / 10 = 9,5 Da hier für den Mikrocontroller aber eine Ganzzahldivision vorliegt, wird 9 als Ergebnis zurückgegeben. Die Nachkommastellen werden „abgeschnitten“, d.h. es wird nicht gerundet. //Variablen uint8_t ui8Wert, ui8Erg, ui8Rest; //Grundeinstellungen ... //Variablen mit Startwerten initialisieren ui8Wert=95; //Weitere einmalige Anweisungen ui8Erg=ui8Wert/10; ui8Rest=ui8Wert%10; UART_SendInt(ui8Wert); UART_SendText(“ / ”); UART_SendInt(10); UART_SendText(“ = ”); UART_SendInt(ui8Erg); UART_SendText(" Rest: "); UART_SendInt(ui8Rest); UART_Send_ENDL(); 95 / 10 = 9 Rest: 5 Ausgabe __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 17 - 4.6.2 Inkrementieren und Dekrementieren i1++ i1-i1 += 2; i1-=2; i1=i1+1; i1=i1-1; i1=i1+2; i1=i1-2; Inkrementierung um 1 Dekrementierung um 1 Inkrementierung um 2 Dekrementierung um 2 Präfix: i1=1; i2=++i1; i1 wird um 1 erhöht und dann i2 zugewiesen i2=2 i1=2 Postfix: i1=1; i2=i1++; i1 wird i2 zugewiesen und dann erhöht i2=1 i1=2 Übung: Legen Sie eine Variable von Typ uint8_t an, erhöhen Sie den Wert bei jedem Schleifendurchlauf um 1 und geben Sie ihn auf den LEDs aus. TIP: Verzögerung nicht vergessen! Übung: Legen Sie eine Variable von Typ uint8_t mit dem Startwert 1 an, multiplizieren Sie bei jedem Schleifendurchlauf die Variable mit dem Faktor 2 und geben sie die Variable auf den LEDs aus. Ihre Beobachtung: 4.6.3 Vergleichsoperatoren Das Ergebnis einer Vergleichsoperation ist wahr (TRUE oder jede beliebige Zahl, die nicht 0 ist) oder falsch (FALSE oder 0). Jeder Ausdruck lässt sich als Wahrheitswert auswerten. Nur Ausdrücke, die numerisch 0 sind, werden als FALSE bewertet. Alle anderen Werte gelten als TRUE (z.B. auch –5). Operator Gleich Symbol == Ungleich != Größer als > Größer oder gleich >= Kleiner < Kleiner oder gleich <= 4.7 4.7.1 Beispiel 100==50 50==50 100!=0 50!=50 100>50 50>100 100>=50 50>=50 100<50 50<100 100<=50 50<=50 Rückgabewert FALSE TRUE TRUE FALSE TRUE FALSE TRUE TRUE FALSE TRUE FALSE TRUE Programmverzweigungen Die if-Anweisung Mit der if-Anweisung kann eine Bedingung überprüft werden, um im Programm zu unterschiedlichen Teilen des Codes zu verzweigen. If-Anweisungen können verschachtelt werden. If ( [Bedingung] ) Der in { } gesetzte Anweisungsblock wird ausgeführt, wenn die Bedingung erfüllt, also wahr (TRUE) ist. __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 18 - else Der in { } gesetzte Anweisungsblock wird ausgeführt, wenn die obere Bedingung nicht erfüllt, also falsch (FALSE) ist. Der else Zweig kann auch weggelassen werden, wenn er nicht erforderlich ist. Beispiel: Der Taster wird überprüft. Ist er gedrückt, wird eine LED angeschaltet, sonst wird sie ausgeschaltet. //Endlosschleife while(1) { if(SWITCH_READ()==1) { LED1_ON(); } else { LED1_OFF(); } } Soll jeweils nur eine Anweisung nach einer if- oder else-Verzweigung ausgeführt werden, so kann auf die Klammern { } verzichtet werden. Dieser Programmierstil sollte aber nur mit entsprechend viel Programmiererfahrung verwendet werden, da er viele Risiken birgt. while(1) { if(SWITCH_READ()==1) LED1_ON(); else LED1_OFF(); } In diesem Fall muss kein Vergleich durchgeführt werden, da der Wert 1 sowieso TRUE entspricht. Dies bedeutet aber in der Praxis nur weniger Schreibarbeit. Der entstandene ausführbare Code bleibt gleich groß. Auch hier sollte man mit besonderer Vorsicht zu Werke gehen. while(1) { if(SWITCH_READ()) //Vergleich nicht notwendig LED1_ON(); else LED1_OFF(); } __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 19 - 4.7.2 Die switch-Anweisung Mit einer switch Anweisung kann eine Variable ausgewertet werden. Dabei lassen sich beliebig viele Verzweigungen in Abhängigkeit ihres Werts aufbauen. switch(Variable) case Wert: break; default: Definiert die zu prüfende Variable Vergleicht den Ausdruck mit dem Wert und führt die darauf folgenden Anweisungen durch (Doppelpunkt nicht vergessen!) Beendet die switch Anweisung. Muss unbedingt in jedem case-Zweig eingesetzt werden. Gilt für alle bisher nicht ausgewerteten Fälle (Doppelpunkt nicht vergessen!) Beispiel: ui8Wert wird ausgewertet. Zu Beginn ist der Wert noch 0. Da kein case Wert zutrifft wird vor dem ersten Tastendruck immer die Zeichenkette “------“ gesendet. Später wird entsprechend dem Wert die jeweilige Zeichenkette gesendet. ui8Wert=0; while(1) { if((SWITCH_READ()==1) && ui8Wert<5) { LED1_ON(); ui8Wert++; UART_SendInt(ui8Wert); UART_Send_ENDL(); SWITCH_WAIT_OPEN(); LED1_OFF(); } switch(ui8Wert) { case 1: UART_SendText("1"); break; case 2: UART_SendText("22"); break; case 3: UART_SendText("333"); break; case 4: UART_SendText("4444"); break; case 5: UART_SendText("55555"); break; default: UART_SendText("------"); break; } UART_Send_ENDL(); } Bei der switch-Anweisung handelt es sich lediglich um eine Kurzform der if-Anweisung. Dieselbe Funktionalität könnte selbstverständlich auch mit einer if-Anweisung realisiert werden. __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 20 - 4.8 Schleifen Viele Programmieraufgaben lassen sich durch wiederholte Ausführung eines Programmteiles lösen. Es wird zwischen kopf- und fußgesteuerten Schleifen (Wiederholungen) unterschieden. 4.8.1 Kopfgesteuerte Schleifen Die Bedingung wird zu Beginn der Schleife geprüft. 4.8.2 while – Schleife Die while-Schleife wird also solange wiederholt, wie die Bedingung wahr (TRUE) bleibt. Ist die Bedingung von Anfang an FALSE, so werden die Anweisungen in der while-Schleife nicht ausgeführt (die Schleife wird gar nicht betreten). while(Bedingung) { //Anweisungen } Beispiel: Die while Schleife wird betreten, wenn der Taster gedrückt wird. Sie wird solange wiederholt, bis der Taster wieder losgelassen wird. Durch die while(1) Schleife wird der Vorgang ständig wiederholt, denn der Wert 1 steht, wie weiter oben bereits ausgeführt, für „TRUE“. //Endlosschleife while(1) { while(SWITCH_READ()==1) { LED1_ON(); } LED1_OFF(); } Übung: Realisieren Sie einen Würfel. Tip: Die Zufallszahl kann durch die Dauer des Drucks des Tasters erzeugt werden. Während er gedrückt ist, wird eine Variable hochgezählt. uint8_t ui8Wurf=0; ... while( SWITCH_READ()==1 ) { ui8Wurf++; //ToDo ... } //Ausgabe ... Erweitern Sie ihren Würfel um eine Statistikfunktion, die mitzählt, wie oft welcher Wert gewürfelt wurde. __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 21 - Beispiel: Häufig wird in einer Schleife von einem Startwert herunter gezählt. Der Startwert wird hier mit dem Taster (SWITCH) durch hochzählen eingestellt. Da die LED1 für einen Blinkvorgang zwei Mal umgeschaltet werden muss, ist es nötig, den eingestellten Wert mit zwei zu multiplizieren und von diesem Startwert aus herunter zu zählen. while(1) { SWITCH_WAIT_PRESSED(); //auf Tastendruck warten ui8Wert=0; while( SWITCH_READ() == 1 ) //Wert hochzaehlen { ui8Wert++; UART_SendInt(ui8Wert); UART_Send_ENDL(); WAIT_mS(1000); } ui32Count=ui8Wert*2; while(ui32Count>0) { LED1_TOGGLE(); ui32Count--; WAIT_mS(500); } //1x Blinken benoetigt //2 Schleifendurchlaeufe } 4.8.3 for - Schleife Die for-Schleife ist eine Sonderform der kopfgesteuerten Schleife. Die Kopfzeile fasst die drei Schritte Wertzuweisung, Test und Veränderung der Variable in einer Anweisung zusammen. Die verwendete Zählervariable muss, wie jede andere Variable, zuvor deklariert worden sein. for(Startzustand; Bedingung; Veraenderung) { Anweisungen } Beispiel: Hier wird die gleiche Funktion mit einer for-Schleife realisiert. while(1) { SWITCH_WAIT_PRESSED(); ui8Wert=0; while( SWITCH_READ() == 1 ) { ui8Wert++; UART_SendInt(ui8Wert); UART_Send_ENDL(); WAIT_mS(1000); } for(ui32Count=ui8Wert*2;ui32Count>0;ui32Count--) { LED1_TOGGLE(); WAIT_mS(500); } } __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 22 - 4.8.4 Fußgesteuerte Schleifen Bei der while-Schleife kann es vorkommen, dass die Schleife nicht ausgeführt wird, da die Bedingung zu Beginn der Schleife geprüft wird. Die do...while-Schleife wird in jedem Fall mindestens einmal ausgeführt. Vor der Wiederholung wird die Bedingung geprüft. Wenn diese wahr ist, wird die Schleife wiederholt. Die Bedingung wird also am Ende der Schleife überprüft. 4.8.5 do while - Schleife do { Anweisungen } while (Bedingung); //Semikolon nicht vergessen! Beispiel: while(1) { SWITCH_WAIT_PRESSED(); //Warten bis Taster gedr. wird do { UART_SendInt(ui8Wert++); UART_Send_ENDL(); WAIT_mS(1000); }while(SWITCH_READ()==1); //Wiederholen solange Taster gedr. } 4.8.6 Schlüsselworte in Schleifen break; Die Schleife wird sofort verlassen und das Programm wird nach der Schleife weiter ausgeführt. continue; //Sprung zurück zum Beginn der Schleife Beispiel 1 (break): int8_t i8Zaehler = 0; UART_SendText(„Start\r\n“); while(i8Zaehler < 10) { i8Zaehler++; if(i8Zaehler == 5) break; UART_SendInt(i8Zaehler); UART_Send_ENDL(); } UART_SendText(„Ende\r\n“); Programmausgabe: Start 1 2 3 4 Ende __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 23 - Beispiel 2 (continue): int8_t i8Zaehler = 0; UART_SendText(„Start\r\n“); while(i8Zaehler < 10) { i8Zaehler++; if(i8Zaehler == 5) continue; UART_SendInt(i8Zaehler); UART_Send_ENDL(); } UART_SendText(„Ende\r\n“); Programmausgabe: Start 1 2 3 4 6 7 8 9 10 Ende __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 24 - Spezielle Funktionen für das XMC 2Go Board 5 Selbstverständlich ist es möglich, die komplexen Funktionen eines Mikrocontrollers direkt in eigenen Programmen zu verwenden. Dies ist jedoch sehr aufwendig. Deshalb werden sehr häufig Module verwendet, die durch Funktionen einen einfachen Zugriff ermöglichen. Für das XMC 2Go Board stehen mehrere Module zur Verfügung. Ein Modul besteht immer aus zwei Dateien: eine Headerdatei mit der Endung .h, die Definitionen und Prototypen enthält, sowie eine Datei mit der Endung .c, die den Quellcode, also die eigentlichen Funktionen enthält. Die Headerdatei wird mit #include eingebunden. 5.1 Kommunikationsschnittstelle Es stehen Funktionen zur Verfügung, um Zahlen oder Text über die Kommunikationsschnittstelle zu übertragen. UART_SendText( Text ); UART_SendInt( Ganzzahl ); UART_SendFloat( Kommazahl); UART_Send_ENDL(); 5.1.1 Ganze Zahlen (Integer) Werte senden Mit der Funktion UART_SendInt( Wert ) können ganze Zahlen ausgegeben werden. UART_SendInt( Wert ); Beispiel: int main(void) { //Variablen int32_t i32Wert1, i32Wert2, i32Erg; //Einmalige Anweisungen //Grundeinstellungen vornehmen Board_Init(); //Variablen initialisieren i32Wert1=978; i32Wert2=-10; //Weiter einmalige Anweisungen UART_SendText("Ausgabe ganzer Zahlen\r\n"); i32Erg=i32Wert1 + i32Wert2; UART_SendInt(i32Erg); UART_Send_ENDL(); i32Erg=i32Wert1 * i32Wert2; UART_SendInt(i32Erg); UART_Send_ENDL(); //----------------------------//Endlosschleife "magic loop" //----------------------------while(1) { } } Ausgabe: Ausgabe ganzer Zahlen 968 -9780 __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 25 - 5.1.2 Kommazahlen (Float Werte) senden Mit der Funktion UART_SendFloat( Wert ) können Kommazahlen gesendet werden. Das folgende Beispiel verdeutlicht die Ungenauigkeit beim Rechnen mit Variablen vom Datentyp float: float fWert1, fWert2, fErg; ... fWert1=100000.0; //zur Darstellung wird immer ein Punkt verwendet fWert2=0.12345; fErg=fWert1+fWert2; UART_SendFloat(fWert1); UART_Send_ENDL(); UART_SendFloat(fWert2); UART_Send_ENDL(); UART_SendFloat(fErg); UART_Send_ENDL(); 100000.00000 0.12345 100000.12500 5.1.3 Gesendete Werte Zeichenketten senden Mit UART_SendText( Text ) können Strings (Zeichenketten) gesendet werden. UART_SendText(Text); Beispiel: //Variablen char sZeichenkette[]="Hallo Welt!"; //String Variable anlegen ... //Weiter einmalige Anweisungen UART_SendText(sZeichenkette); //Text aus einem Datenfeld UART_Send_ENDL(); UART_SendText("ABC-abc\r\n"); //Text direkt uebergeben Hallo Welt! ABC-abc 5.1.4 Gesendete Werte Eine neue Zeile beginnen Mit UART_Send_ENDL() kann ein Zeilenumbruch eingefügt werden. Ein Zeilenumbruch besteht aus einem Steuerzeichen für den Wagenrücklauf und einem Steuerzeichen für den Zeilenvorschub. Diese Zeichen können auch direkt an das Ende eines Strings angefügt werden. Weil sie aber nicht „druckbar“ sind (d.h. nicht angezeigt werden können), verwendet man zu ihrer Darstellung sogenannte „Escape“-Zeichen. Escape-Zeichen werden mit einem Rückstrick („Backslash“) codiert. Escape-Zeichen befinden sich innerhalb des Strings. Escape-Zeichen für Wagenrücklauf: Escape-Zeichen für Zeilenvorschub: ‘\r‘ ‘\n‘ Beispiel: UART_SendText(„Hallo Welt!“); UART_Send_ENDL(); UART_SendText(„Hallo Welt!\r\n“); //gleiche Ausgabe __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 26 - 5.2 XMC_2Go_NWT Modul Dieses Modul enthält alle benötigten Funktionen, um die LEDs und den Druckaster einsetzen zu können. LED1_ON(); LED1_OFF(); LED1_TOGGLE(); LED2_ON(); LED2_OFF(); LED2_TOGGLE(); SWITCH_READ(); SWITCH_WAIT_PRESSED( ); SWITCH_WAIT_OPEN( ); WAIT_uS( Wert ); WAIT_mS( Wert ); 5.2.1 LEDs verwenden Mit den folgenden Funktionen kann eine LED direkt eingeschaltet, ausgeschaltet oder umgeschaltet werden. LED1_ON( ) LED2_ON( ) Beispiel: LED 1 wird angeschaltet LED1_ON(); LED1_OFF( ) LED2_OFF( ) Beispiel: LED 2 wird ausgeschaltet LED2_OFF(); LED1_TOGGLE( ) LED2_TOGGLE( ) Beispiel: LED 1 wird in der Endlosschleife mit einer Verzögerung von 100mS ständig umgeschaltet. Sie blinkt also oder „togglet“. while(1) { LED1_TOGGLE1(); WAIT_mS(100); } __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 27 - 5.2.2 Drucktaster (Switch) auslesen Der Zustand des Drucktasters (Switch) kann mit der Funktion SWITCH_READ() ausgelesen werden. Der Rückgabewert ist entweder 0 (wenn der Taster nicht gedrückt ist) oder 1 (wenn der Taster gedrückt ist). SWITCH_READ(); Beispiel: Die LED blinkt nur, während der Taster gedrückt ist. while(1) { if( SWITCH_READ() == 1 ) { LED1_TOGGLE(); WAIT_mS(100); } } In bestimmten Situationen muss auch auf einen Tastendruck oder auf das Loslassen des Tasters gewartet werden. SWITCH_WAIT_PRESSED() wartet so lange, bis der Taster gedrückt wird. Ist der Taster beim Aufruf der Funktion schon gedrückt, so fährt das Programm mit der nächsten Anweisung fort. SWITCH_WAIT_OPEN() wartet so lange, bis der Taster nicht mehr gedrückt ist. Ist der Taster beim Aufruf der Funktion nicht gedrückt, so fährt das Programm mit der nächsten Anweisung fort. SWITCH_WAIT_PRESSED(); SWITCH_WAIT_OPEN(); Beispiel: Die LED wird umgeschaltet, wenn der Taster gedrückt wird. Die unten gezeigte Programmstruktur wird häufig verwendet. Es wird auf ein Ereignis gewartet. Wenn dieses Ereignis eingetreten ist, wird darauf reagiert. Allerdings muss nun noch darauf gewartet werden, dass dieser Zustand wieder aufgehoben wird, damit die LED nicht ständig umgeschaltet wird solange der Taster gedrückt ist. while(1) { if( SWITCH_READ() == 1) { LED1_TOGGLE(); SWITCH_WAIT_OPEN(); } } 5.2.3 Warten Da der Mikrocontroller sehr schnell arbeitet, kann es vorkommen, dass gewollt Zeit vergehen soll. Dafür kann eine der Warte-Funktionen verwendet werden. Da sich der Prozessor in einer Warteschleife befindet, kann er in dieser Zeit natürlich keine anderen Anweisungen durchführen. WAIT_uS ( Wert ) //Wartet angegebene Anzahl von Mikrosekunden WAIT_mS ( Wert ) //Wartet angegebene Anzahl von Millisekunden Beispiel: LED 1 blinkt 5x pro Sekunde while(1) { LED1_TOGGLE(); WAIT_mS(100); } //100mS __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 28 - 6 Port-Pins einsetzen Port-Pins können entweder als Eingänge oder Ausgänge verwendet werden. Im Folgenden wird erklärt wie die Pins konfiguriert werden müssen. Die Beispiele werden auf einem Steckbrett realisiert. Auf einem Steckbrett sind an den Rändern + und – durchgehend verbunden. Hier bedeutet + 3,3V und – 0V (also GND). Die anderen Steckplätze sind durchnummeriert und jeweils ABCDE und FGHIJ sind miteinander verbunden (siehe roter Kreis). Abbildung: Grundaufbau auf Steckbrett Abbildung: Anschlussbelegung (Quelle: www.infineon.com/xmc-dev) Die einzelnen Anschlüsse des Boards werden Port-Pins genannt. Die Nummerierung erfolgt nach der Schreibweise [Port].[Bit]. Der Begriff „Port“ kann also mehrere physische Anschlüsse bezeichnen. __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 29 - 6.1 Port-Pins als digitale Eingänge Folgende Port-Pins können als Eingänge verwendet werden: P0.0, P0.5, P0.6, P0.7, P0.8, P0.9, P0.14, P0.15 P2.0, P2.6, P2.7, P2.9, P2.10, P2.11 (Also alle außer die Anschlüsse für die Spannungsversorgung) 6.1.1 Eingänge für aktive digitale Signale Bei den digitalen Eingängen wird unterschieden, ob ein aktives digitales Signal vorliegt, das selbständig den Zustand 0 (0V) oder den Zustand 1 (Versorgungsspannung ~ 3,3V) annehmen kann. Die Stromstärke spielt dabei keine Rolle. Solche Signale werden in der Regel von anderen digitalen Systemen zur Verfügung gestellt. Abbildung: Anschluss eines digitalen Systems Mit dem folgendem Befehl wird ein Port-Pin P0.X (X durch die Zahl eines vorhandenen Bits ersetzen) als Eingang für ein aktives digitales Signal konfiguriert: P0_X_set_mode(INPUT); Bei Port-Pins 2.6 und 2.7 muss eine Besonderheit beachtet werden. Diese Eingänge können auch für analoge Signale verwendet werden. Deshalb muss hier eine zusätzliche Einstellung vorgenommen werden, die den Eingang als digitalen Eingang konfiguriert. P2_X_enable_digital(); P2_X_set_mode(INPUT); 6.1.2 Eingänge für passive Signale Oft wird aber auch ein Schalter angeschlossen der nur geschlossen oder offen sein kann. Hierzu muss am Schalter eine Spannung über einen Vorwiederstand angeschlossen werden. Bei dem vorliegenden Prozessor besteht die Möglichkeit, hierzu einen im XMC1100 eingebauten Widerstand in Höhe von 70kOhm zu verwenden. Bei geöffnetem Schalter wird am Eingang nun, wie bei einem aktiven Signal, die Versorgungsspannung, also der Zustand 1, erkannt. Wird der Schalter geschlossen so wird der Eingang auf 0V, also GND, gelegt. Der Eingang erkennt nun eine 0. Es fließt allerdings ein geringer Strom von etwa 40µA durch den Vorwiderstand. PU wird hier als Abkürzung für Pull Up, also den eingebauten Widerstand der den Pin auf den Spannungswert von nahezu 3,3V „hochzieht“, verwendet. P0_X_set_mode(INPUT_PU); P2_X_enable_digital(); P2_X_set_mode(INPUT_PU); __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 30 - 6.1.3 Einlesen der Eingangswerte Nach der erfolgreichen Konfiguration können nun die Zustände, die an den Port-Pins anliegen, eingelesen werden. Hierzu steht die folgende Funktion zur Verfügung: PY_X_read(); Die Funktion liefert bei einer 0 also 0V am Eingang den Wert 0 zurück. Liegt an dem Eingang eine 1 an so wird der Wert 2^X also die binäre Wertigkeit des entsprechenden Bits zurückgegeben. Der Aufruf der Funktion P2_6_read() liefert also den Wert 64 (2^6) zurück, wenn an P2.6 eine 1 anliegt. Natürlich kann bei einer Abfrage, ob an dem Port eine 1 anliegt ein Vergleich mit 64 ausgeführt werden. Einfacher ist es aber, auf !=0 abzufragen. Bei einem Taster, der über einen Widerstand (Pull Up) angeschlossen ist, muss die Abfrage allerdings anders gestaltet werden. Wenn der Taster nicht betätigt wird, so liegt über den Vorwiderstand die Versorgungsspannung auf dem Eingang. Wird der Taster aber gedrückt so wird der Eingang auf 0V (GND) gelegt und eine 0 eingelesen. In diesem Fall muss die Abfrage ==0 eingesetzt werden. Man spricht von der sogenannten negativen Logik. 6.1.4 Anschluss eines Tasters Abbildung: Anschluss eines Schalters Abbildung: Taster auf Steckbrett P2_6_enable_digital(); P2_6_set_mode(INPUT_PU); while(1) { if(P2_6_read()==0) //Abfrage ob Taster gedrückt ist { UART_SendText("gedrueckt\r\n") LED1_ON(); while(P2_6_read()==0) //Warten bis Taster losgel. wird { WAIT_mS(10); } LED1_OFF(); } } __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 31 - . 6.2 Port-Pins als digitale Ausgänge Folgende Port-Pins können als Ausgänge verwendet werden: P0.0, P0.5, P0.6, P0.7, P0.8, P0.9, P0.14, P0.15 P2.0, P2.10, P2.11 ACHTUNG: Die Port-Pins P2.6, P2.7, P2.9 können NUR als EINGÄNGE verwendet werden! 6.2.1 Ausgänge für aktive digitale Signale Bei den digitalen Ausgängen wird unterschieden, ob an den Ausgängen ein anderes digitales System angeschlossen ist. Hier kann ohne weitere Vorkehrungen eine 0 (GND) oder eine 1 (3.3V) ausgegeben werden. Der Eingangswiderstand der Gegenseite ist nahezu unendlich groß. Es fließt also praktisch kein Strom und der Mikrocontroller wird nicht belastet. Mit dem folgendem Befehl wird ein Port-Pin PX.X als Ausgang für ein aktives digitales Signal konfiguriert: P0_X_set_mode(OUTPUT); Port 2 muss ebenfalls zuvor wieder als digitaler Port konfiguriert werden. P2_X_enable_digital(); P2_X_set_mode(OUTPUT); //gilt nur für P2.0 P2.10 und P2.11 6.2.2 Ausgänge über die ein Strom fließen soll Die Port-Pins können einen Strom in Höhe von 7mA ausgeben (treiben) oder gegen GND abfließen lassen (senken). Werden große Ströme z.B. für einen Motor benötigt, so muss ein externer Treiber (z.B. ein Transistor) eingesetzt werden. Für einen Mikrocontroller ist es einfacher, Strom gegen GND abfließen zu lassen. Deshalb werden die Schaltungen oft so ausgelegt, dass das aktive Bauelement über einen Vorwiderstand, der den Strom auf maximal 7mA begrenzt, an 3,3V angeschlossen ist. Liegt an dem Port-Pin nun ebenfalls 3,3V, also eine 1 an, so kann kein Strom fließen. Wird der Port-Pin dagegen auf 0 gesetzt (also auf GND), so kann ein Strom fließen. Achtung! Der Mikrocontroller kann zerstört werden, wenn Ströme von mehr als 7mA fließen! Ausgänge setzen, löschen oder umschalten Die einzelnen Ausgänge können auf 1 (3,3V) gesetzt werden. Sie können auch gelöscht, also auf 0 (GND) gesetzt werden. Häufig kommt es auch vor, dass ein Ausgang umgeschaltet werden soll, um z.B. ein Rücksignal für einen Signalgeber zu erzeugen. Hier ist es nicht wichtig zu wissen, in welchem Zustand sich der Ausgang befindet. Wichtig ist nur, dass er umgeschaltet wird. Eine 1 wird zur 0 und eine 0 wird zur 1. Diesen Vorgang nennt man auch „togglen“. Port-Pin auf 1 (3,3V) setzen: PY_X_set(); Port-Pin auf 0 (GND) setzen: PY_X_reset(); Port-Pin umschalten: PY_X_toggle(); __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 32 - 6.2.3 Anschluss einer Leuchtdiode Abbildung: Anschluss einer Leuchtdiode Abbildung: Leuchtdiode auf Steckbrett an P0.7 Abbildung: Anschlüsse einer Leuchtdiode P2_6_enable_digital(); P2_6_set_mode(INPUT_PU); P0_7_set_mode(OUTPUT); while(1) { if(P2_6_read()==0) { P0_7_reset(); } else { P0_7_set(); } } __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 33 - 6.2.4 Anschluss eines Piezo-Schallwandlers Abbildung: Anschluss eines Piezo-Schallwandlers Abbildung: Piezo-Schallwandler im Einsatz Piezo-Schallwandler haben einen Innenwiderstand >1kOhm. Es können also maximal Ströme in Höhe von 3,3mA fließen. Aus diesem Grund können Piezo-Schallwandler ohne weitere Maßnahmen direkt an einen Port-Pin angeschlossen werden. Bitte beachten, die Periodendauer beträgt 2x die Wartezeit, da mit jedem Togglen nur eine Halbwelle erzeugt wird. P0_8_set_mode(OUTPUT); while(1) { P0_8_toggle(); WAIT_uS(200); //2500 Hz } __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 34 - 6.2.5 Anschluss eines Motors Da bei einem Motor unter Umständen Ströme fließen, für die der Mikrocontroller nicht ausgelegt ist, muss ein externer Treiber eingesetzt werden. Als „Schalter“ wird z.B. ein Transistor verwendet. Übersteigt die Spannung, die zwischen Basis und Emitter anliegt, einen bestimmten Wert, wird der Stromfluss zwischen Kollektor und Emitter freigegeben. Die Transistoren haben in unserem Fall die Form eines Halbzylinders. Von der flachen Seite aus betrachtet, sind die Anschlüsse von links nach rechts: Kollektor, Basis, Emitter. Ein Transistor sollte immer mit einem Vorwiderstand betrieben werden, um die Stromstärke zwischen Basis und Emitter zu begrenzen! Abbildung: Anschluss eines Motors Abbildung: Motortreiber im Einsatz P0_6_set_mode(OUTPUT); P0_6_set(); //Motor einschalten P0_6_reset(); //Motor ausschalten Für größere Motoren empfiehlt sich der Einsatz einer Freilaufdiode. 6.3 Port-Pins als analoge Eingänge einsetzen Viele Informationen, die mit einem Mikrocontroller verarbeitet werden, liegen analog, als zeitkontinuierlich und auch wertkontinuierlich, vor. Zeitkontinuierlich bedeutet, dass das Signal zu jedem beliebigen Zeitpunkt definiert ist. Wertkontinuierlich bedeutet, dass die Signalwerte stufenlos veränderbar sind. Viele verfügbare Sensoren wandeln diese analogen Größen in Spannungen um, die dann mit Hilfe eines Analog-Digital Wandlers in Zahlen umgewandelt werden können. Die Umwandlung kann natürlich nicht ständig erfolgen, sondern nur zu von dem Mikrocontroller festgelegten Zeitpunkten. Diesen Vorgang nennt man Abtastung. Die Werte, die bei der Abtastung entstanden sind, weisen nicht mehr die Qualität des ursprünglich gesendeten analogen Signals auf, denn es sind nur Momentaufnahmen (das abgetastete Signal ist also nicht mehr zeitkontinuierlich). In unserem Fall wird eine Spannung bis maximal 3,3V durch die Zahlen von 0 bis 4095 abgebildet (dagegen werden die Zahlen beim digitalen System binär übertragen). Die Schritte, in der die Spannung in Zahlen umgewandelt werden kann, sind __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 35 - 0,80586 mV pro Bit (das abgetastete Signal ist also auch nicht wertkontinuierlich, dadurch entsteht ein weiterer Qualitätsverlust). 0 ~ 0mV 1 ~ 0,80586 mV 2 ~ 1,61172 mV 3 ~ 2,41758 mV 4 ~ 3,22344 mV .. 100 ~ 80,58608 mV … 1000 ~ 805,86080 mV .. 2000 ~ 1611,7216 mV … 3000 ~ 2417,58241 mV … 4000 ~ 3223,44322 mV … 4095 ~ 3300,00000 mV In der Regel ist die Spannung aber nur eine Hilfsgröße und die ermittelten Zahlenwerte müssen den eigentlichen gemessenen physikalischen Größen wie Druck, Temperatur, Helligkeit … zugeordnet werden. Häufig wird das analoge Signal durch andere Signale gestört. Die Störungen sind „zufällig“ verteilt und können deshalb weitgehend eliminiert werden, wenn von vielen Abtastwerten ein Mittelwert gebildet wird. Es werden also z.B. 100 Abtastwerte addiert und dann durch 100 dividiert. Die folgende Funktionen werden vom Modul NWT_ADC.h und NWT_ADC.c bereit gestellt. 6.3.1 Port-Pins als analoge Eingänge initialisieren Die Port-Pins P2.7 und P2.6 können als analoge Eingänge verwendet werden. Sie sind mit den folgenden Befehlen zu initialisieren: ADC_P2_6_INIT(); ADC_P2_7_INIT(); 6.3.2 Analoge Spannungswerte in eine Zahl zwischen 0 und 4095 wandeln Die folgenden Funktionen starten die Wandlung und liefern nach der beendeten Wandlung einen Wert zurück, der einer Variablen zugewiesen werden kann: uint32_t ui32WertP2_6, ui32WertP2_7; … ui32WertP2_6 = ADC_P2_6_READ(); ui32WertP2_6 = ADC_P2_7_READ(); 6.3.3 Einlesen eines Potentiometers Durch Drehen an einem Potentiometer (Poti) wird ein Schleifer über einen Widerstand geführt. Je nach Position des Abgriffs kann eine Spannung zwischen 0V und 3,3V abgegriffen werden. Diese Spannung kann mit Hilfe des Analog-Digital Wandlers eines Mikrocontrollers erfasst werden. Abbildung: Anschluss eines Potentiometers __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 36 - Abbildung: Potentiometer im Einsatz In der Endlosschleife wird ein Wert vom AD-Wandler eingelesen und anschließend über die Kommunikationsschnittstelle an den PC gesendet. Dies geschieht 1 mal pro Sekunde. #include "init.h" #include "xmc1100.h" #include "..\_Module\NWT_ADC.h" int main(void) { //----------------------------//Variablen //----------------------------uint32_t ui32WertP2_6; //Grundeinstellungen Board_Init(); //----------------------------//Einmalige Anweisungen //----------------------------ADC_P2_6_INIT(); while(1) { ui32WertP2_6 = ADC_P2_6_READ(); UART_SendInt(ui32WertP2_6); UART_Send_ENDL(); WAIT_mS(1000); } } __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 37 - Bei den auf dem PC angezeigten Werten sieht man gut, wie groß die Schwankungen und damit die Ungenauigkeiten sind. Summiert man allerdings die Abweichung, so stellt man fest, dass das Ergebnis viel kleiner als die einzelnen Abweichungen oder sogar 0 ist. Messwerte Messwert 1 Messwert 2 Messwert 3 Messwert 4 Messwert 5 Messwert 6 Messwert 7 Messwert 8 Messwert 9 Messwert 10 Messwert 11 Messwert 12 Messwert 13 Messwert 14 Messwert 15 Messwert 16 Messwert 17 Messwert 18 Mittelwert 2004 Abweichung -22,33 -36,33 -25,33 17,67 13,67 21,67 4,67 5,67 8,67 2,67 -1,33 -0,33 5,67 -2,33 2,67 3,67 2,67 -1,33 Abweichung in % -1,11% -1,81% -1,26% 0,88% 0,68% 1,08% 0,23% 0,28% 0,43% 0,13% -0,07% -0,02% 0,28% -0,12% 0,13% 0,18% 0,13% -0,07% 2005,33 0,00 0,00% 1983 1969 1980 2023 2019 2027 2010 2011 2014 2008 2004 2005 2011 2003 2008 2009 2008 6.3.4 Einsatz eines Ringspeichers Um genaue Messwerte zu erhalten, wird hier ein Ringspeicher für 256 Werte eingesetzt. Kern ist eine 8Bit Variable die bei der Erhöhung um den Wert 1 automatisch von 255 wieder auf 0 springt und damit den linearen Speicher quasi zu einem Ring biegt. Der folgende Code beschreibt den Ringspeicher im „Kreis“. ui32RingSpeicher[ui8Loop] = ADC_P2_6_READ(); ui8Loop++; //nach 255 wird ui8Loop wieder 0 Um einen gültigen Messwert zu erhalten, müssen nun die Werte im Ringspeicher aufaddiert und durch die Größe (hier also 256) dividiert werden. for(ui16LoopCounter=0; ui16LoopCounter<256; ui16LoopCounter++) { ui32Mittelwert=ui32Mittelwert+ui32RingSpeicher[ui16LoopCounter]; } ui32Mittelwert=ui32Mittelwert/256; Der Vorteil besteht in einem praktischen stabilen Wert. Der Nachteil ist aber auch sofort zu erkennen: erst nach 256 neuen Werten ist wieder ein gültiger Wert verfügbar. Das bedeutet, dass das System eine deutlich größere Laufzeit aufweist. In dem folgenden Beispiel, das alle 10mS einen Wert erfasst, dauert es 2,56 Sekunden bis der ausgegebene Wert dem tatsächlichen Wert entspricht. In der Praxis muss ein Kompromiss eingegangen werden zwischen Reaktionsgeschwindigkeit und Genauigkeit. __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 38 - Hier das ganze Programm. int main(void) { //----------------------------//Variablen //----------------------------uint32_t ui32WertP2_6; uint32_t ui32RingSpeicher[256]; uint32_t ui32Mittelwert=0; uint8_t ui8Loop=0; uint16_t ui16LoopCounter; //Grundeinstellungen Board_Init(); //----------------------------//Einmalige Anweisungen //----------------------------ADC_P2_6_INIT(); //Ring Speicher mit 0 initialisieren for(ui16LoopCounter=0; ui16LoopCounter<256; ui16LoopCounter++) { ui32RingSpeicher[ui16LoopCounter]=0; } while(1) { //Ringspeicher fuellen ui32RingSpeicher[ui8Loop] = ADC_P2_6_READ(); ui8Loop++; //Ringspeicher auswerten for(ui16LoopCounter=0; ui16LoopCounter<256; ui16LoopCounter++) { ui32Mittelwert=ui32Mittelwert+ui32RingSpeicher[ui16LoopCounter]; } ui32Mittelwert=ui32Mittelwert/256; //Wert verarbeiten UART_SendInt(ui32Mittelwert); UART_Send_ENDL(); WAIT_mS(10); } } Gut ist zu erkennen, wie die Werte sich dem eigentlichen erwarteten Messwert annähern und dann zu stabilen Messwerten werden. 13 27 41 55 69 83 97 111 125 139 153 167 181 195 209 223 237 251 265 279 293 307 321 335 349 363 377 391 405 ... ... 3397 3411 3425 3439 3453 3467 3481 3495 3509 3523 3537 3551 3565 3579 3579 3579 3579 3579 3579 3579 3579 __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 39 - Der System-Timer 7 Der System-Timer wird nach Verstreichen eines festgelegten Intervalls ausgelöst. Die Programmausführung wird dann unterbrochen und springt in die Funktion SysTick_Handler(). Nachdem diese Funktion abgearbeitet wurde, wird die Programmausführung fortgesetzt. Das Intervall zwischen den Aufrufen von SysTick_Handler() wird mit der Funktion SysTick_Config( Wert ) festgelegt. Der Übergabewert ist die Anzahl an Taktzyklen („Arbeitsschritte“ des Mikrocontrollers), die innerhalb des Intervalls vergehen sollen. Die Anzahl vergangener Taktzyklen ist proportional zur verstrichenen Zeit. Bei diesem Mikrocontroller entsprechen 8 Taktzyklen in etwa einer Mikrosekunde (µs). Beispiel //Grundeinstellungen vornehmen SysTick_Config(8000); //Intervall von ca. 1 ms Die Funktion SysTick_Handler() wird automatisch aufgerufen (ähnlich der main() Funktion). Im Gegensatz zur main()-Funktion muss SysTick_Handler() aber nicht unbedingt vorhanden sein. Möchte man die Funktion verwenden, muss sie, wie jede andere Funktion, mit einem Prototyp „eingeführt“ werden. Beispiel #include "init.h" void SysTick_Handler(void); //Prototyp int main(void) { //----------------------------//Variablen //----------------------------//----------------------------//Einmalige Anweisungen //----------------------------//Grundeinstellungen vornehmen Board_Init(); SysTick_Config(800000); //100ms //Variablen initialsieren //Sonstige einmalige Anweisungen UART_SendText("#=================#\r\n"); UART_SendText("# NWT 2go Vorlage #\r\n"); UART_SendText("#=================#\r\n"); //----------------------------//Endlosschleife "magic loop" //----------------------------while(1) { } } void SysTick_Handler(void) { LED1_TOGGLE(); //LED blinkt 5mal pro Sekunde } __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 40 - Wenn auf eine Variable sowohl in der main() als auch in der SysTick_Handler() Funktion zugegriffen werden soll, muss diese global, d.h. außerhalb aller Funktionen deklariert werden. Beispiel: #include "init.h" void SysTick_Handler(void); //----------------//Globale Variablen //----------------uint8_t ui8BlinkyEin = 1; int main(void) { //----------------------------//Variablen //----------------------------//----------------------------//Einmalige Anweisungen //----------------------------//Grundeinstellungen vornehmen Board_Init(); SysTick_Config(800000); //100ms //Variablen initialsieren //Sonstige einmalige Anweisungen UART_SendText("#=================#\r\n"); UART_SendText("# NWT 2go Vorlage #\r\n"); UART_SendText("#=================#\r\n"); //----------------------------//Endlosschleife "magic loop" //----------------------------while(1) { //Zugriff auf die globale Variable ui8BlinkyEin = SWITCH_READ(); } } void SysTick_Handler(void) { if(ui8BlinkyEin) //Zugriff auf die globale Variable LED1_TOGGLE(); //LED 1 blinkt nur bei gedrücktem Taster. else LED1_OFF(); } Achtung! Wenn SysTick_Config() aufgerufen wird, muss auch die Funktion SysTick_Handler() vorhanden sein. Ansonsten läuft das Programm „ins Leere“ und wird nicht weiter ausgeführt! __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 41 - 8 Servos Um der Konstruktion eines Getriebes aus dem Weg zu gehen, können Servos umfunktioniert werden. Servos haben den Vorteil, dass Motor und Getriebe in einem handlichen Gehäuse untergebracht sind. Abbildung: Getriebe für den Antrieb Servos sind dazu gedacht, einen bestimmten Winkel anzufahren. Um als Antrieb (beispielsweise für einen Roboter) zu dienen, sollten sich die Motoren aber kontinuierlich drehen. Die hier eingesetzten Servos (Modelcraft RS2 MG/BB) verwenden zur "Orientierung" einen Poti. Das Ziel ist nun, die Servos so umzubauen, dass die Motorsteuerung nicht mitbekommt, wann die Zielposition erreicht ist und die Motoren weiterdrehen lässt. Die einfachste Möglichkeit ist, die mitlaufende Nase des Poti mit einem Seitenschneider abzuzwicken (das ist hier möglich, weil diese Nase bei diesen Servos keine Achse bildet). Gleichzeitig wird damit auch der Anschlag der Zahnräder entfernt. Die Potis müssen nun möglichst genau in Mittelstellung blockiert werden (z.B. durch ganz leichtes und vorsichtiges Anschmelzen der Nase an die Fassung). Präziser ist es jedoch, den Spannungsteiler/Poti durch zwei feste Widerstände zu ersetzen. Das ist deshalb ratsam, weil die Servos eine Motorsteuerung besitzen, die die Geschwindigkeit der Motoren an die "Entfernung" zur Zielposition anpasst. Umso näher die Potistellung an dieser Zielposition ist, desto langsamer drehen die Motoren. Damit beide Motoren in beide Richtungen gleich schnell fahren, müsste der Poti so genau wie möglich in Mittelstellung sein. Weil das schwer zu erreichen ist, ist es besser, den Poti abzuzwicken und durch zwei möglichst identische Widerstände (in der Größenordnung des Poti in Mittelstellung) zu ersetzen. Abbildung: Zwei feste Widerstände ersetzen den Poti Die modifizierten Servos können dann mit Laschen an der Unterseite der Basisplatte befestigt werden. Sie werden parallel zum Board an einer Stromquelle angeschlossen. Bei dieser Stromquelle kann es sich z.B. um ein Batteriepack handeln. Das Board wird über die Pins angeschlossen, die bisher als Stromquelle gedient hatten. Die Motoren werden über ein digitales Signal gesteuert (orangene Ader). Das Signal besteht aus einer High-Pegel-Phase und einer Low-Pegel-Phase. Die Dauer der High-Pegel-Phase bestimmt die Zielposition (1ms = Gegen den Uhrzeigersinn bis zum Anschlag; 2ms = Im Uhrzeigersinn bis zum Anschlag). Da weder Anschlag noch Positionsbestimmung erfolgen können, dreht der Motor einfach immer weiter. Praktisch ist dabei, dass die Motorsteuerung die Motorgeschwindigkeit an die "Nähe" zur Zielposition anpasst. So kann auf einfache Weise die Geschwindigkeit in beide Richtungen gesteuert werden (1000µs = Vollgas gegen den Uhrzeigersinn; 1600µs = Langsam im Uhrzeigersinn). Auf die High-PegelPhase folgt eine Low-Pegel-Phase von mindestens 3ms. __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 42 - Die eingebauten Motoren sind sehr stark und bremsen den Roboter bei einem kurzen Impuls gegen die Laufrichtung auf der Stelle ab. Dabei erhöht sich die Stromaufnahme allerdings deutlich. Im Betrieb ohne weitere große Verbraucher spielt das keine Rolle (dem Board macht es nichts aus, nur die Helligkeit der Leuchtdioden sinkt kurzzeitig). Wer aber (z.B. bei Peripherieeinheiten) eine Mindeststromstärke benötigt, sollte einen Vorwiderstand verwenden. Abbildung: Anschluss eines Servos Beispiel: //Vollgas im Uhrzeigersinn P0_0_set_mode(OUTPUT); P0_0_set(); WAIT_ms(2); P0_0_reset(); WAIT_ms(3); __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 43 - 9 9.1 Übungen Fußgängerampel Realisieren Sie eine Fußgängerampel, die bei Bedarf (Tastendruck) den Übergang für Fußgänger frei gibt. Die Grünphase soll durch einen Piepton auch für Sehbehinderte erkennbar sein. 9.2 FET- Fussball Ergebnis Tipper Sind Ergebnisse von Fußballspielen aufgrund von Expertenwissen vorhersagbar? Jeder, der schon mal getippt hat, wird feststellen, dass das doch meistens nicht so ist. Warum also nicht ein Tippgerät entwickeln, mit dem Spielergebnisse zufällig ermittelt werden können? Vorgehensweise: Diskutieren Sie die Funktionsweise unter Berücksichtigung der Möglichkeiten des NWT 2Go Boards und halten Sie das Ergebnis schriftlich fest. Überlegen Sie, wie Sie diese Funktionalität mit dem NWT 2Go Board umsetzen können. Entwickeln Sie ein Programm. 9.3 Lern Timer Oftmals besteht die Gefahr, beim Lernen abzuschweifen. Entwickeln Sie deshalb den Lern-Timer, der nach Ihrer Vorgabe z.B. alle 3 Minuten piepst, es sei denn Sie drücken vor oder während des Piepsens eine Taste und setzen den Timer zurück. __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 44 - Anhang Übersicht 10 10.1 Datentypen Datentyp char int8_t uint8_t int16_t uint16_t int32_t uint32_t float Kennung c i8 ui8 i16 ui16 i32 ui32 f Größe 1 Byte 1 Byte 1 Byte 2 Byte 2 Byte 4 Byte 4 Byte 4Byte double d 8 Byte 10.2 Beschreibung Zeichen Zahlenwerte -128 bis 127 Zahlenwerte 0 bis 255 -32768 bis 32767 0 bis 65535 -2^31 bis 2^31-1 0 bis 2^32-1 Kommazahlen sehr rechenintensiv Kommazahlen extrem rechenintensiv NWT_UART Modul UART_SendText( Text ); UART_SendInt( Zahl ); UART_SendFloat( Zahl); UART_Send_ENDL(); 10.3 XMC_2Go_NWT Modul LED1_ON(); LED1_OFF(); LED1_TOGGLE(); LED2_ON(); LED2_OFF(); LED2_TOGGLE(); SWITCH_READ(); SWITCH_WAIT_PRESSED(); SWITCH_WAIT_OPEN(); WAIT_uS( Wert ); WAIT_mS( Wert ); __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 45 - 10.4 Port-Pins Port-Pin Eingang digital X X X X X X X X X X X X X X P0.0 P0.14 P0.15 P0.5 P0.6 P0.7 P0.8 P0.9 P2.0 P2.10 P2.11 P2.6 P2.7 P2.9 Ausgang digital Eingang analog X X X X X X X X X X X X X //Port 2 P2_X_enable_digital(); P2_X_set_mode(OUTPUT); //Port 0 P0_X_set_mode(OUTPUT); //Allgemein P2_X_set_mode(INPUT_PU); //mit Vorwiderstabd P2_X_set_mode(INPUT); //ohne Vorwiderstabd PY_X_set(); PY_X_reset(); PY_X_toggle(); PY_X_read() 11 [1] [2] Literatur µVision User's Guide http://www.keil.com/ __________________________________________________________________________________________ C Kurs mit dem XMC 2Go Evaluation Kit - 46 -