Programmieren in C Teil 3: Mikrocontrollerprogrammierung 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 1
Tag 1 Hello World 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 2
Mikrocontroller Im Gegensatz zum Mikroprozessor Peripherie integriert Speicher Takterzeugung Interrupt-Controller Timer-Baustein Schnittstellen Single-Chip-Betrieb möglich Angepasster Befehlssatz für Steueraufgaben (in, out) Wenig Speicher Geringer Stromverbrauch Versteckt in Alltagsgeräten (Kaffeemaschine, Handy, Smartcard,...) 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 3
ATmega640 Features max. 16 MHz Taktfrequenz (aber fast 16 MIPS!) Hardwaremultiplizierer 64 kb Flash-Speicher (Programmspeicher) 8 kb SRAM 4 kb EEPROM 16-Kanal 10-Bit-ADC 6 Counter 4 Hardware-PWM-Ausgänge 4 USARTs... 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 4
ATmega640 Programm ist im Flash-Speicher abgelegt Program Counter zeigt auf aktuellen Befehl im Speicher Recheneinheit ( Arithmetic Logic Unit, ALU) Führt alle Rechenoperationen aus (Addieren, Subtrahieren, Shiften,...) Liest Operanden aus Register und schreibt Ergebnis in Register Operation wird durch Inhalt des Instruction Registers vorgegeben Abbildung: Datenblatt ATmega640 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 5
myavr-board Stamp mit Mikrocontroller 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 6
myavr-board Programmieradapter 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 7
myavr-board LEDs 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 8
myavr-board Sieben-Segment-Anzeige 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 9
myavr-board DIP-Schalter 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 10
myavr-board Taster 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 11
myavr-board Joystick 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 12
myavr-board Lautsprecher 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 13
myavr-board Potentiometer 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 14
myavr-board Fotosensor 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 15
myavr-board Graphikdisplay 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 16
Hello World Ein einfaches Programm Programmierung in Assembler Einbinden von Header-Dateien:.include <Dateiname> Befehle: ldi <reg>, <val> (load immediate) Lädt Wert <val> in Register <reg> out <port>, <reg> (output) Schreibt Inhalt eines Registers in Port rjmp <label> (relative jump) Springt zum Label Kommentare beginnen mit ; Labels definieren Abschnitte im Code ende: (Markiert das Ende) 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 17
Hello World Das Programm.include "m640def.inc".org 0x000 ldi r16, 0xFF out DDRD, r16 ldi r16, 0x01 out PORTD, r16 ; Data Direction Register setzen ; In Register 16 Wert 0xFF laden ; Inhalt von r16 in DDRD schreiben ; LED einschalten ; In Register 16 Wert 1 laden ; Inhalt von r16 in PORT D schreiben ende: rjmp ende ; Endlosschleife 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 18
AVR Studio AVR Studio (IDE) starten Neues Projekt erstellen Atmel AVR Assembler Name des Projekts eintragen AVR Simulator auswählen Atmega640 als Device wählen Programm schreiben oder.c-datei laden Assemblieren (F7) :020000020000FC :0A0000000FEF0AB901E00BB9FFCFC2 :00000001FF 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 19
Simulation Simulation (Debugging) starten (Strg-Shift-Alt-F5) Schrittweise den Code ausführen (F11) I/O-View (rechts) zeigt die Änderungen im Controller an 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 20
Programm auf myavr Board MK3 brennen Alle blauen Jumper öffnen Programm assemblieren (F7) Hexfile Tools Program AVR Connect... STK500 und COM-Port wählen Unter 'Flash' das Input Hexfile auswählen 'Program' wählen, um Hexfile zu brennen Programm wird sofort ausgeführt Resetknopf startet Programm neu 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 21
Hello World in AVR-GCC Gleiche Funktionalität in C programmieren: Neues Projekt erstellen, wie zuvor Aber 'AVR GCC' auswählen Programmcode: #include <avr/io.h> // Enthält alle Definitionen int main(void) { // LED einschalten DDRD = 0xff; // Setze Port D auf Ausgang PORTD = 0x1; // Schreibe 1 an Port D } while(1) ; return 0; // Endlosschleife // Wird nie erreicht 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 22
Kompilieren und brennen Kompiliervorgang starten (F7) Hex-File brennen wie zuvor Wichtig: Hex-File muss für jedes Projekt neu ausgewählt werden! STK500 Fenster nicht schließen, sondern minimieren, dann kann wieder mit programmiert werden Simulation ist auch wie zuvor möglich 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 23
Port I/O Ermöglicht Digitale Ein-/Ausgabe über einzelne Anschlüsse ( Pins ) des Controllers Pins sind zu Gruppen ( Ports ) zusammengefasst (meist 8er-Gruppen) Zuschaltbare interne Pull-up-Widerstände Schaltungsprinzip (für Anschluss eines Tasters): Abbildung: http://www.mikrocontroller.net/articles/avr-tutorial:_io-grundlagen 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 24
Port I/O Gesteuert über drei Register: Data Direction Register (DDxn) 0 bedeutet Eingang 1 bedeutet Ausgang Port Input Pins (PINxn) Im Prinzip nur lesbar Schreiben ändert Zustand von DDxn Data Register (PORTxn) Wert der ausgegeben wird 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 25
Port I/O Globale Pull-up disable -Funktion (PUD) im MCUCR-Register Ausgänge zeigen im Detail folgendes Verhalten: Tabelle: Datenblatt ATmega640 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 26
Port I/O Pull-up-Widerstand Bildquelle: Datenblatt ATmega640 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 27
Port I/O Data Register Bildquelle: Datenblatt ATmega640 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 28
Port I/O Port Input Register Bildquelle: Datenblatt ATmega640 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 29
Port I/O Data Direction Register Bildquelle: Datenblatt ATmega640 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 30
Bitmanipulationen 8-Bit Register 7 6 5 4 3 2 1 0 Darstellung im Binärsystem 0 0 0 0 0 0 0 0 Nach Reset genullt Setzen des Wertes entweder dezimal oder hexadezimal Bsp: PORTA = 11; oder PORTA = 0xB; 7 6 5 4 3 2 1 0 0 0 0 0 1 0 1 1 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 31
Bit-Tabelle Eine Stelle hexadezimal entspricht vier Bits Deshalb Umrechnung recht einfach Selten Benutzung von Dezimalwerten für Bitmanipulationen Intuitive Variante: Bitverschiebungen Dez Hex Binär 0 0x0 0000 1 0x1 0001 2 0x2 0010 3 0x3 0011 4 0x4 0100 5 0x5 0101 6 0x6 0110 7 0x7 0111 8 0x8 1000 9 0x9 1001 10 0xA 1010 11 0xB 1011 12 0xC 1100 13 0xD 1101 14 0xE 1110 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 32 15 0xF 1111
Bit-Shifts (<<, >>) Shift nach links Entspricht Multiplikation mit 2 Bsp: a = 0x2; a << 1; Von rechts mit 0 gefüllt Shift nach rechts Entspricht Division durch 2 Bsp: a = 0x10; (16) a >> 2; (4) Von links mit 0 gefüllt 7 6 5 4 3 2 1 0 0 0 0 0 0 0 1 0 7 6 5 4 3 2 1 0 0 0 0 0 0 1 0 0 7 6 5 4 3 2 1 0 0 0 0 1 0 0 0 0 7 6 5 4 3 2 1 0 0 0 0 0 0 1 0 0 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 33
Bits einzeln setzen Einfache Zuweisung überschreibt Zustand des Registers Bsp: a = 0x4; a = 0x2; Kombinierte Operation aus Shift und ODER Setzt ein bestimmtes Bit und lässt andere unberührt Bsp: a = (1 << 4); Setzt Bit Nr. 4 zusätzlich wegen ODER- Verknüpfung 7 6 5 4 3 2 1 0 0 0 0 0 0 1 0 0 7 6 5 4 3 2 1 0 0 0 0 0 0 0 1 0 7 6 5 4 3 2 1 0 0 0 0 0 0 0 1 0 7 6 5 4 3 2 1 0 0 0 0 1 0 0 1 0 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 34
Bits einzeln löschen Einfache Zuweisung überschreibt Zustand des Registers Bsp: a = 0x7; a = 0x0; Kombinierte Operation aus Shift, NOT und UND Löscht ein bestimmtes Bit und lässt andere unberührt Bsp: a = 0x7; a &= ~(1 << 2); Löscht Bit Nr. 2 7 6 5 4 3 2 1 0 0 0 0 0 0 1 1 1 7 6 5 4 3 2 1 0 0 0 0 0 0 0 0 0 7 6 5 4 3 2 1 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1 0 0 1 1 1 1 1 0 1 1 7 6 5 4 3 2 1 0 0 0 0 0 0 0 1 1 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 35
Links (Hardwaredokumentation) Datenblatt ATmega640 Datenblatt Stamp Technische Beschreibung myavr-board mk3 Datenblatt LCD-Display Datenblatt LCD-Controller 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 36
Links (Entwicklungstools) Für Windows: WinAVR AVR Studio Für Linux: AVR GCC avrdude KontrollerLab (IDE für Linux/KDE) Sonstiges: AVR libc Dokumentation 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 37
Aufgaben Zweite und dritte LED an Port D leuchten lassen Mehrere LEDs leuchten lassen LEDs an Port L gezielt leuchten lassen (nur die 4. oder 5., ) Bit setzen: PORTx = (1 << bit) Bit löschen: PORTx &= ~(1 << bit) LEDs an Port L hochzählen lassen (binär oder Lauflicht) Variablen werden wie in C definiert, allerdings Typen mit definierter Größe: uint8_t (8 bit unsigned), uint16_t (16 bit unsigned) LEDs an Port L mit Delay hochzählen lassen Delay: _delay_ms(millisekunden) _delay_us(mikrosekunden) Was passiert wenn man die Endlosschleife am Ende weglässt? 08/30/10 Fachbereich Physik Institut für Kernphysik Bastian Löher, Martin Konrad 38