Ein-/Ausgangsports
(Hier geht's zum Ein-/Ausgangsport beim Attiny)
Der direkte Zugriff auf die Ports des Uno erlaubt wesentlich schnellere Ein-/Ausgabe bei den einzelnen Pins als mit den Arduino-Anweisungen digitalRead() und digitalWrite() und man kann mit einer Anweisung eine ganze Gruppe von Pins quasi gleichzeitig setzen oder lesen.
Der Atmega328P-Mikrocontroller des Arduino Uno oder Nano besitzt 3 Ports: Port B, C und D. Nachfolgende Abbildung zeigt die Zuordnung der Binär-Pins D0 bis D13 und der Anlog-Pins A0 bis A5 zu den Ports:
(Stehen bei einer Anwendung zu wenige Binär-Pins zur Verfügung, können - sofern nicht anderwertig verwendet - auch die Analog-Pins als Binär-Pins verwendet werden. So werden z.B. standardmäßig die Pins A4 und A5 als "Binärsignale" für die I2C-Schnittstelle verwendet.)
Zur Programmierung stehen je Port 3 Register zur Verfügung:
1. Data Direction Register X (DDRX):
Die einzelnen Bits geben die an, ob der jeweilige Pin als Eingang oder als Ausgang fungiert:
DDXn = 0 -> Eingang
DDXn = 1 -> Ausgang
2. Port X Data Register (PORTX)
Wenn ein Pin im Data Direction Register X (DDRX) als Ausgang definiert ist:
PORTXn = 0 -> Ausgabe von logisch "0"
PORTXn = 1 -> Ausgabe von logisch "1"
Wenn ein Pin im Data Direction Register X (DDRX) als Eingang definiert ist:
PORTXn = 0 -> Interner Pullup-Widerstand deaktiviert
PORTXn = 1 -> Interner Pullup-Widerstand aktiviert
3. Port X Input Pins Register (PINX)
Ist ein Pin im Data Direction Register X (DDRX) als Eingang definiert, gibt PINXn den Zustand des Pins zurück. Der interne Pullup-Widerstand für den jeweiligen Pin kann mit dem Port X Data Register (PORTX) aktiviert oder deaktiviert werden.
X ........ Port B, C oder D
n ........ Bit Nr. 0 - 7
Beispiele:
Setzen der Binär-Pins D2 und D7 als Ausgang:
(D2 und D7 sind die Bits 2 und 7 am Port D)
DDRD |= B10000100; // Nur Bit 2 und 7 werden verändert
oder
DDRD |= (1 << DDD2); //D2 ist Ausgang
DDRD |= (1 << DDD7); //D7 ist Ausgang
oder
DDRD |= (1 << DDD2) | (1 << DDD7); //D2 und D7 sind Ausgaenge
Ausgabe von logisch "1" und logisch "0" am Beispiel Binär-Pin D10:
(D10 ist das Bit 2 am Port B)
//D10 als Ausgang setzen
DDRB |= (1 << DDB2);
//D10 auf "1" setzen
PORTB |= (1 << PORTB2);
//D10 auf "0" setzen
PORTB &= ~(1 << PORTB2);
Einlesen des Binär-Pins D5 mit internem Pullup-Widerstand:
(D5 ist das Bit 5 am Port D)
//D5 als Eingang setzen
DDRD &= ~(1 << DDD5);
//Pullup-Widerstand aktivieren
PORTD |= (1 << PORTD5);
//Abfrage des Eingangs-Pin D5
byte bitStatus = (PIND & (1 << PIND5)) >> PIND5;