# Portas de Entradas/Saídas Digitais

As portas de I/O podem ser endereçadas bit a bit. Os registradores que exercem essas funções são: P0, P1, P2 e P3. Esses registradores estão localizados nos endereço 80H, 90H, A0H e B0H. Cada bit desses registradores representa um pino que pode funcionar como entrada digital ou saída digital.

### Estrutura Interna de um Pino

A Figura abaixo ilustra a estrutura interna de um pino da porta P1. Basicamente, este circuito é composto por um elemento de memória (P1.X latch) e de sinais de controle. Os sinais de controle têm como função indicar a operação realizada, isto é, leitura ou escrita do estado do pino.

![Esquema de um pino da porta P1 \[1\].](https://www.embarcados.com.br/wp-content/uploads/2016/10/PinP1.png)

A saída invertida do latch é conectada a um transistor. Quando o bit N da porta está em 1, os pinos ficam em nível lógico 1 devido ao resistor de pullup interno. Nessa condição, o pino funciona como uma entrada e seu estado dependerá do que estiver conectado externamente. Agora, quando o bit N da porta está em 0, o pino funciona como um saída em nível lógico 0.

### Acessando as Portas do 8051

Várias instruções podem ser utilizadas para acessar as portas. Instruções de movimentação de dados podem ser utilizadas para escrever diretamente nos 8 bits da porta, ou realizar a leitura desses 8 bits. Porém, as instruções booleanas podem ser utilizadas quando é necessário realizar a leitura ou escrita de um único bit. Isso é possível pois as portas podem ser endereçadas bit a bit. De modo geral:

* MOV \<porta>,\<valor>: Movimentação de dados (8 bits), em que \<porta> = \<valor>;
* MOV \<valor>,\<porta>: Movimentação de dados (8 bits), em que \<valor> = \<porta>;
* SETB \<bit>: faz bit = 1;
* CLR \<bit>  : faz bit = 0;
* JB \<bit>,\<label>: testa bit, e se for igual a 1 salta para o label;
* JNB \<bit>,\<label>: testa bit, e se for igual a 0 salta para o label.

A utilização dessas instruções é mostrada no exemplo abaixo, em que uma chave está conectada ao pino P1.4.

```
       ORG 40h ; endereço inicial do programa
       MOV A, #1 ; move valor 1 para Acumulador
LOOP:
       MOV P1, A ; move conteúdo do Acumulador para P1
       SETB P1.4 ; faz P1.4 = 1 (pull-up interno) - pino de entrada
       JNB P1.4, CH_PR ; testa se P1.4 é igual a zero. Se sim, vai para CH_PR
       ;Operações para Chave ==1
       SJMP LOOP ; pula para LOOP
CH_PR:
       ; Operações para Chave==0
       SJMP LOOP ; pula para LOOP
 
       END
```

### Interrupções Externas

Dois pinos da porta 3 (P3.2-INT0 e P3.3-INT1) podem ser utilizados para gerar uma interrupção externa. Nesse caso, o registrador TCON, ilustrado na Figura abaixo, deve ser utilizado para configurar o modo de disparo da interrupção, isto é, se o evento será detectado por nível baixo ou por borda de descida. Nesse registrador também são definidas as flags que indicam qual interrupção ocorreu. O registrador TCON pode ser endereçado bit a bit e está localizado no endereço 88H.

![Registrador TCON \[1\].](https://www.embarcados.com.br/wp-content/uploads/2016/10/SFR_TCON.png)

Os quatros bits menos significativos são utilizados para as interrupções externas:

* IE1: Interrupt 1 Edge Flag – Seu valor é determinado pelo hardware.
  * 0: Quando a rotina de interrupção é processada.
  * 1: Quando o hardware detecta o evento de interrupção externa.
* IT1: Interrupt 1 Type Control.
  * 0: trigger por nível baixo.
  * 1: trigger por borda de descida.
* IE0: Equivalente ao IE1 (para rotina localizada no endereço 0013H).
* IT0: Equivalente ao IT1.

A configuração da INT0 é mostrada no trecho de código abaixo.

```
       ORG 0h ; endereço inicial do programa
       SJMP INICIO ; salta para INICIO
       ORG 3h ; endereço reservado para Interrupção Externa 0
       SJMP ROTINA ; salta para ROTINA
INICIO:
       MOV TCON, #1 ; move valor 1 para TCON (configura INT0 para borda de descida)
       MOV IE, #81H ; move valor 81H para IE (habilita interrupção externa 0)
       SJMP $ ; loop infinito
 
ROTINA: ; rotina de interrupção
      ;Código da rotina de interrupção
      RETI ; retorno de rotina de interrupção
 
      END
```

&#x20;A configuração da INT1 é mostrada no trecho de código abaixo.

```
        ORG 0 ; endereço inicial do programa
        SJMP INICIO ; salta para INICIO
        ORG 13H ; endereço reservado (interrupção externa 1)
        SJMP ROTINA ; salta para ROTINA
INICIO:
        MOV TCON, #04H ; configura a interrupção externa 1 (borda de descida no pino INT1)
        MOV IE, #84H ; habilita interrupção externa 1
        SJMP $ ; espera (LOOP)
 
ROTINA: ; Rotina de interrupção
        ; Código da rotina de interrupção
        RETI ; retorno da rotina interrupção
 
        END ; fim do programa
```
