Parallel-IO Ansteuerung Miniprojekt Lauflicht Ports am ATmega128 PortE (PE7...PE0) alternativ, z.b. USART0 (RS232) 1 Pin von PortC Port C (PC7...PC0) 1
Parallel-IO-Port "Sammelsurium" verschiedener Speicher (Register) zur Anbindung von externen Komponenten (Lesen/Schreiben) ATmega128-7 IO-Ports A...G - 8 Bit je Port A... F (8 Leitungen steuerbar), 4 Bit PortG - jedes Port-Bit (Leitung) ist in der Grundfunktion einzeln konfigurierbar als INPUT (mit/ohne Pull-up) oder OUTPUT - jeder Port verfügt über alternative Funktionalität, z.b.: Eingang für ADC, serielle Schnittstelle, externer Timer- Anschluss... Register liegen im IO-Bereich des SRAM (je Port 3 feste Adressen) Register für Grundfunktion (X entspricht A...G): - DDRX: 8-Bit Data-Direction-Register (bestimmt, ob Port zu INPUToder OUTPUT-Zwecken genutzt wird) - PORTX: 8-Bit Output-Register (oder Pull-up setzen) - PINX: 8-Bit Input-Register Pin n von PortX ist Ausgang Bits der Port-Register DDRX, PORTX, PINX VCC Pull-Up in nterner Datenbus DDRXn 1 PORTXn? PINXn? S2 S3 S1 z.b. Pin 5 von Port C phys. (PC5) Pin PXn Direction: Pull-up: OUTPUT OFF n... Pin-Nummer 7... 0 X... Port-Name A... F 2
Pin n von PortX ist Eingang VCC Pull-Up interner Datenbus DDRXn 0 PORTXn 0 PINXn? S2 S1 S3 phys. PXn Direction: INPUT Pull-up: OFF Einstellung bei RESET n... Pin-Nummer 7... 0 X... Port-Name A... F Pin n von PortX ist Eingang VCC Pull-Up in nterner Datenbus DDRXn 0 PORTXn 1 PINXn? S2 S1 S3 phys. PXn Direction: Pull-up: INPUT ON n... Pin-Nummer 7... 0 X... Port-Name A... F 3
IO-Adresse 0x0000 0x003F IO-Port-Register des AVR RAM-Adresse (0x0000) (0x0020) (0x0060) RAM Register I/O ext. I/O +0x0020 PORTE: 0x03 (0x0023) PINE: 0x02 (0x0022) DDRE: 0x01 (0x0021)... PORTA: 0x18 (0x0038) PINA: 0x19 (0x0039) DDRA: 0x1A (0x003A) RAM PORTF: (0x62) PORTG: (0x65) RAMEND 1 Byte Angabe im Datenblatt (RegisterSummary): gleiche Adresse, einmal mit einmal ohne den Offset 0x0020 Verwendung der Parallel-IO-Ports vom Programm Programm Register PORTB Register PIND z.b. angeschlossene LEDs z.b. angeschlossene Tasten 4
Verwendung der Parallel-IO-Ports vom Programm Ausgabe von Daten auf IO-Port: - Programm stellt Port auf Ausgabe ein (Initialisierung) - Programm schreibt Byte in die IO-Adresse des Ports (Port-Register) - Bitwerte erscheinen an den Port-Pins des Controllers (High bzw. Low-Pegel) - an die Pins angeschlossene Bauteile/Geräte werden angesteuert (z.b. LEDs) Eingabe von Daten über IO-Port: - Programm stellt Port auf Eingabe ein (Initialisierung) - angeschlossene Bauteile/Geräte schalten die Pins des Controllers auf High bzw. Low-Pegel (z.b. Tasten) - Bitwerte erscheinen im Pin-Register des Controllers - Programm liest Byte von der IO-Adresse des Ports (Pin-Register) Controller-spezifische Konstanten Register-Namen (Bit-Namen) aus dem Datenblatt (Register-Summary) des Controllers ersichtlich zu jedem Register (Bit) sind im h-file für den spezifischen Prozessor Konstanten definiert - für prozessorspezifische Adresse des Registers - für Bitnummern des Registers 5
Controller-spezifische Konstanten Controller-spezifische h-files sind zu finden in \WINAvr\avr\include\avr - Beispiel: ATmega128 iom128.h spezifische IO-Adresse aus Datenblatt (Register-Summary) jedes Programm, was IO des Controller verwendet - includiert \avr\io.h, das dafür sorgt, dass das für den Controller passende Controller-spezifische h-file includiert wird #include <avr\io.h> - verwendet statt Adressen (Bit-Nummern) die Namen der Konstanten - Übersichtlichkeit (keine magic numbers) - Flexibilität (Programm, das PORTA nutzt läuft auch auf anderem Prozessor, der PORTA besitzt, z.b. ATmega32) Miniprojekt Lauflicht + 8 * Taster 1 Port-Pin PortD C 8 Port-Pins PortB 8 * LED Quarz + - Batterie Port-Pin: high... LED ist aus low... LED ist an 6
Spezifikation Input: eine Taste an PortD Output: 8 LEDs an PortB genau eine LED ist an Tastendruck => nächste LED geht an Arbeitsschritte Für alle Aufgaben grundsätzlich: - grobe Programmstruktur entwerfen - Vorüberlegungen zu einzelnen Problemen des Entwurfs - Verfeinerung des Entwurfs (möglichst viele Funktionen verwenden, d.h. strukturiert programmieren) - Programmieren - Testen schrittweises Vorgehen: 1. Lauflicht ohne Tastenweiterschaltung (nur Ausgabe auf Port) 2. Lauflicht mit Tastenweiterschaltung (Eingabe von PortD und Ausgabe auf PortB) 7
Lauflicht ohne Tastenweiterschaltung Entwurf und Vorüberlegungen Programmablauf für Mikrocontroller Definieren und Initialisieren der benötigten Variablen Initialisieren der benötigten Komponenten Mikrocontroller- Programme laufen in endlosen Schleifen! Programm, das mit Komponenten und Variablen arbeitet 8
Grober Entwurf Lauflicht ohne Tastenweiterschaltung Port initialisieren PortB: OUTPUT LED-Variable initialisieren LED an: Bit=0 LED aus: Bit=1 LED-Variable ausgeben LED-Variable weiterschalten warten wie? wie? C-Programme für Mikrocontroller // bindet ein h-file ein, in dem alle IO-Adressen und // Konstanten für den eingestellten Mikrocontroller-Typ // definiert sind #include <avr\io.h> #define F_CPU 1e6 // eingestellte Prozessor-Taktfrequenz // weitere include-anweisungen für benötigte Funktionen der // avr-libc oder eigene Include-Files // Funktionsprototypen für eigene Funktionen int main(void) { // Definieren & Initialisieren der benötigten Variablen // Initialisieren der benötigten Komponenten while(1) // Endlosschleife { // Programm, das mit Komponenten arbeitet } } // eigene Funktionen 9
Schalten des Lauflichts: - Bit-Schiebeoperation in C char var=0x01; Wie? // rechts -> links var = var << 1; // var hat den Wert 0x02 var= 0x80; // links -> rechts var= var >> 1; // var hat den Wert 0x40 Warten, damit das Lauflicht sichtbar wird - Prozessor verbraucht Zeit, in der er nichts tut - Verwenden einer Funktion aus der avr-libc (F_CPU definieren, util\delay.h includieren) void _delay_ms (double ms) Test-Plan 1. nur Initialisierung testen LED0 muss leuchten 2. gesamtes Programm testen Lauflicht muss sichtbar sein 10
Lauflicht mit Tastenweiterschaltung Entwurf und Vorüberlegungen grober Entwurf Lauflicht mit Tastenweiterschaltung Port initialisieren LED-Variable initialisieren PortB: OUTPUT PortD: INPUT mit Pullup-Widerständen LED an: Bit=0 LED aus: Bit=1 LED-Variable ausgeben LED-Variable weiterschalten Warten auf Taste Taste gerückt: Bit=0 Taste losgelassen: Bit=1 11
U T t L Warten auf Taste (PortD) Taste U TasteH drücken PINDn=1 Taste U TasteL loslassen PINDn=0 Register PIND - enthält den Wert 0xff, falls keine Taste gedrückt ist - enthält einen Wert verschieden von 0xff, falls mindestens eine Taste gedrückt ist ob eine bestimmte Taste gedrückt wurde, erfährt man durch einen Vergleich mit dem entsprechenden Bitmuster - Beispiel Taste SW2: char sw, muster=(1<<pd2); // Bit-Konstante aus h-file sw=pind; if(sw == muster) //Taste SW2 gedrückt t Flussdiagramm Warten auf Taste (Prellzeit) Warten start Warte auf Taste gedrückt Warte auf Taste losgelassen erkennt Taste losgelassen erkennt Taste gedrückt U TasteH erkennt Taste gedrückt erkennt Taste losgelassen PINXn=1 Warte Prellzeit ab Warten fertig U TasteL Prellzeit einige ms PINXn=0 t 12