Mikrontrolér (MCU) ATmega328P obsahuje tri vstupno/výstupné porty: PORTB, PORTC a PORTD. Portom môžeme rozumieť skupinu vývodov, ktoré sú dostupné z vonkajšej strany MCU. Každý z portov má 8 bitov (8 vývodov). Každý z vývodov môžeme nastaviť ako vstupný alebo výstupný, prípadne môže plniť nejakú špecifickú funkciu ako napr. komunikačný vývod rozhrania UART. Na obrázku nižšie je ekvivalentná schéma zapojenia vývodu. Každý vývod obsahuje ochranné diódy a nastaviteľný pull-up rezistor.

Na prácu s vstupno/výstupnými portami slúžia tri registre: PORTx (Data Register), DDRx (Data Direction Register) a PINx (Port Input Pins), kde x reprezentuje písmeno portu, t.j. B, C alebo D. Registre PORTx a DDRx umožňujú čítanie a zápis jednotlivých bitov, register PINx je určený iba na čítanie. Zápis do registra PINx spôsobí zmenu hodnoty zodpovedajúceho bitu v dátovom registri PORTx.
Register DDRx slúži na nastavenie „smeru“ daného vývodu, t.j. či je vývod vstupný alebo výstupný. Jednotlivé bity tohto registra sú označené ako DDxn, kde n je poradové číslo daného bitu v registri DDRx. Ak je hodnota bitu DDxn nastavená na logickú jednotku, tak daný vývod n bude nakonfigurovaný ako výstupný. Naopak, ak je hodnota bitu nastavená na logickú nulu, tak je vývod n konfigurovaný ako vstupný.
V prípade zápisu do registra PORTx môžu nastať dve rôzne situácie vzhľadom na stav príslušného registra DDRx:
- V prípade, že je vývod portu nastavený ako výstupný (DDxn=log.1), tak zápisom logickej jednotky na príslušný bit dátového registra (PORTxn=log.1) dochádza k nastaveniu logickej jednotky (vysokej úrovne napätia) na príslušnom vývode. V prípade zápisu logickej nuly (PORTxn=log.0) dochádza k nastaveniu logickej nuly (nízkej hodnote napätia) na danom vývode.
- V prípade, že je vývod portu nastavený ako vstupný (DDxn=log.0), tak zápisom logickej jednotky na príslušný bit dátového registra (PORTxn=log.1) dochádza k aktivácii pull-up rezistora na danom vývode. V prípade, že je bit dátového registra nastavený na logickú nulu (PORTxn=log.0), tak je pull-up na danom vývode nezapojený.
Stav daného vývodu je možné zistiť čítaním bitu vstupného registra PINxn bez ohľadu na nastavenie bitu DDxn v registri DDRx. Zápis logickej jednotky na bit PINxn spôsobuje zmenu hodnoty bitu PORTxn bez ohľadu na stav bitu DDxn.
Nižšie sú uvedené všetky registre, ktoré sa používajú na konfiguráciu vývodov. Pri popise registrov je v prvom riadku uvedené poradové číslo bitu. O riadok nižšie je uvedený názov daného bitu (orámovaná časť). Na ďalšom riadku je uvedené, či je bit určený na zápis (W), čítanie (R) alebo pre čítanie aj zápis (R/W). V poslednom riadku je uvedená prednastavená hodnota bitu (po resete alebo pripojení mikrokontroléra na napájanie). Väčšinou je táto hodnota nulová, ale môže byť aj jednotková, preto treba vždy túto hodnotu skontrolovať v datasheete! Ak ešte nemáte skúsenosti s nastavovaním alebo zisťovaním stavu bitov v registroch, tak prejdite na prácu s registrami a dozviete sa viac.
PORTB, DDRB, PINB - Registre slúžiace na konfiguráciu vstupno/výstupných vývodov portu B.



PORTC, DDRC, PINC - Registre slúžiace na konfiguráciu vstupno/výstupných vývodov portu C.
Pozor! Port C má iba 7 vývodov!



PORTD, DDRD, PIND - Registre slúžiace na konfiguráciu vstupno/výstupných vývodov portu D.



#define F_CPU 8000000UL //definícia frekvencie MCU, nutné pre knižnicu delay.h
#include <avr/io.h>
#include <util/delay.h>//knižnica pre _delay_ms()
int main(void)
{
DDRB=255;//dekadický zápis, všetky vývody portu B ako výstupné
while (1)
{
PORTB|=(1<<PORTB0);//zasvietenie LED0
_delay_ms(500);//pauza 500ms
PORTB&=~(1<<PORTB0);//zhasnutie LED0
_delay_ms(500);//pauza 500ms
}
}
#define F_CPU 8000000UL //definícia frekvencie MCU, nutné pre knižnicu delay.h
#include <avr/io.h>
#include <util/delay.h>//knižnica pre _delay_ms()
int main(void)
{
DDRB=255;//všetky vývody portu B ako výstupné - LEDky
DDRD=0;//všetky vývody portu D ako vstupné - tlačidlá
PORTD=255;//zapnutie pull-up rezistorov na celom porte D, nestlačené tlačidlo má log. 1
uint8_t blikLED=0;//ak blikLED=0 -> bliká LED0; ak blikLED=1 -> bliká LED1
while (1)
{
//zistím, či bolo stlačené S7
if (PIND&(1<<PIND7)==0)//stlačením tlačidla privediem log. 0 na PIND7
{
blikLED=0;//bude blikať LED0
}
//zistím, či bolo stlačené S6
if (PIND&(1<<PIND6)==0)//stlačením tlačidla privediem log. 0 na >PIND6
{
blikLED=1;//bude blikať LED1
}
if (blikLED==0)
{
PORTB|=(1<<PORTB0);//zasvietenie LED0
_delay_ms(500);//pauza 500ms
PORTB&=~(1<<PORTB0);//zhasnutie LED0
_delay_ms(500);//pauza 500ms
}
else
{
PORTB|=(1<<PORTB1);//zasvietenie LED1
_delay_ms(500);//pauza 500ms
PORTB&=~(1<<PORTB1);//zhasnutie LED1
_delay_ms(500);//pauza 500ms
}
}
}