O 8051, Memória, Entrada/Saída e Interrupções
Autor:. Prof. Dr. Jorge Kinoshita
ver. 1.00 – PCS597 – Agosto/1999
1. Objetivos
Esta apostila possui diversos campos a serem preenchidos no decorrer da aula.
2. O 8051 e sua interface com a memória.
2.1 Memória interna
O 8051 possui RAM e ROM internos.
A ROM interna que vai de 0000 até 0FFFH armazena programa e é usada quando o pino \EA (external adress ativo em low) está desabilitado.
A RAM interna possui 256 bytes divididos em:
2.2 Memória externa
2.2.1. Os pinos da pastilha de memória
A memória EPROM 27(X Kbits) (ex: 27256) se comunica através dos pinos:
\CS – Chip Select
\OE – Output Enable
D0-D7 – Dados de saída (dados lidos).
A memória RAM 62(X Kbits) (ex: 62256) se comunica através dos sinais:
\CS – Chip Select
\OE – Output Enable
\WR – sinal de write
D0-D7 – Dados (dados lidos ou escritos).
2.2.2. Como usar os pinos \CS e o \OE da EPROM/RAM ?
Ao fazer a interligação de uma EPROM ou RAM com o microcontrolador deve-se observar:
o \CS é ativado pela via de endereços. O microcontrolador especifica o endereço com o qual realizará a operação de leitura e escrita. Algum outro circuito (por exemplo: um decodificador) deve gerar os sinais de \CS para as pastilhas de memória e de entrada/saída.
o \OE é ativado pelo sinal de leitura do microcontrolador.
2.2.3. Leitura: os pinos \PSEN e \RD do 8051.
O 8051 possui dois sinais para se fazer a leitura:
\PSEN – é ativo quando o microcontrolador faz a busca de um código a ser executado.
\RD – é ativo quando o microcontrolador faz a leitura de um sinal
Isto é uma peculiaridade deste microcontrolador. Em geral, os microprocessadores possuem apenas um sinal de leitura.
Devido a esta característica o 8051 pode endereçar 64Kbytes de código na EPROM e 64Kytes de dados na RAM.
Figura 1: Esquema 8051 + 64K EPROM + 64K RAM.
Desenhe na aula: Observe que os D0-D7 e A0-A7 são chaveados e por isso é necessário o latch 74373.
Esta interligação é incoveniente durante a fase de desenvolvimento do produto porque não é possível excutar código na RAM. Assim é necessário gravar e regravar a EPROM diversas vezes até que o produto esteja estável. No laboratório utilizamos 32Kbytes para a EPROM que contém o programa monitor e 32Kbytes para dados e/ou programa. Executar programa na RAM é possível desde que o \PSEN e o \RD possam fazer leituras na RAM.
Figura 2: Esquema 8051 + 32K EPROM + 32K RAM. Execução de código na RAM.
Desenhe na aula.
Explique como o monitor faz a carga do programa na RAM e depois executa do ponto de vista dos sinais \RD, \WR e \PSEN.
Resposta: durante a carga o programa é visto como um conjunto de dados que é escrito na RAM e portanto é usado o sinal \WR. Durante a execução (após G8000 por exemplo) o sinal de \PSEN é usado para a leitura dos códigos na RAM.
2.3 Instruções de acesso à memória.
ROM: leitura de código de programa (na execução de instruções) ou leitura de contantes.
Leitura de constante na ROM (externa ou interna depende de EA).
Exemplo do application builder:
A contém um valor de zero a três e é convertido no valor adequado dependendo da tabela abaixo do código.
RELPC: INC A
MOVC A,@A+PC
RET
DB 66H
DB 77H
DB 88H
DB 99H
É possível também fazer a indexação usando o DPTR.
Exemplo:
MOVC A,@A+DPTR
Acesso à RAM interna
MOV 21H,A
ou usando R0 ou R1:
MOV R0,21H
MOV @R0,A
Acesso à RAM externa:
Usando R0 ou R1 (8bits)
MOV R0,#21H
MOVX @R0,A
Usando DPTR (16 bits).
MOV DPTR,#FFF3H
MOVX @DPTR,A
3. 8051 e sua interface com Entrada e Saída.
Existem três formas de se interligar periféricos de Entrada/Saída no 8051:
Exercício: Observe no diagrama lógico em anexo como foi feita a ligação do display no kit 8051.
Obs: Existem alguns microprocessadores que distinguem uma área de memória e uma área para periféricos através de um dos pinos da pastilha. O 8086 e posteriores possuem o pino \IO/M. Estes processadores possuem instruções especiais para se trabalhar com os periféricos de entrada e saída (ex: IN e OUT como em IN 0378H: faz a leitura do dado no port 0378H). O 8051 e o motorola 68000 não possuem instruções deste tipo e os periféricos de entrada e saída são mapeados em memória. Do ponto de vista de programação, as instruções que lidam com os periféricos são as mesmas que lidam com a memória (ex: MOVX no 8051). Neste caso dizemos que os periféricos de entrada e saída estão mapeados em memória.
4. 8051 e o uso de interrupções.
Os microprocessadores geralmente executam as instruções passo a passo. Entretanto, em alguns casos é interessante que uma rotina seja executada (sem que ela tenha sido chamada por nenhuma instrução de software) interrompendo o fluxo normal do programa. O evento que dispara este tipo de rotina, conhecida como rotina de interrupção, é gerado por algum sinal de hardware. Um exemplo é o "timer" em sistemas multiprocessados (exemplo: dentro do Unix ou Windows95) que faz com que cada processo seja executado em apenas uma fração do tempo. Os microcontroladores também possuem esquemas de interrupção.
O tipo de interrupção que acabamos de descrever é conhecido também como "interrupção de hardware". Existe também o termo "interrupção de software" que é gerado por uma instrução de Assembly em processadores como o 68000 e os da família Intel 8086 em diante. Uma interrupção de software é semelhante a uma chamada de subrotina. A diferença está na especificação de onde se encontra a subrotina. Não vamos entrar em detalhes sobre este tipo de interrupção.
4.1. Interrupção no 8051
O 8051 possui 5 fontes de interrupção geradas pelo hardware:
INT0, INT1: duas de dois pinos externos.
TF0, TF1 – duas de dois timer/counters.
TI ou RI – uma da serial.
A cada fonte de interrupção está associada um bit em registradores. Estes bits podem ser setados ou resetados via software, com os mesmos resultados de serem setados ou resetados via hardware.
Todas as interrupções podem ser habilitadas/desabilitadas de acordo com o registrador IE.
IE.7 = EA (EA =0 nenhuma interrupção será reconhecida, EA = 1 depende dos outros flags abaixo).
IE.6 = reservado
IE.5 = ET2 para timer 2
IE.4 = ES para serial.
IE.3 = ET1
IE.2 = EX1
IE.1 = ET0
IE.0 = EX0
Ao ocorrer uma interrupção (por exemplo: o timer zero estoura ou há uma variação de sinal em um dos pinos do 8051 encarregado da interrupção externa) então o microcontrolador para o que estava executando, empilha o endereço de retorno e executa uma rotina que trata esta interrupção. Ao finalizar a rotina (no final da rotina existe a instrução RETI) o endereço de retorno é desempilhado e colocado no PC. O microcontrolador continua a executar o código. Este procedimento é muito semelhante a uma chamada de rotina via software; a diferença é que um sinal de hardware disparou a rotina.
Quando uma interrupção ocorre, o processador deve determinar quem causou a interrupção para chamar a rotina adequada. Um mecanismo seria consultar cada uma das possíveis fontes de interrupção vendo um registrador de status. Este mecanismo (polling) é lento.
No caso do 8051 (assim como a grande maioria dos processadores) temos um mecanismo mais rápido que o polling: cada fonte de interrupção aponta para um local na memória onde se encontra a rotina de tratamento da interrupção. A CPU vai diretamente para este local. Tal mecanismo é conhecido como interrupção vetorada e o vetor de interrupção é dado pela tabela 1.
Tabela 1: Vetor de interrupção do 8051. Ao ocorrer uma interrupção, haverá uma chamada a uma das posições pré-definidas na memória.
Fonte Desvio
INT0 03H
TF0 0bH
INT1 13H
ET1 1BH
TI ou RI 23H
Problema 1: E se duas interrupções ocorrerem ao mesmo tempo (no mesmo ciclo) ? Qual interrupção é executada primeira? O 8051 assim diversos outros processadores possuem um esquema de prioridade.
Resposta:
Existem duas formas de se estabelecer qual interrupção deverá ser servida primeira dentro do 8051:
a) podemos associar os níveis zero (menos priotário) e um (mais prioritário) a cada uma das interrupções através do registrador IP.
IP = + (reservado, reservado, PT2, PS, PT1, PX1, PT0, PX0) -.
Por exemplo, se IP.5 = 1 (PT2 = 1) então a interrupção vinda do timer 2 é de prioridade de nível 1.
b) para as interrupções dentro do mesmo nível temos a seguinte ordem começando pelo de prioridade mais alta: IE0, TF0, IE1, TF1, RI ou TI.
Problema 2: Vamos supor que um dispositivo fez o pedido de interrupção. O processador trata esta interrupção e caso este pedido não deixar de existir, o processador vai novamente chamar a rotina de tratamento da interrupção ficando neste loop indefinidamente. Como as rotinas de interrupção devem limpar o pedido de interrupção no caso do 8051?
Resposta:
As interrupções podem ser disparadas por nível ou por borda. A cada fonte de interrupção existe um bit correspondente. No caso de uma interrupção ser disparada por borda, se este bit for limpo então a interrupção deixa de existir. No caso de uma interrupção ser disparada por nível, limpar o bit não resolve o problema.
As interrupções externas INT0 e INT1 podem ser individualmente configuradas para serem disparadas por nível ou borda dependendo dos bits IT0 e IT1 do registrador TCON. O bit IT0 ou IT1 será setado quando a interrupção ocorrer e limpado automaticamente quando a rotina de interrupção for chamada.
Em relaçào aos timers, os flags TF0 e TF1 são setados automaticamente quando o contador passa de tudo 1 para tudo zero. Isto é corresponde a um disparo por borda. Os flags TF0 e TF1 são automaticamente limpos durante o atendimento pela rotina de interrupção.
A interrupção d porta serial é gerada quando o bit RI vai para 1 ou o bit TI vai para 1. Os flags RI e TI não são automaticamente limpos. É necessário que a rotina de tratamento de interrupção limpe o bit correspondente.
4.2. Interrupção no kit 8051
O programa monitor gravado na EPROM do kit faz com que as interrupções sejam desviadas para a posição final da memória como está descrito na apostila da experiência 1. Observe que isto é válido apenas para este monitor (existem diversos outros monitores para o 8051 e cada um faz seu tratamento particular). Por exemplo: a interrupção do timer 0 originalmente tratada 0BH é desviada pelo programa monitor para o endereço 0FFF3H. Isto é feito para que o aluno possa acertar o vetor de interrupção (desviado) na RAM.
4.3 Exemplo: um programa de tratamento da interrupção TF0 no kit 8051
Este programa envia o caracter 2 de tempo em tempo para a serial usando a interrupção de timer.
Este programa está dividido em três partes:
1. Programa principal – faz a programação do timer 0 (o timer 1 está sendo usado pela serial) para que ele gere interrupções de tempo em tempo (dado pelo registrado TH0). A interrupção do timer é habilitada e o timer é ativado. Depois o programa permanece em um loop infinito. Este programa está alocado na posição 8000H.
2. Rotina de Interrupção – faz algum tratamento (por exemplo: imprime a hora) e depois retorna através da instrução RETI. Não é necessário limpar o flag TF0 porque isto é feito automaticamente pelo hardware.
3. Acerto do vetor de interrupção – Na posição FFF3H é feito um desvio para a rotina de tratamento de interrupção. Este acerto do vetor de interrupção pode também ser feito pelo programa principal desde que se carregue os bytes adequados na posição FFF3H.
O código do programa é:
org 8000H
ANL TMOD,#F0h ;limpa o controle do timer zero
ORL TMOD,#02h ;TIMER0 NO MODO 2
MOV TL0,#FFh ;value set by user
mov TH0,#FFh ;value set by user
setb ET0 ; habilita a interrupção do timer
setb TR0 ; dispara o timer
SETB EA ; habilita de fato as interrupções
MAIN:
AJMP MAIN ; fica neste loop
CO: JNB TI,$
CLR TI
MOV SBUF,B
JNB TI,$
RET
TIMER0: MOV B,#32H ; rotina de interrupção
ACALL CO
RETI
; --------- acerto do vetor de interrupcao.
org fff3h
ljmp TIMER0
END
Observação:
Os flags e registradores não são automaticamente salvos pela rotina de interrupção. Se seu programa principal estiver executando qualquer tarefa que dependa do estado dos flags e registradores então deve-se salvar o estado no início da rotina de interrupção e recuperá-los no final.
Bibliografia: