La comprensione dei Port di input/output contenuti nei chip Atmel permette una veloce manipolazione dei pin di I/O del microcontrollore (molto piu' veloce di quanto si possa ottenere dalle funzioni pinMode(), digitalRead() e digitalWrite() che normalmente utilizziamo). I chip usati sulle schede Arduino (ATmega8, ATmega168 e ATmega368) dispongono di tre Port i cui bit sono mappati sui PIN di Arduino:
Ciascun Port e' controllato da tre registri, che sono anche gia' definiti come variabili nel C usato per arduino. Il registro DDRx (sostituire la x con la lettera B, C oppure D), determina quali pin sono usati come INPUT e quali come OUTPUT. Il registro PORTx (sostituire la x con la lettera B, C oppure D) dispone quali pin di uscita devono essere posti HIGH e quali LOW, mentre il registro PINx (sostituire la x con la lettera B, C oppure D) legge lo stato dei pin collegati al Port che stiamo considerando. La precedente immagine mostra la mappatura dei pin della scheda sui Port del processore.
I registri DDRx e PORTx passono essere entrambi scritti e letti. Il registro PINx corrisponde allo stato degli ingressi e puo' solo essere letto.
PORTD collegato ai pin digitali di Arduino da D0 to D7
PORTB collegato ai pin digitali di Arduino da D8 to D13 (i 2 pin mancanti sono usati per il quarzo del clock)
PORTC collegato ai pin digitali/analogici di Arduino da A0 to A5 (Pin 6 & 7 sono disponibili solo su Arduino Mini)
Ciascun bit di questi registri corrisponde ad un singolo pin; ad esempio il bit 0 di DDRB, PORTB, e PINB si riferisce al pin PB0 (digital pin 8).
(Notare inoltre che alcuni bit di un port possono essere usati per scopi diversi dall'I/O; fare pertanto attenzione a non cambiare i valori corrispondenti a questi bit in nessuno dei tre registri associati al port.)
Riferendoci alla mappatura mostrata nella precedente immagine, il registro del PortD controlla i pin digitali di Arduino da d0 a d7.
DDRD e' il registro di direzione del Port D (digital pins 0-7). I valori dei bit in questo registro stabiliscono se i pin corrispondenti del PORTD sono configurati come INPUT o come OUTPUT, per esempio:
DDRD = B11111110; // setta i pin da 1 to 7 come output, pin 0 come input DDRD = DDRD | B11111100; // questo e' piu' sicuro in quanto imposta i pin da 2 to 7 come output // senza cambiare il valore relativo ai pin 0 e 1, che sono l'RX ed il TX della porta seriale
PORTD e' il registro dello stato dei pin impostati come output. Esempio:
PORTD = B10101000; // setta i pin digitali 7,5,3 HIGH in un solo colpo!!
Sui pin 7, 5 e 3 sara' presente una tensione di 5 volt se tali pin sono stati precedentemente impostati come uscite mediante la funzione pinMode(), oppure se li abbiamo impostati piu' velocemente tramite il registro DDRD (vedi esempio precedente).
PIND invece (PIND è una variabile C dichiarata per default) contiene lo stato di tutti i pin associati a questo PORT (possiamo leggere lo stato dei pin da D0 fino a D7 con una sola istruzione!!).