Escolar Documentos
Profissional Documentos
Cultura Documentos
– 2020 –
O código E5H, 20H (instrução com 2 bytes, portanto) faz com que a UC atue
para transferir o conteúdo da posição 20H da memória de dados interna para o
registrador A. Existem diversos outros códigos, como por exemplo, para
solicitar que o processador execute operações aritméticas, operações lógicas,
altere o fluxo de execução do código do programa. Estas instruções serão
abordadas ao longo do texto.
Tabela 1 – Exemplo de memória de programa com o conteúdo escrito em formato binário (1a)
e hexadecimal (1b). Fisicamente, os dados são armazenados em formato binário na memória
de programa.
(1a) (1b)
O registrador DPTR (Data Pointer), constituído por DPH (conjunto dos 8 flip-
flops mais significativo do registrador) e DPL (conjunto dos 8 flip-flops menos
significativo do registrador), também possui 16 flip-flops; os demais
registradores do 8051 possuem 8 flip-flops. O DPTR armazena endereço de 16
bits para acessar dados na memória de programa, bem como ler ou escrever
dados em memória RAM externa (Seção 2.5). Assim como o PC, este
registrador tem 16 flip-flops para que possa endereçar uma faixa de 64KiB
(0000H a FFFFH).
Se [A3-0 > 9 ou AC = 1]
O conteúdo de A
DA A é convertido para então (A3-0 + 6 ) C
nro decimal de 2
dígitos
Se [A7-4 > 9 ou C = 1]
então (A7-4 + 6 )
Rotaciona o conteúdo do
acumulador para a esquerda. (An + 1) <= (An)
RL A O flip-flop 0 é carregado com (A0) <= (A7)
conteúdo do flip-flop 7.
(a)
(b)
REGISTRADOR RRR
R0 000
Mnemônico Código Binário Código
R1 001 Hexadecimal
R2 010
MOV A,R2 1110 1010 EA
R3 011
R5 0011 0010
101
R6 110
R7 111
(c) (d)
2.3 - Organização da memória RAM interna
No 8051, o código a ser executado deve ser gravado na memória ROM durante
o processo de fabricação do componente. Isto faz com que o componente,
produzido em grandes volumes, tenha menor custo unitário. Contudo, o
conteúdo da ROM não pode ser modificado posteriormente. No entanto,
existem variantes do microcontrolador 8051 (como por exemplo, o AT89C51 da
Atmel) que possuem memória Flash em vez de ROM, permitindo que o mesmo
seja programado em laboratório.
A memória de dados do tipo RAM (interna ou externa) pode ser utilizada para
criar variáveis; estas são alteradas durante a execução do programa para
proporcionar, por exemplo, a realização de uma contagem.
É possível também observar que nem todos os endereços de 80H a FFH foram
implementados no 8051; por exemplo, não existe registrador no endereço 91H.
Estes endereços são reservados para acesso a periféricos que foram,
posteriormente, incluídos em upgrades do 8051, como por exemplo, para
acessar registrador de conversor digital-analógico.
MOV DPTR,#0A0BH
MOVX A,@DPTR ; Ou opcionalmente
MOV P2,#0AH
MOV R1,#0BH
MOVX A,@R1
0FFFh
Entradas Saída
OEN G D Q
H X X Z
L H L L
L H H H
L L X Q0
(a) (b)
Figura 12 – Exemplo dos sinais de controle gerados pelo 8051 para a escrita de dado em
memória externa.
sfr, sfr16 e sbit são utilizados no arquivo reg51.h para declarar registradores
de função especial de 8 bits, 16 bits (DPTR) e flip-flops do registrador de
função especial PSW (Tabelas 2 e 7). bit e sbit podem ser utilizados para
associar variáveis do programa em linguagem C a flip-flops dos registradores
da memória RAM interna entre 20H e 2FH (Figura 12).
sbit: define variáveis do tipo bit (aceita 0 ou 1) na região de memória dos registradores de
função especial (special function registers – SFR) ou entre 0x20 e 0x2F.
bit: define variáveis do tipo bit (aceita 0 ou 1) na memória interna entre entre 0x20 e 0x2F.
sfr: define variáveis nos endereços de memória dos egistradores de função especial.
bdata: cria variável na memória RAM interna cujos flip-flops podem ser
acessados de forma independente dos demais (região de 0x20 a 0x2F). Ex:
xdata: cria variável na memória RAM externa acessada por MOVX @DPTR
pdata: cria variável na memória RAM externa acessada por MOVX A,@Ri
(permite acessar somente os primeiros 256 bytes de XDATA: 0x0000-
0x00FF).
Como já descrito (Seção 2.6), o 8051 interage com dispositivos externos (por
exemplo, memória externa de programa e memória externa de dados) através
das portas (P0, P1, P2 e P3). É também possível interagir com outros
periféricos conectados à estas portas, tais como, conversor analógico-digital,
displays de 7 segmentos e outros.
// declaração de constantes
#define CS 0xFF;
#define DSP_0 0xE7;
// função main
void main (void)
{
unsigned char
converte_7seg[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x08,0x03,0x46,0x21,
0x06,0x0E,0x80};
P0 = CS;
P3 = DSP_0;
P1 = converte_7seg[1];
while (1);
}
O próximo quadro traz código em linguagem C para mostrar uma contagem
crescente nos 4 displays. A contagem vai de 0 a F e reinicia em 0. A cada
incremento, a contagem é deslocada sequencialmente do display da esquerda
para a direita; ao apresentar a contagem no display 0, novo valor é
apresentado no display 3.
sbit CS = P0^7;
sbit END1 = P3^4;
sbit END0 = P3^3;
CS = 1;
cntdsp = 3; // guarda endereço do display no qual valor será mostrado
while (1) {
END1 = cntdsp_1;
END0 = cntdsp_0;
P1 = dsp7_code[digito++];
for (delay = 0; delay< 30000; delay++); // atraso Edsim 2.1.20
if (cntdsp == 0) cntdsp = 3;
else cntdsp--;
if ( digito == 16) digito = 0;
} // end of while
} //end of main
5. Polling e Interrupção
Além destas duas fontes de interrupção externa, existem outras três fontes de
interrupção devido a dispositivos internos. A Tabela 10 informa quais são estas
fontes de interrupção e o endereço da memória de programa para o qual o
fluxo de execução do programa é desviado em resposta à ocorrência de cada
uma delas. Estes endereços foram estabelecidos pelo projetista do 8051.
Figura 16 – Pinos do 8051 (P3.2 e P3.3) através dos quais solicitações de interrupção externa
(/INT0 e /INT1) são realizadas.
Figura 17 – Registrador Interrupt Enable. Deve-se colocar ‘1’ em cada flip-flop para se obter a
função descrita.
Timer 0 TF0
Externa 1 IE1
Timer 1 TF1
Figura 18 – Registrador Interrupt Priority (IP). Para aumentar o nível de prioridade de dada
fonte de interrupção, deve-se colocar o flip-flop associada à mesma em ‘1’ .
Figura 19 – Registrador Timer Control (TCON). Os flip-flops TF1, TF0, IE1, IE0 quando
setados (nível lógico alto) indicam pendência de atendimento de interrupção (consultar Tabela
11). Os flip-flops IT1 e IT0 em nível lógico alto especificam que as interrupções externas 1 e 0
(respectivamente) são solicitadas por borda de descida. Os demais flip-flops estão relacionados
aos Timers 1 e 0, respectivamente (Seção 6).
Habilitar a interrupção;
#include <reg51.h>
void c51_int0 (void);
EX0 = 1;
EA = 1;
IT0 = 1; // interrupção habilitada -- borda de descida
ponteiro = mensagem;
while (1) {
while (state != 1);
state = 0;
P1 = *(ponteiro+aux++);
if (aux == 16) aux = 0;
} // end of while
} //end of main
CPU de 8 bits;
4 portas de entrada e saída (8 pinos cada);
4 KiB de memória ROM interna para programas;
128 bytes de memória RAM interna para dados;
endereça 64 KiB de memória de programa externa;
endereça 64 KiB de memória de dados externa;
5 vetores de interrupção com 2 níveis de prioridade:
o 2 interrupções externas
o 2 contadores/temporizadores
o 1 interface serial
Figura 20 – Diagrama dos diferentes módulos compreendidos pelo 8051.
O 8051 tem dois Timers de 16 bits (Timer0 e Timer1) sendo que cada um deles
pode operar em 4 modos diferentes. A seleção da forma de funcionamento
(contador ou temporizador), bem como do modo de operação é determinada
pelo registrador TMOD (Figura 21). Embora os seus flip-flops tenham funções
específicas, estes não podem ser manipulados de forma individual (Tabela 7);
deve-se escrever em todo o registrador.
A seguir, irá se trabalhar com o Timer1 para evitar qualquer confusão por parte
do leitor. Os mesmos procedimentos devem ser adotados para o Timer0 para
os modos de 0 a 2, substituindo-se x por 0 na designação dos flip-
flops/registradores referenciados na Figura 23; observa-se novamente, que ao
trabalhar com o Timer0, o mesmo é configurado por meio dos 4 flip-flops
menos significativos do registrador TMOD (Figura 21).
Figura 22 - Esquema de funcionamento dos Timers nos modos 0 e 1. OSC corresponde a
frequência do cristal soldado aos pinos 18 e 19 do 8051 (Figura 2).
OBS: Caso se queira medir largura de pulso de sinal aplicado em /INT1, fazer
GATE=1. A contagem ocorrerá durante intervalo de tempo no qual o pino /INT1
estiver em nível lógico alto.
7. Interface Serial
Nos modos síncrono e assíncrono, o byte a ser transmitido deve ser carregado
no registrador SBUF pelo programa, sendo que a máquina de estado do 8051
transmite automaticamente o conteúdo de SBUF.
Modo Síncrono (Modo 0)
Tabela 12 – Modos de operação da interface serial definidos por meio da programação dos flip-
flops SM0 e SM1 do registrador SCON. O protocolo implementado em cada modo de
operação, o número de bits transmitidos (incluindo start bit e stop bit) e as taxas de
transmissão serial possíveis são também apresentados. HD: Half-Duplex; FD: Full-Duplex.
0 0 0 SÍNCRONO - HD 8 Fclock/12
0 1 1 ASSÍNCRONO - FD 10 Variável
1 1 3 ASSÍNCRONO - FD 11 Variável
(a)
(b)
Figura 26 – Diagramas de tempo da transmissão serial no modo síncrono (a) e assíncrono (b).
No modo síncrono, o sinal de clock transmitido pelo Tx informa o instante em que o receptor
deve realizar a leitura do nível lógico presente em seu pino de entrada. Nos modos
assíncronos, o receptor deve ter conhecimento da taxa de transmissão; o start bit possibilita
sincronizar a recepção. O nono bit transmitido nos Modos 2 e 3 (modos assíncronos)
corresponde ao valor contido no flip-flop TB8.
Na recepção, o byte de dados será recebido (bit a bit) pelo 8051 no pino Rx e
armazenado no registrador SBUF; o pino Tx gera sinal de sincronismo que tem
o papel de informar sobre o instante de proceder a leitura do pino Rx. Veja que
os registradores de transmissão e recepção têm o mesmo nome, ou seja,
ambos compartilham um mesmo endereço (99H) nos SFR (Tabela 7); contudo,
sinais de controle gerados pela UC do 8051 diferenciam os mesmos. Assim, ao
se escrever em SBUF, escreve-se no registrador de transmissão serial; ao se
ler de SBUF, lê-se do registrador de recepção serial.
Caso se transmita um nono bit (Modo 2 ou Modo 3), seu valor deve ser
carregado no flip-flop TB8 do registrador SCON (Figura 25); transmite-se start
bit, byte de dados, nono bit (valor de TB8) e stop bit (11 bits). É comum que o
nono bit seja o bit de paridade do dado transmitido; este é empregado na
recepção para verificar se o dado não foi corrompido durante a transmissão. Na
recepção, o byte de dados recebido bit a bit através do pino Rx é armazenado
no registrador SBUF (lembre-se, registradores de transmissão e recepção
serial compartilham o mesmo endereço). O nono bit recebido nos modos 2 e 3
é armazenado no flip-flop RB8 do registrador SCON (Figura 25). Nos modos
assíncronos, é possível receber e transmitir dados simultaneamente. No jargão
técnico, diz-se que o modo assíncrono é full-duplex (FD).
Após a configuração da interface serial (em função do modo, pode envolver até
4 registradores: SCON, PCON, TMOD e TCON), o programa deve carregar o
byte a ser transmitido no registrador SBUF (nono bit em TB8 nos modos 2 e 3).
Quando a transmissão for concluída, o flip-flop TI é setado pelo hardware; caso
a interrupção serial esteja habilitada, o fluxo de execução do programa é
desviado (PC é carregado com o valor 0023h) para que o programador
identifique que a interface serial pode ser carregada com novo dado a ser
transmitido. O flip-flop TI deve ser resetado pelo programador (TI = 0;). O
hardware não reseta o flip-flop para permitir que o programador identifique se a
solicitação de execução do tratador deve-se a buffer de transmissão vazio ou
não. Opcionalmente, o programador pode identificar este evento por polling
(sem habilitar de interrupção), devendo também limpar o flag TI.
Para que o 8051 receba dados, o flip-flop REN do registrado SCON (Figura 25)
deve ser colocado em nível lógico alto. Quando um byte for recebido em SBUF,
o flip-flop RI é setado pelo hardware; caso a interrupção serial esteja habilitada,
o fluxo de execução do programa é desviado (PC é carregado com o valor
0023h) para que o programador identifique que há dado para ser lido na
interface serial (registrador SBUF). O flip-flop RI deve ser resetado pelo
programador (RI = 0;). O hardware não reseta o flip-flop para permitir que o
programador identifique se a solicitação de execução do tratador deve-se a
buffer de recepção cheio (RI em nível lógico alto) ou buffer de transmissão
vazio (TI em nível lógico alto). Opcionalmente, o programador pode identificar a
ocorrência de recepção de dado (RI em nível lógico alto) por polling (sem
habilitar a interrupção), devendo também limpar o flag RI.
Observe que esta equação possui 3 variáveis, SMOD, Fosc e TH1. SMOD
pode assumir 2 valores ( 0 ou 1), Fosc pode ser qualquer valor comercial de
cristal dentro da faixa de funcionamento do 8051 e TH1 pode assumir 256
diferentes valores. Para simplificar o trabalho do programador, a Tabela 13
apresenta os valores destas 3 variáveis, bem como o modo de programação do
Timer1 para que se obtenha algum dos baud rates mais frequentemente
utilizados.
Tabela 13 – Valores de Fosc, SMOD e Timer1 para se obter a baud rate especificada na
primeira coluna.
#pragma LARGE // modelo de memoria. Large: Variáveis em xram
#include <reg51.h> // endereços dos special function registers
unsigned char xdata dados_rx [32]; // vetor de 32 byte para a recepção de dados
unsigned char xdata *regPtr; // ponteiro utilizado na recepção de dados
regPtr = dados_rx;
ES = 1;
EA = 1; // habilita interrupcao serial
SBUF = 0x41; // envia caractere ‘A'
while (SBUF != 'x'); // enquanto não detecta um 'x' na porta serial, executa...
ES = 0; // inibe interrupcao pela porta serial
count++;
tm++;
}
} // end of serial
Comunicação Multiprocessadores
Quando o computador quiser enviar dados apenas para um dos 8051, este
envia, primeiramente, um byte de endereço que identifica o 8051 com o qual
deseja se comunicar. Este byte de endereço distingue-se dos bytes de dados
por meio do nono bit (TB8); o mesmo é 1 para endereços e 0 para dados.
O computador passa então a enviar bytes de dados com o nono bit igual a 0
(TB8=0;). Apenas o 8051 previamente endereçado (agora com SM2=0;) irá
requerer a execução de seu tratador de interrupção da serial de forma a
receber os dados enviados pelo computador. Os demais 8051 (SM2=1;) não
tomam conhecimento do envio destes dados pelo computador.
Observações:
Observação:
Para sair do modo Power Down, reseta-se o 8051. O Reset apenas não altera
o conteúdo da RAM interna (00 a 7FH).
Observação:
Nesse modo, a alimentação da pastilha pode ser reduzida a 2 Volts. Todavia,o valor de
Vcc não pode ser reduzido antes que a pastilha esteja em Power Down. Ao sair de
Power Down, Vcc já deve ter sido restabelecido para 5V por tempo suficiente para que o
oscilador entre em funcionamento normal.
APÊNDICE A
A.1 Convenções
addr16 - endereço com tamanho de 16 bits. Usado nas instruções LJMP e LCALL;
rel - deslocamento de até 128 bytes anteriores ou até 127 bytes posteriores à
posição atual do PC. Usado por SJMP e todos os demais JMPs condicionais;
OBS: Em instruções nas quais o código binário incorpora o emprego do acumulador, este é referenciado
como A; nas instruções que utilizam endereçamento direto, o acumulador deve ser referenciado como
Acc, sendo tal referência substituída pelo seu endereço (E0h) pertencente aos SFR.
A.2 Instruções para Transferência de Dados
Exemplo
MOV A,#04h P
MOV R6,#40h
PUSH 40h
POP direct Retira da pilha um dado e o (direct)((SP))
armazena na IRAM ou SFR no
endereço direct (SP)(SP)-1
POP 40h
Exemplo
INC A P
Exemplo
CLR A P
Exemplo
CLR P3.2
SETB C
SETB P3.2
CPL P3.2
ANL C,flip-flop Lógica AND entre o flag carry e o (C)(C) and (flip-flop) C
flip-flop da posição de IRAM ou
SFR endereçada ANL C, 29H.5
ANL C, /flip-flop Lógica AND entre o flag carry e o (C)(C) and [(flip- C
complemento do flip-flop da flop)/]
posição de IRAM ou SFR
endereçada ANL C, /29H.5
MOV C, P3.5
MOV P3.5,C
Exemplo
(SP)(SP)+1
((SP))(PC15-8)
(PC10-0)addr11
(SP)(SP)-1
(PC10-0)((SP))
(SP)(Sp)-1
(SP)(Sp)-1
LINGUAGEM ASSEMBLY
Diretivas de compilação
ORG (Origin)
Formato:
ORG <Endereço da memória> <;comentário>
EQU (Equate)
Formato:
<rótulo> EQU <constante> <;comentário>
DB (Define Byte)
END
Formato:
END <;comentário>
(código)
.....
final: JMP final
ctes1: DB 45H,0ABH,0E2H
ctes2: DB “EEL”,70H,30H ; na memória => 45, 45, 4B, 70,30
Tabela C.1 – Instruções do 8051 para o desvio condicional do fluxo de execução do programa.
MNEMÔNICO DESCRIÇÃO
C.2 Subrotinas
Quando um conjunto de linhas de código é muito utilizado ao longo de um
programa, é usual disponibilizá-lo como uma subrotina de forma a melhorar a
legibilidade do código, bem como compactar o código, visando a menor
ocupação da memória de programa. A Figura C.1 ilustra como isto é realizado.
Neste exemplo, se o número de instruções (Ninst) repetidas for 40, por
exemplo, a implementação do programa com rotina é reduzido de,
aproximadamente, 80 linhas de instrução. Tal redução de tamanho do código
original obtido com o uso de subrotina pode proporcionar que o código
resultante possa ser comportado na memória de programa interna sem a
necessidade de acrescentar memória externa ao sistema. Tem-se também
ganhos em relação à legibilidade do código, pois uma vez que a função da
subrotina tenha sido compreendida, outra menção à mesma no programa não
requer a sua nova análise. Como desvantagem, tem-se que a alteração do
fluxo de execução do programa consome algum tempo (execução de
procedimentos adicionais pela UC do 8051); pode portanto, não ser
recomendável quando se requer maior velocidade na execução de tarefas pelo
processador.
Contudo, o programador pode utilizar a instrução JMP (que não existe no conjunto de
instruções do 8051) e deixar que o compilador a substitua pelo código da instrução mais
adequada. A instrução LJMP (3 bytes) é utilizada quando o desvio ocorrer para um trecho de
código distante (além de 2048 bytes) da instrução JMP, pois ocupa 1 byte a mais da memória
de programa do que as instruções AJMP e SJMP.
C. 3 Pilha
[PC] ← [PC] + 3; PC é incrementado durante a leitura de cada um dos 3 bytes que compõem
a instrução LCALL 2028H; a execução da instrução é iniciada:
[PCMSB] ← [{[SP]}]; Conteúdo da posição de memória apontada por SP é carregado no MSB do PC;
END. Mnemônico
Figura C.4 – Exemplo de recuperação de dado colocado na pilha pela instrução PUSH. Ao
término da execução desta instrução, o conteúdo de SP será idêntico ao anterior à execução
deste código.
Ao gerar o código, o compilador não analisa o mesmo para saber qual banco
de registradores está sendo utilizado pelo programador. Por esta razão, não é
possível referenciar o nome de registradores em instrução de PUSH e POP;
estas instruções utilizam endereço direto. Assim, nestas instruções, deve-se
especificar o endereço sendo utilizado pelo registrador; ou seja, para
armazenar na pilha, o conteúdo do registrador R1 do banco 2, a instrução é
POP 11H. Utiliza-se ACC em vez de A nas instruções de PUSH e POP para
referenciar o acumulador; desta forma, o compilador substitui ACC pelo
endereço que este ocupa na memória SFR. No Assembly, instruções que
utilizam A em vez de ACC não fazem uso do endereço do acumulador; a
utilização do acumulador fica implícito no código binário da instrução.
POP 07H
;.... (mais POPs)
POP 01H
POP 00H
RET
CLR RS0
RET
Referências