Labor für Elektronik und elektrische Antriebe Praktikum zur Lehrveranstaltung Elektronik/Mikroprozessortechnik µC.1 Verbundlabor Mechatronik Labor für Elektronik und elektrische Antriebe Praktikumsversuch µC Programmierung von Mikrocontrollern Tilman Küpper, Nils Beutler 03/2013 Labor für Elektronik und elektrische Antriebe Praktikum zur Lehrveranstaltung Elektronik/Mikroprozessortechnik 1 µC.2 Einleitung Im Kapitel „Digitaltechnik“ werden Aufbau und Funktion moderner Mikroprozessoren und Mikrocontroller betrachtet. Folgende Themen sind dabei von besonderer Bedeutung (vergl. Abb. 1): Logische Verknüpfungen Logikgatter (AND, OR, NAND, NOR usw.) finden sich an vielen Stellen eines Mikroprozessors. Beispielsweise analysiert der Befehlsdecoder so die einzelnen Bits eines Maschinenbefehls. Speicher, Register, Flags Zwei Transistoren genügen, um ein einzelnes Bit abzuspeichern (sog. Flipflop-Schaltung). Mit Flipflops können daher Speicherzellen aufgebaut werden, die innerhalb (Arbeitsregister, Flags) und außerhalb von Prozessoren (Hauptspeicher) benötigt werden. Zählerschaltungen Flipflops eignen sich auch zum Aufbau von Zählerschaltungen, die in Mikroprozessoren und Mikrocontrollern an verschiedenen Stellen benötigt werden. Zum Beispiel beim Befehlszähler oder zum Inkrementieren (Hochzählen) bzw. Dekrementieren (Abwärtszählen) von Registerinhalten. Rechenwerk, Arithmetisch-logische Einheit (ALU) Ein vollständiges Rechenwerk zum Addieren und Subtrahieren von 4-Bit-Dualzahlen wird ebenfalls in der Lehrveranstaltung besprochen. Abb. 1 – Aufbau eines Mikroprozessors Im Praktikumsversuch „Mikrocontroller (µC)" haben Sie nun die Gelegenheit, eigene Erfahrungen mit der Programmierung eines typischen Mikrocontrollers zu sammeln. Aber was ist eigentlich ein „Mikrocontroller“ – was unterscheidet ihn von einem „klassischen Mikroprozessor“? Tilman Küpper, Nils Beutler 03/2013 Labor für Elektronik und elektrische Antriebe Praktikum zur Lehrveranstaltung Elektronik/Mikroprozessortechnik µC.3 Wird von einem Mikroprozessor gesprochen, ist damit die digitale Recheneinheit auf einem Chip mit Registern und eventuell Cache und Speichercontroller gemeint. Mikroprozessoren haben heutzutage eine Wortbreite von 8 bis 64 Bit, in manchen speziellen Systemen sogar bis zu 128 Bit. Prozessoren für PCs sollen möglichst alle unterschiedlichen Aufgaben, wie zum Beispiel Textverarbeitung, Spiele oder Multimediananwendungen möglichst gleichzeitig und gleichmäßig schnell abarbeiten können. [...] Oft wird in der Technik von „Embedded System“ gesprochen. Hiermit ist ein komplexeres Gerät mit Speicher, Mikroprozessor und Kommunikationsschnittstellen gemeint, das auf einer einzigen Platine integriert ist. Solche Geräte werden für den Massenmarkt produziert. [...] Mit zunehmender Integration der Halbleitertechnologie wurde es möglich, die Größe von Embedded Systems stark zu reduzieren und immer mehr Funktionalität bei gleicher Leistung auf einem einzigen Chip zu integrieren. Ein Mikrocontroller ist ein Computer auf einem Chip mit Programm-, Datenspeicher und Kommunikationsschnittstellen. Viele Mikrocontroller haben selbst einen Oszillator, mehrere Analog-/Digitalwandler, Timer und Zähler auf dem Chip integriert. Mikrocontroller sind sehr flexibel in ihrem Einsatz. Mikrocontroller werden in allen erdenklichen Geräten eingesetzt und werden in Massen produziert, was sich positiv auf die Kosten auswirkt. Einfache Chips sind schon für weniger als 1 Euro auf dem Markt erhältlich.1 In diesem Praktikumsversuch wird der Mikrocontroller ATmega8515 eingesetzt. Er wird von der Firma Atmel (www.atmel.com) hergestellt. Sein interner Aufbau ist in Abb. 2 wiedergegeben. Der Mikrocontroller ATmega8515 ist Teil einer größeren Controllerfamilie, der sog. „AVR-Familie“. Die unterschiedlichen Mikrocontroller dieser Familie unterscheiden sich zum Beispiel in der Größe des eingebauten RAM-Speichers, der Anzahl der digitalen Ein- und Ausgangsleitungen oder der Anzahl der seriellen Schnittstellen. Einige AVR-Mikrocontroller besitzen einen integrierten AnalogDigital-Wandler, andere können direkt in ein CAN-Bus-Bordnetz integriert werden usw. Zudem existiert eine große Auswahl hinsichtlich der verfügbaren Bauformen, vom kleinen SMD-Gehäuse mit 8 Kontakten bis zu größeren QFP-Gehäusen („Quad Flat Package“) mit 64 Kontakten. Alle Mikrocontroller der AVR-Familie besitzen denselben 8-Bit-Prozessorkern mit denselben Maschinenbefehlen und einer ähnlichen Anzahl von Registern. Zur Programmierung des ATmega8515 stellt die Firma Atmel eine kostenlose Programmierumgebung2 zur Verfügung. Dieses „AVR Studio“ wird auf einem handelsüblichen Windows-PC installiert. Außerdem wird ein für AVR-Mikrocontroller geeignetes Programmiergerät benötigt. Solche Programmiergeräte können als fertige Bausteine für wenig Geld beschafft 3 oder mit geringem Aufwand selbst aufgebaut4 werden. Das Atmel Studio ermöglicht die Programmierung von Mikrocontrollern entweder direkt in Assembler (Maschinensprache) oder in der Programmiersprache C. In den folgenden Praktikumsversuchen wird ausschließlich die Programmiersprache C verwendet, die bereits durch die Lehrveranstaltung Ingenieurinformatik bekannt ist. 1 Thomas Ruschival, Untersuchung von Angriffsmöglichkeiten auf Feldgeräte von Automatisierungssystemen, Studienarbeit am Institut für Automatisierungs- und Softwaretechnik der Universität Stuttgart (2006), S. 14f. 2 Download über die Atmel-Homepage: http://www.atmel.com/tools/atmelstudio.aspx 3 Zum Beispiel das Programmiergerät STK500 der Firma Atmel: http://www.atmel.com/tools/STK500.aspx 4 Entsprechende Bauanleitungen finden sich im Internet, zum Beispiel im ersten Kapitel des „AVR-Tutorials“ auf der Seite http://www.mikrocontroller.net Tilman Küpper, Nils Beutler 03/2013 Labor für Elektronik und elektrische Antriebe Praktikum zur Lehrveranstaltung Elektronik/Mikroprozessortechnik µC.4 Abb. 2 – Interner Aufbau des Mikrocontrollers ATmega85155 5 Aus dem Datenblatt des Mikrocontrollers ATmega8515, http://www.atmel.com/Images/doc2512.pdf, Firma Atmel (Stand: 28. Januar 2013) Tilman Küpper, Nils Beutler 03/2013 Labor für Elektronik und elektrische Antriebe Praktikum zur Lehrveranstaltung Elektronik/Mikroprozessortechnik 2 µC.5 Beschreibung des Versuchsaufbaus Programmiergerät STK500 Experimentierbox Abb. 3 – Programmiergerät STK500 mit Experimentierbox (1) Die acht digitalen Ein-/Ausgänge PB0, PB1, …, PB7 des Mikrocontrollers (der sog. „Port B“) sind direkt mit den entsprechenden Buchsen auf der Frontplatte der Experimentierbox verbunden (siehe Abb. 4 auf der folgenden Seite). So können auf einfache Weise Taster, Leuchtdioden oder andere Komponenten an den Mikrocontroller angeschlossen werden. (2) Bei den vier Tastschaltern ist zu beachten, dass diese „active low“ geschaltet sind. Dies bedeutet, dass jeder Schalter im gedrückten Zustand ein Low-Signal (= 0) an den Mikrocontroller sendet bzw. ein High-Signal (= 1) im nicht gedrückten Zustand. (3) Die Leuchtdioden sind bereits mit passenden Vorwiderständen ausgestattet, so dass sie direkt mit den Ausgängen des Mikrocontrollers verbunden werden können. Die Leuchtdioden leuchten, falls am jeweiligen Ausgang ein High-Signal (= 1) anliegt. (4) Der Lüfter am unteren rechten Rand der Experimentierbox kann nicht direkt mit einem Ausgang des Mikrocontrollers verbunden werden, da sein Strombedarf groß ist. Aus diesem Grund wird er über eine Transistorverstärkerstufe mit Strom versorgt. (5) Der Temperatursensor SMT 160-30 gibt an seinem Ausgang ein Rechtecksignal aus. Aus dem Tastgrad D, also dem Verhältnis von Impuls- zu Periodendauer (engl. „duty cycle“), kann die Temperatur berechnet werden. Es gilt: D = 0,32 + 0,0047 ∙ T wobei T die Temperatur in °C ist.6 Das in Abb. 5 gezeigte Sensorsignal zeigt einen Tastgrad von D = 0,4192. Die gemessene Temperatur ist also: T = [(0,4192 – 0,32) / 0,0047] °C = 21,1 °C Zur Auswertung des Temperatursensors durch den Mikrocontroller muss ein Programm geschrieben werden, welches den Tastgrad des Sensorsignals ermittelt. Die Frequenz des Sensorsignals (hier ca. 3 kHz) ist dagegen nicht von Bedeutung. 6 Vergl. Datenblatt des Temperatursensors SMT 160-30, http://www.smartec.nl/pdf/DSSMT16030.PDF, Firma Smartec (Stand: 26. Februar 2013) Tilman Küpper, Nils Beutler 03/2013 Labor für Elektronik und elektrische Antriebe Praktikum zur Lehrveranstaltung Elektronik/Mikroprozessortechnik (1) Ein-/Ausgänge PB0, …, PB7 (2) Tastschalter µC.6 (3) Leuchtdioden (4) Lüfter (5) Temperatursensor Abb. 4 – Frontplatte der Experimentierbox B A Tastgrad A/B = 0,4192 B Abb. 5 – Ausgangssignal des Temperatursensors SMT 160-30 Tilman Küpper, Nils Beutler 03/2013 Labor für Elektronik und elektrische Antriebe Praktikum zur Lehrveranstaltung Elektronik/Mikroprozessortechnik 3 µC.7 Vorbereitung auf den Versuchstermin Im Rahmen dieses Praktikumstermins erstellen Sie eine Reihe von C-Programmen. Es ist daher wichtig, dass Sie sich vor Beginn dieses Praktikums (!!) nochmals mit der Programmiersprache C beschäftigen und einige Grundlagen aus der Lehrveranstaltung Ingenieurinformatik wiederholen. Sie können die folgenden Übungsaufgaben in einem Rechnerraum der FK03 oder an Ihrem privaten PC durchführen. Als Programmierumgebung eignet sich zum Beispiel das kostenlos erhältliche „Visual Studio Express“ der Firma Microsoft. 7 3.1 Programmierung von Schleifen Schreiben Sie ein Programm, welches in Zweierschritten von -10 bis +10 zählt! Schreiben Sie ein Programm, welches in einer Endlosschleife immer wieder den Text „Schleife“ auf dem Bildschirm ausgibt! Tipp: Es gibt in der Programmiersprache C drei Arten von Schleifen, nämlich while-Schleifen, dowhile-Schleifen und for-Schleifen. Machen Sie sich nochmals den Unterschied zwischen diesen Schleifenarten klar. Welche Anweisungen dienen zur Programmierung von abweisenden, welche zur Programmierung von nicht-abweisenden Schleifen? Wie können diese Schleifen in Struktogrammen grafisch dargestellt werden? 3.2 Programmierung von Verzweigungen Das abgebildete C-Programm erwartet vom Anwender eine Eingabe, ob zwei Zahlen addiert oder subtrahiert werden sollen. Anschließend wird die gewünschte Berechnung ausgeführt und das Ergebnis auf dem Bildschirm ausgegeben. Vervollständigen Sie den abgebildeten C-Quelltext! Tipp: Sie können die Anweisungen if-else oder switch-case benutzen. #include <stdio.h> int main(void) { int wahl, a, b, ergeb; printf("(1) Addition oder (2) Subtraktion: "); scanf("%d", &wahl); printf("Zahl A: "); scanf("%d", &a); printf("Zahl B: "); scanf("%d", &b); /* Verzweigung, Berechnung, Ausgabe... */ return 0; } 7 Kostenloser Download über die Seite http://www.microsoft.com Tilman Küpper, Nils Beutler 03/2013 Labor für Elektronik und elektrische Antriebe Praktikum zur Lehrveranstaltung Elektronik/Mikroprozessortechnik 4 µC.8 Versuchsdurchführung Um die Programmierung der folgenden Beispiele zu erleichtern, sind auf den Laborrechnern vorbereitete Projektverzeichnisse abgelegt. Oft sind die Programme schon (teilweise) implementiert; Sie müssen die C-Quelltexte dann nur noch vervollständigen oder – je nach Aufgabenstellung – geeignet verändern. 4.1 Digitale Ein- und Ausgänge Im ersten Versuch lernen Sie die digitalen Ein- und Ausgänge des Mikrocontrollers kennen. Die Anschlüsse des ATmega8515 können entweder als Ein- oder als Ausgänge verwendet werden. Zu Beginn des Mikrocontroller-Programms muss daher festgelegt werden, welche Anschlüsse welche Funktion übernehmen sollen. Dazu dienen die sog. „Data Direction Register“ des Mikrocontrollers. Im Praktikum wird mit den Anschlüssen PB0, PB1, …, PB7 gearbeitet, dem sog. „Port B“. Daher muss hier das Data Direction Register des Ports B (kurz: DDRB) entsprechend eingestellt werden. Das DDRB-Register hat eine Größe von 8 Bit. Jedes einzelne Bit bezieht sich auf einen einzelnen Anschluss: das nullte Bit auf den Anschluss PB0, das erste Bit auf PB1, das zweite Bit auf PB2 usw. Um einen Anschluss des Mikrocontrollers als Ausgang zu verwenden, muss „sein“ Bit im DDRBRegister auf 1 gesetzt werden. Für Eingänge ist es auf 0 zu setzen. Die Zuweisung DDRB = 0b00001111; macht beispielsweise die Anschlüsse PB0…PB3 zu Ausgängen und die Anschlüsse PB4…PB7 zu Eingängen. (Wer mag, kann diese Zuweisung statt im Binärformat auch im Dezimal- oder Hexadezimalformat schreiben: DDRB = 15; und DDRB = 0x0F; haben dieselbe Bedeutung, weil 00001111bin = 15dez = 0Fhex ist.) Um einen Ausgang ein- oder auszuschalten, muss das entsprechende Bit im PORTB-Register gesetzt oder gelöscht werden. Dazu werden die Funktionen sbi(PORTB, <Bitnummer>); zum Einschalten oder cbi(PORTB, <Bitnummer>); zum Ausschalten aufgerufen. Zur Überprüfung, ob an einem Eingang ein Signal anliegt oder nicht, dient die Funktion bit_is_set(PINB, <Bitnummer>). Vorbereitung: Verbinden Sie die Anschlüsse PB0, …, PB3 mit den Leuchtdioden und die Anschlüsse PB4, …, PB7 mit den Tastschaltern auf der Experimentierbox. Wechseln Sie am Laborrechner in das vorbereitete Projektverzeichnis „Digital_IO“ und öffnen Sie die Datei „Digital_IO.atsln“. Dadurch wird das AVR Studio gestartet und das vorbereitete C-Programm geladen. Wählen Sie den Hauptmenüpunkt „Build Rebuild Solution“, um den C-Quelltext in Maschinensprache zu übersetzen. Öffnen Sie anschließend mittels „Tools AVR Programming Apply“ das Modul zur Datenübertragung an den Mikrocontroller. Es erscheint das in Abb. 6 gezeigte Dialogfenster. Über die obere Schaltfläche „Program“ kann das gerade erstellte Maschinenspracheprogramm an den Mikrocontroller übertragen und automatisch gestartet werden. Betätigen Sie die Tastschalter auf der Experimentierbox. Was macht das gerade erstellte Programm? Programmieraufgabe: Die Tastschalter auf der Experimentierbox sind „active low“ geschaltet. Ein gedrückter Tastschalter sendet also ein Low-Signal (= 0) an den Eingang des Mikrocontrollers. Aus diesem Grund sind alle Leuchtdioden zunächst eingeschaltet und werden durch Druck auf die Tastschalter ausgeschaltet. Ändern Sie das Programm, so dass die Leuchtdioden bei Betätigung der Tastschalter nicht aussondern eingeschaltet werden! Wenn kein Tastschalter gedrückt ist, sollen die Leuchtdioden nicht leuchten. Tilman Küpper, Nils Beutler 03/2013 Labor für Elektronik und elektrische Antriebe Praktikum zur Lehrveranstaltung Elektronik/Mikroprozessortechnik µC.9 /* Taktfrequenz des Controllers muss angegeben werden */ #define F_CPU 1843200UL /* Include-Dateien mit AVR-spezifischen Funktionen */ #include <compat/deprecated.h> #include <avr/sfr_defs.h> #include <avr/io.h> #include <util/delay.h> /* Hauptprogramm */ int main(void) { /* PB0...PB3 sind Ausgänge, PB4...PB7 sind Eingänge */ DDRB = 15; while(1 == 1) /* Endlosschleife */ { if(bit_is_set(PINB, 4)) sbi(PORTB, 0); /* Bit setzen */ else cbi(PORTB, 0); /* Bit löschen */ if(bit_is_set(PINB, 5)) sbi(PORTB, 1); else cbi(PORTB, 1); if(bit_is_set(PINB, 6)) sbi(PORTB, 2); else cbi(PORTB, 2); if(bit_is_set(PINB, 7)) sbi(PORTB, 3); else cbi(PORTB, 3); } return 0; /* Diese Anweisung wird nie erreicht */ } Versuchsergebnis: Beschreiben Sie kurz (mit Stichworten oder einigen Zeilen C-Quelltext), welche Änderungen Sie am Programm vorgenommen haben! Tilman Küpper, Nils Beutler 03/2013 Labor für Elektronik und elektrische Antriebe Praktikum zur Lehrveranstaltung Elektronik/Mikroprozessortechnik µC.10 Korrekten Mikrocontroller auswählen ISP-Modus wählen Verzeichnis, Dateiname überprüfen Menüpunkt „Memories“ auswählen Maschinenspracheprogramm zum Controller senden und automatisch starten Abb. 6 – Datenübertragung zum Mikrocontroller 4.2 Eine Verkehrsampel In diesem Versuch soll eine einfache Verkehrsampel programmiert werden. Die Ampel zeigt zunächst dauerhaft Rot. Erst wenn ein Tastschalter gedrückt wird, wechselt die Ampel auf Rot-Gelb und dann auf Grün. Nach einiger Zeit wechselt die Ampel zurück auf Gelb und schließlich wieder auf Rot. Vorbereitung: Die Anschlüsse der Leuchtdioden und Tastschalter bleiben unverändert. In diesem Versuch werden die Leuchtdioden an PB0 (grün), PB1 (gelb) und PB2 (rot) und der Tastschalter an PB4 verwendet. Schließen Sie zunächst das AVR Studio, falls es noch geöffnet ist. Wechseln Sie am Laborrechner in das vorbereitete Projektverzeichnis „Ampel“ und öffnen Sie die Datei „Ampel.atsln“. Nun wird das AVR Studio mit dem vorbereiteten Ampelprogramm geladen. Programmieraufgabe: Vervollständigen Sie das Ampelprogramm, so dass es dem Struktogramm in Abb. 7 entspricht! (Tipp: Die while-Schleife zum Warten auf den Tastschalter am Anschluss PB4 ist bereits implementiert.) Tilman Küpper, Nils Beutler 03/2013 Labor für Elektronik und elektrische Antriebe Praktikum zur Lehrveranstaltung Elektronik/Mikroprozessortechnik µC.11 Abb. 7 – Struktogramm des Ampelprogramms Versuchsergebnis: Ergänzen Sie den abgebildeten Quelltext! #define F_CPU 1843200UL #include <stdio.h> #include <avr/io.h> #include <util/delay.h> #include <avr/sfr_defs.h> #include <compat/deprecated.h> int main(void) { DDRB = 15; /* PB0...PB3 sind Ausgänge, PB4...PB7 sind Eingänge */ while(1 == 1) { cbi(PORTB, 0); cbi(PORTB, 1); sbi(PORTB, 2); /* Ampel auf Rot schalten */ _delay_ms(1000); while(bit_is_set(PINB, 4)) _delay_ms(50); /* Auf Tastendruck warten */ } return 0; } Tilman Küpper, Nils Beutler 03/2013 Labor für Elektronik und elektrische Antriebe Praktikum zur Lehrveranstaltung Elektronik/Mikroprozessortechnik 4.3 µC.12 Drehzahlsteuerung eines Gleichstrommotors In diesem Versuch soll der auf der Experimentierbox angebrachte Lüfter (Gleichstrommotor) mit unterschiedlichen Drehzahlen betrieben werden. Die Drehzahl eines Gleichstrommotors kann dadurch verändert werden, dass man ihn mit einer anderen Versorgungsspannung betreibt. Zur stufenlosen Einstellung der Versorgungsspannung kann im einfachsten Fall ein veränderlicher Vorwiderstand eingebaut werden. Insbesondere bei größeren Motorleistungen hat dies allerdings immense ohmsche Verluste im Widerstand zur Folge, weswegen dieses Verfahren kaum zum Einsatz kommt. Häufig angewendet wird in der Praxis die Motoransteuerung mittels Pulsweitenmodulation (PWM). Der Motor wird dabei mit einem Rechtecksignal versorgt. Dieses Rechtecksignal hat eine konstante Amplitude, der Tastgrad ist hingegen variabel. Solche Rechtecksignale können mit modernen Leistungsschaltern (Schalttransistoren, MOSFETs) mit sehr geringen Verlusten bereitgestellt werden. Vorbereitung: Der Ausgang PB0 wird an die Ansteuerschaltung des Lüfters angeschlossen. Die vier Tastschalter bleiben weiterhin mit den Anschlüssen PB4…PB7 verbunden. Schließen Sie zunächst das AVR Studio, falls es noch geöffnet ist. Wechseln Sie am Laborrechner in das vorbereitete Projektverzeichnis „Luefter“ und öffnen Sie die Datei „Luefter.atsln“. Es öffnet sich das AVR Studio mit dem vorbereiteten C-Programm. Programmieraufgabe: Das Beispielprogramm ist so implementiert, dass der Lüfter direkt nach dem Programmstart mit geringer Geschwindigkeit läuft. Anschließend kann durch Druck auf die vier Tastschalter eine neue Geschwindigkeit eingestellt werden. Wie muss das Programm geändert werden, damit der Lüfter direkt nach dem Programmstart zunächst gar nicht läuft? Ändern Sie das Programm und testen Sie die Änderungen, indem Sie den Stromversorgungsstecker vom Programmiergerät kurz abziehen und wieder einstecken: Der Lüfter sollte nun nach dem Einstecken zunächst stehen bleiben. Versuchsergebnis (a): Beschreiben Sie kurz (entweder Stichworte oder einige Zeilen C-Quelltext), welche Änderungen Sie im Programm vorgenommen haben! Tilman Küpper, Nils Beutler 03/2013 Labor für Elektronik und elektrische Antriebe Praktikum zur Lehrveranstaltung Elektronik/Mikroprozessortechnik /* Ansteuerung eines Lüfters mittels PWM-Signal #define F_CPU 1843200UL #include <stdio.h> #include <avr/io.h> #include <util/delay.h> #include <avr/sfr_defs.h> #include <compat/deprecated.h> µC.13 */ /* PWM-Signal an PB0 aktivieren, vergl. Datenblatt des ATmega8515. /* Der Tastgrad des PWM-Signals wird über das OCR0-Register in 256 /* Stufen eingestellt (minimal 0, maximal 255). void init_pwm(void) { /* Register TCCR0 ist das "Timer/Counter Control Register 0" TCCR0 = (1 << WGM00) | (1 << COM01) | (1 << CS01); OCR0 = 100; /* Zunächst mittleren Tastgrad einstellen } */ */ */ */ */ int main(void) { DDRB = 15; /* PB0...PB3 Ausgänge, PB4...PB7 Eingänge */ init_pwm(); /* PWM-Signal an PB0 aktivieren */ while(1 == 1) /* Drehzahl je nach Tastendruck einstellen */ { if(!bit_is_set(PINB, 4)) OCR0 = 0; else if(!bit_is_set(PINB, 5)) OCR0 = 100; else if(!bit_is_set(PINB, 6)) OCR0 = 200; else if(!bit_is_set(PINB, 7)) OCR0 = 255; } return 0; } Versuchsergebnis (b): Überprüfen Sie mit dem Oszilloskop den Spannungsverlauf am Ausgang PB0, womit der Lüfter angesteuert wird. Skizzieren Sie die drei Spannungsverläufe, die sich nach Druck auf die Tastschalter PB4, PB6 und PB7 ergeben! U Spannung an PB0 t Zeit Tilman Küpper, Nils Beutler 03/2013 Labor für Elektronik und elektrische Antriebe Praktikum zur Lehrveranstaltung Elektronik/Mikroprozessortechnik 4.4 µC.14 Daten über die serielle Schnittstelle senden Viele Mikrocontroller sind mit einer seriellen Schnittstelle ausgestattet, so auch der hier verwendete ATmega8515. Vor der Verwendung muss diese Schnittstelle per Software initialisiert werden (Funktion com_init() – zu Details vergl. Datenblatt des Mikrocontrollers ATmega8515). Zum Senden eines Zeichens können Sie die Funktion com_send(<Zeichen>) verwenden. 8 Das zu sendende Zeichen wird entweder mit einfachen Anführungszeichen oder als ASCII-Code übergeben: com_send('X'); bzw. com_send(88); Vorbereitung: Schließen Sie zunächst das AVR Studio, falls es noch geöffnet ist. Wechseln Sie am Laborrechner in das vorbereitete Projektverzeichnis „Seriell“ und öffnen Sie die Datei „Seriell.atsln“. Es öffnet sich das AVR Studio mit dem vorbereiteten C-Programm. Übersetzen Sie das C-Programm in Maschinensprache und übertragen Sie es auf den Mikrocontroller! Starten Sie am Laborrechner (zusätzlich zum AVR Studio) das Programm „Tera Term“, mit dem die über die serielle Schnittstelle eintreffenden Daten auf dem Bildschirm angezeigt werden können. Nach dem Programmstart muss zunächst die korrekte Schnittstelle eingestellt werden: Wählen Sie den zweiten „USB Serial Port“ in der Liste. Abb. 8 – Schnittstelle in Tera Term einstellen Programmieraufgabe: Ergänzen Sie das C-Programm, so dass die Zeichenfolge „Hallo“ nicht mehr ohne Leerzeichen hintereinander ausgegeben wird! Stattdessen soll nach jeder Ausgabe zum Anfang der folgenden Zeile gesprungen werden. Tipp: Eine ASCII-Tabelle ist auf der letzten Seite abgedruckt. Versuchsergebnis: Welche Zeichen bzw. ASCII-Codes müssen für einen Zeilenumbruch (englisch „Carriage Return“) und für einen Zeilenvorschub (englisch „Line Feed“) ausgegeben werden? Zeilenumbruch: (Carriage Return, CR) Zeilenvorschub: (Line Feed, LF) 8 Soll ein Zeichen über die serielle Schnittstelle nach „außen“ (zum Beispiel zu einem angeschlossenen PC) gesendet werden, muss zunächst abgewartet werden, bis eine evtl. gerade laufende Datenübertragung beendet ist. Der Mikrocontroller zeigt die Bereitschaft zum Senden dadurch an, dass im Register UCSRA das Bit Nr. 5 gesetzt ist. Das zu sendende Zeichen kann dann in das „Senderegister“ UDR geschrieben werden. Die bereits fertig programmierte Funktion com_send(<Zeichen>) führt diese Schritte der Reihe nach aus. Tilman Küpper, Nils Beutler 03/2013 Labor für Elektronik und elektrische Antriebe Praktikum zur Lehrveranstaltung Elektronik/Mikroprozessortechnik µC.15 /* Daten über die serielle Schnittstelle zum PC senden */ #define F_CPU 1843200UL #include #include #include #include #include <stdio.h> <avr/io.h> <util/delay.h> <avr/sfr_defs.h> <compat/deprecated.h> #define BAUD 9600UL #define UBRR_VAL ((F_CPU + BAUD * 8) / (BAUD * 16) - 1) /* Schnittstelle zum Senden mit void com_init(void) { UBRRH = UBRR_VAL / 256; /* UBRRL = UBRR_VAL & 255; /* UCSRB |= (1 << TXEN), UCSRC } 9600 baud aktivieren */ Details zur Initialisierung der seriellen */ Schnittstelle: siehe Datenblatt ATmega8515 */ = (1 << UCSZ1) | (1 << URSEL) | (1 << UCSZ0); /* Ein Zeichen über die serielle Schnittstelle senden - vergl. Fußnote (8) */ void com_send(char ch) { while(!bit_is_set(UCSRA, 5)) { /* warten */ } UDR = (unsigned char)ch; } int main(void) { com_init(); while(1 == 1) { _delay_ms(500); com_send('H'); com_send('a'); com_send('l'); com_send('l'); com_send('o'); } return 0; } 4.5 Der Temperatursensor SMT 160-30 Am unteren linken Rand der Experimentierbox ist ein Temperatursensor des Typs SMT 160-30 angebracht. In diesem Versuch soll dieser Sensor abgefragt und die gemessene Temperatur über die serielle Schnittstelle zum PC gesendet werden. In Abschnitt 2 wurde gezeigt, dass der Sensor an seinem Ausgang ein Rechtecksignal mit einem von der aktuellen Temperatur abhängigen Tastgrad ausgibt. Der Mikrocontroller muss diesen Tastgrad ermitteln. Dazu liest der Mikrocontroller über einen längeren Zeitraum hinweg das Sensorsignal regelmäßig ein. Immer, wenn der Sensor ein 5V-Signal (logische „1“) liefert, wird eine Zählervariable z1 hochgezählt. Bei einem 0V-Signal (logische „0“) wird eine zweite Zählervariable z2 hochgezählt. Für den Tastgrad gilt dann: D = z1 / (z1 + z2) Es ist wichtig, dass das Sensorsignal tatsächlich in exakt regelmäßigen Zeitintervallen eingelesen wird, andernfalls wird der Tastgrad nicht korrekt berechnet. Aus diesem Grund ist es sinnvoll, einen sog. „Timer-Interrupt“ des Mikrocontrollers zu aktivieren. Dieser sorgt dann automatisch für den regelmäßigen Aufruf der Einlesefunktion. Tilman Küpper, Nils Beutler 03/2013 Labor für Elektronik und elektrische Antriebe Praktikum zur Lehrveranstaltung Elektronik/Mikroprozessortechnik µC.16 Vorbereitung: Verbinden Sie den Ausgang des Temperatursensors mit dem Eingang PB4 des Mikrocontrollers. Schließen Sie zunächst das AVR Studio, falls es noch geöffnet ist. Wechseln Sie am Laborrechner in das vorbereitete Projektverzeichnis „SMT16030“ und öffnen Sie die Datei „SMT16030.atsln“. Es öffnet sich das AVR Studio mit dem vorbereiteten C-Programm. Starten Sie am Laborrechner (zusätzlich zum AVR Studio) das Programm „Tera Term“, mit dem die über die serielle Schnittstelle eintreffenden Daten auf dem Bildschirm angezeigt werden können. /* ------------------------------------------------------------/* Temperatursensor SMT 160-30 abfragen und gemessene Temperatur /* über die serielle Schnittstelle zum PC senden /* ------------------------------------------------------------#define F_CPU 1843200UL #include #include #include #include #include #include */ */ */ */ <stdio.h> <avr/io.h> <util/delay.h> <avr/sfr_defs.h> <compat/deprecated.h> <avr/interrupt.h> #define BAUD 9600UL #define UBRR_VAL ((F_CPU + BAUD * 8) / (BAUD * 16) - 1) /* Globale Zählervariablen für den Ausgang des Temperatursensors */ volatile long z1, z2; /* Diese sog. "Timer-Interruptfunktion" wird vom Mikrocontroller */ /* regelmäßig aufgerufen, vergl. Datenblatt ATmega8515. */ ISR (TIMER0_OVF_vect) { if(bit_is_set(PINB, 4)) ++z1; else ++z2; } /* Serielle Schnittstelle zum Senden mit 9600 baud aktivieren. */ void com_init(void) { UBRRH = UBRR_VAL / 256; /* Details zur Initialisierung der seriellen */ UBRRL = UBRR_VAL & 255; /* Schnittstelle: siehe Datenblatt ATmega8515 */ UCSRB |= (1 << TXEN), UCSRC = (1 << UCSZ1) | (1 << URSEL) | (1 << UCSZ0); } /* Ein Zeichen über die serielle Schnittstelle senden - vergl. Fußnote (8) */ void com_send(char ch) { while(!bit_is_set(UCSRA, 5)) { /* warten */ } UDR = (unsigned char)ch; } /* Wie printf, Ausgabe erfolgt aber über die ser. Schnittstelle. */ void com_printf(const char* pformat, ...) { static char buf[100]; size_t i = 0; va_list arg; va_start(arg, pformat); vsnprintf(buf, 100, pformat, arg); va_end(arg); while(buf[i] != 0 && i < 100) com_send(buf[i++]); } /* Hauptprogramm */ Tilman Küpper, Nils Beutler 03/2013 Labor für Elektronik und elektrische Antriebe Praktikum zur Lehrveranstaltung Elektronik/Mikroprozessortechnik µC.17 int main(void) { double d, t; com_init(); DDRB = 15; /* PB0...PB3 Ausgänge, PB4...PB7 Eingänge */ /* Timer-Interrupt initialisieren, vergl. Datenblatt ATmega8515 */ TCCR0 = (1 << CS00), TIMSK |= (1 << TOIE0); while(1 == 1) { z1 = 0, z2 = 0; /* Timer-Interrupt einschalten, 1 Sekunde warten, wieder ausschalten */ sei(); _delay_ms(1000); cli(); /* Aus den Zählerständen z1 und z2 wird der Tastgrad berechnet */ d = 1.0 * z1 / (z1 + z2); com_printf("z1 = %ld, z2 = %ld, D = %f \r\n", z1, z2, d); } } Programmieraufgabe: Das C-Programm ermittelt den aktuellen (von der Temperatur abhängigen) Tastgrad des Sensorsignals und sendet diesen über die serielle Schnittstelle an den PC. Ergänzen Sie das C-Programm, so dass zusätzlich zum Tastgrad auch die (daraus berechnete) Temperatur an den PC gesendet wird! Hinweis: Zum Zusammenhang zwischen Tastgrad und Temperatur vergl. die Beschreibung des Temperatursensors in Abschnitt 2. Versuchsergebnis: Stellen Sie mit dem Oszilloskop das vom Temperatursensor ausgegebene Rechtecksignal dar. Ermitteln Sie am Oszilloskop den Tastgrad D und daraus die Temperatur T. Vergleichen Sie diese am Oszilloskop gemessenen Werte mit denjenigen, die vom Mikrocontroller gesendet werden! Tastgrad D (Oszilloskop) Temperatur T (Oszilloskop) Tastgrad D (Mikrocontroller) Temperatur T (Mikrocontroller) Tilman Küpper, Nils Beutler 03/2013 Labor für Elektronik und elektrische Antriebe Praktikum zur Lehrveranstaltung Elektronik/Mikroprozessortechnik 4.6 µC.18 Ein elektronischer Würfel Im letzten Versuch soll ein elektronischer Würfel programmiert werden: Wenn der Tastschalter an PB4 betätigt wird, berechnet der Mikrocontroller eine Zufallszahl zwischen 1 und 6 und sendet die Zufallszahl über die serielle Schnittstelle an den PC. Tipp: z = 1 + rand() % 6; Vorbereitung: Verbinden Sie einen Tastschalter mit dem Eingang PB4 des Mikrocontrollers. Schließen Sie zunächst das AVR Studio, falls es noch geöffnet ist. Wechseln Sie am Laborrechner in das vorbereitete Projektverzeichnis „Wuerfel“ und öffnen Sie die Datei „Wuerfel.atsln“. Es öffnet sich das AVR Studio mit dem vorbereiteten C-Programm. Programmieraufgabe (a): Das Hauptprogramm (Funktion main) ist noch gar nicht vorhanden – es muss vollständig von Ihnen programmiert werden! Programmieraufgabe (b): Wenn Sie noch etwas Zeit haben, erweitern Sie Ihr C-Programm: Lassen Sie die Zufallszahl (zusätzlich zur Übertragung an den PC) auch durch die Leuchtdioden auf der Experimentierbox anzeigen! Sie können dazu drei Leuchtdioden mit den Ausgängen PB0, PB1 und PB2 verbinden. Die Ausgabe der „gewürfelten“ Zahl erfolgt dann im Binärformat (001, 010, 011, 100, 101 bzw. 110). 5 Anhang 5.1 Webseiten zur AVR-Mikrocontrollerprogrammierung http://www.mikrocontroller.net/articles/AVR-Tutorial Dieses AVR-Tutorial führt auf einfache Weise in die Arbeit mit AVR-Mikrocontrollern ein. Zunächst wird die minimal erforderliche Hardwareausstattung beschrieben. Die Programmierung geschieht in Assembler (Maschinensprache), also deutlich „hardwarenaher“ im Vergleich zur Programmiersprache C. http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial Das AVR-GCC-Tutorial zeigt die Programmierung von AVR-Mikrocontrollern in der Programmiersprache C. Die Beschreibung der benötigten Hardware ist allerdings nicht so ausführlich wie im zuerst genannten AVR-Tutorial. (Tipp: Mit dem AVR-Tutorial beginnen. Wenn die ersten Programme laufen, mit dem AVR-GCC-Tutorial fortsetzen…) http://www.avrfreaks.net/ Ein umfangreiches Internetangebot in englischer Sprache zu allen Aspekten der AVR-Programmierung. Auch ein Forum mit vielen Unterforen zu Hard- und Softwarefragen oder auch zu „Anfängerproblemen“ ist vorhanden. http://www.atmel.com/ Die Firma Atmel ist der Hersteller der AVR-Mikrocontrollerfamilie. Auf der Firmen-Webseite befinden sich Datenblätter zu allen AVR-Mikrocontrollern und umfangreiche „Application Notes“. Tilman Küpper, Nils Beutler 03/2013 Labor für Elektronik und elektrische Antriebe Praktikum zur Lehrveranstaltung Elektronik/Mikroprozessortechnik 5.2 µC.19 American Standard Code for Information Interchange (ASCII) Abb. 9 – ASCII-Tabelle9 9 Aus Wikipedia, Die freie Enzyklopädie, http://de.wikipedia.org/wiki/American_Standard_Code_for_Information_Interchange (Stand: 10. März 2013) Tilman Küpper, Nils Beutler 03/2013