ATmega16 possui 32 pinos de E/S para comunicação com dispositivos externos.   Antes de fazer interface com dispositivos externos, esses pinos devem ser configurados como pinos de entrada ou saída.  Este artigo demonstra a operação básica de E/S do ATmega 16 usando LEDs.
Todas as quatro portas podem ser configuradas para ler uma entrada de algum dispositivo externo ou para fornecer saída para qualquer dispositivo externo conforme a aplicação.  Por exemplo, um switch está conectado a um pino específico, esse pino deve ser configurado como entrada para ler os valores do switch (dispositivo externo neste caso) e se você estiver conectando um LED a qualquer pino da porta, então esse pino específico deve ser configurado como saída para transmitir o sinal ao LED (dispositivo externo neste caso).  Uma única porta pode ser configurada de forma que alguns dos pinos da mesma porta sejam de entrada e outros de saída.
Configurando portas IO:
Cada porta (PORTx, x = A ou B ou C ou D) dos microcontroladores AVR possui três registros associados:
1.      DDRx:  Registrador de direção de dados, para definir a direção de cada pino do PORTx e configurá-lo para ser como entrada ou saída.
2.      PORTx:  Os valores que devem ser fornecidos na saída da porta são escritos neste registrador.  Esses valores atuam como entrada para o dispositivo conectado na porta de saída do microcontrolador (através dos pinos configurados de saída PORTx).
3.      PINx:  Este registro armazena o valor de entrada do hardware externo conectado, quando a porta está configurada como porta de entrada.  Os dados de entrada são lidos do registro PINx.
Portanto, a primeira etapa na configuração ou inicialização de qualquer porta IO é definir sua direção no registro de direção de dados (DDRx) para definir o comportamento de pinos individuais como entrada ou saída.  Um valor alto (1) em qualquer bit do registro DDRx significa que o pino correspondente está definido como saída e vice-versa.
Exemplo:  Considerando o cenário switch-LED, suponha que um switch esteja conectado ao Pin5 (PORTD.4) do PORTD e o LED esteja conectado ao Pin8 (PORTD.7) do PORTD.  Agora precisamos inicializar os pinos de acordo.  Os outros pinos do PORTD não são utilizados neste caso, portanto podem ser ignorados a partir de agora.
PASSO 1:  Para configurar PORTD.4 como entrada o valor do Pin-5 (DDRD.5) no registro DDRD é colocado em 0.
| DDRD.7 | DDRD.6 | DDRD.5 | DDRD.4 | DDRD.3 | DDRD.2 | DDRD.1 | DDRD.0 | 
| – | – | 0 | – | – | – | – | – | 
 Fig. 2: Valor do bit do registro DDRD para definir PORTD como entrada no AVR
Passo 2: Para inicializar PORTD.7 como saída, o valor do Pin-8 (DDRD.7) no registro DDRD é definido como 1.
| DDRD.7 | DDRD.6 | DDRD.5 | DDRD.4 | DDRD.3 | DDRD.2 | DDRD.1 | DDRD.0 | 
| 1 | – | 0 | – | – | – | – | – | 
 Fig. 3: Valor do bit do registro DDRD para definir PORTD como saída no AVR
Etapa 3:  O restante dos pinos pode ter qualquer valor, pois não estão sendo utilizados neste caso.  Os valores padrão do registro DDRx são 0 para cada pino, ou seja, todas as portas dos microcontroladores AVR são inicializadas como entrada.
| DDRD.7 | DDRD.6 | DDRD.5 | DDRD.4 | DDRD.3 | DDRD.2 | DDRD.1 | DDRD.0 | 
| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 
  Figura 4: 
Portanto, o valor de DDRD será inicializado como 0x80.

Figura 5: 
O comando acima também pode ser escrito desta forma:

Figura 6: 
Onde, 0b é o símbolo usado para representar números binários e a seguir está o valor real de 8 bits.
Configurando o valor de pull-up:
Todas as quatro portas do Atmega16 são equipadas com resistores pull up internos controlados por software.  Cada pino das portas pode ser obtido definindo os valores no registro PORTx.  A tabela a seguir ilustra o estado real do pino com diferentes combinações de valores DDRx e PORTx.
| DDRx | PORTx | Estado de E/S | Puxar para cima | Descrição | 
| 0 | 0 | Entrada | Não | Pinos PORTx definidos como entrada e pull-ups desabilitados. | 
| 0 | 1 | Entrada | Sim | Pinos PORTx definidos como entrada com pull up habilitado | 
| 1 | 0 | Saída | Não | Pinos PORTx definidos como saída e pull-ups desabilitados. | 
| 1 | 1 | Saída | Sim | Pinos PORTx definidos como saída com pull ups habilitados. | 
Fig. 7: Status do pino para diferentes combinações de bits de DDRx e PORTx na interface de LED
Exemplo: Os comandos a seguir podem ser usados para desabilitar e habilitar pull-ups no PORTD.
PORTD = 0xFF;         //Pinos PORTD puxados para cima.
PORTD = 0x00;          //Desativa os registros pull-up.
Para entender os comandos acima, um experimento simples de piscar o LED é explicado abaixo.
Descrição do circuito:
Conecte o circuito conforme mostrado no diagrama de circuito.  Não há cristal no circuito.  Este projeto utiliza o cristal embutido do microcontrolador AVR, evitando assim a necessidade de cristal externo.  O valor do cristal interno varia de 1MHz a 8MHz, que pode ser ajustado usando os fusíveis.  (Os leitores podem conectar o cristal externo, mas modificar os bits dos fusíveis de acordo. Os bits dos fusíveis são explicados em artigos posteriores). 
Explicação do código: 
#include
Para incluir todos os arquivos de entrada e saída do microcontrolador AVR.
#include
WinAvr possui uma função integrada para fornecer atraso.  Para usar as funções de atraso, inclua o arquivo de cabeçalho acima.
DDRA=0xFF;
Para tornar a porta A como porta de saída
PORTA=~PORTA;
Seja qual for o valor da PORTA, elogie-o e envie de volta para a PORTA.
_atraso_ms(1000);
Uma função de atraso fornece um atraso de 1000 milissegundos.
Para entender a compilação e execução do programa acima, consulte o tutorial Trabalhando com AVRstudio.
O que deve ser observado?
Da mesma forma, um código pode ser para o LED piscar em todas as quatro PORTAS.  Observa-se que todos os pinos estão funcionando corretamente, exceto os pinos PC2, PC3, PC4 e PC5.  A razão é que os microcontroladores AVR possuem JTAG embutido, que precisa ser desabilitado para usar esses pinos como pinos de E/S.  A desativação do JTAG é explicada em um artigo separado.
Código-fonte do projeto
###
// Programa para piscar LED usando microcontrolador AVR (ATmega16)
###
Diagramas de circuito
| Diagrama de circuito de como fazer a interface do LED com o microcontrolador AVR-ATmega16 |  | 
Componentes do Projeto
- ATmega16
- LIDERADO
 
              