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.
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.
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.
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 programaMOV A, #1 ; move valor 1 para AcumuladorLOOP:MOV P1, A ; move conteúdo do Acumulador para P1SETB P1.4 ; faz P1.4 = 1 (pull-up interno) - pino de entradaJNB P1.4, CH_PR ; testa se P1.4 é igual a zero. Se sim, vai para CH_PR;Operações para Chave ==1SJMP LOOP ; pula para LOOPCH_PR:; Operações para Chave==0SJMP LOOP ; pula para LOOPEND
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.
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 programaSJMP INICIO ; salta para INICIOORG 3h ; endereço reservado para Interrupção Externa 0SJMP ROTINA ; salta para ROTINAINICIO: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 infinitoROTINA: ; rotina de interrupção;Código da rotina de interrupçãoRETI ; retorno de rotina de interrupçãoEND
A configuração da INT1 é mostrada no trecho de código abaixo.
ORG 0 ; endereço inicial do programaSJMP INICIO ; salta para INICIOORG 13H ; endereço reservado (interrupção externa 1)SJMP ROTINA ; salta para ROTINAINICIO:MOV TCON, #04H ; configura a interrupção externa 1 (borda de descida no pino INT1)MOV IE, #84H ; habilita interrupção externa 1SJMP $ ; espera (LOOP)ROTINA: ; Rotina de interrupção; Código da rotina de interrupçãoRETI ; retorno da rotina interrupçãoEND ; fim do programa