Tutorial · Iniciante · 30 min

Arquitetura do 8051: pinos, mapa de memória e registradores

O que o 8051 realmente contém: um núcleo Harvard, quatro portas com características diferentes, 256 bytes de RAM e um ciclo de máquina que permite fazer contas.

Introdução

A maioria dos cursos de microcontroladores começa pelo 8051, e a maioria dos estudantes o conhece como uma lista de fatos para decorar: quatro portas, 128 bytes de RAM, dois temporizadores, seis interrupções. Decorada assim, a informação fica fácil de esquecer. Compreendida como um conjunto de escolhas deliberadas tomadas em 1980, quando a RAM era cara e um chip tinha que caber em 40 pinos, ela explica quase tudo sobre como pequenos microcontroladores ainda funcionam hoje.

Este é o passeio pela arquitetura: o que existe dentro do encapsulamento, como a memória é dividida e por que a aritmética de temporização é excepcionalmente fácil. Os dois tutoriais seguintes cobrem o acionamento dos pinos e a geração de PWM com um temporizador.

“8051” é uma família, não um chip

A Intel introduziu o MCS-51 em 1980 e depois licenciou amplamente o núcleo, então ninguém compra um Intel 8051 hoje. O que se compra é um componente compatível — quase sempre o AT89S52 da Atmel (atualmente Microchip) — que acrescenta memória flash reprogramável por quatro pinos, em vez da ROM apagável por UV do original.

As diferenças que vale conhecer:

8051 (original) AT89S52 (o que você tem)
Memória de programa 4 KB de ROM 8 KB de flash
RAM interna 128 bytes 256 bytes
Temporizadores 2 3
Fontes de interrupção 5 6
Programação ROM com máscara na fábrica No sistema, pelos pinos SPI

Todo o restante — o conjunto de instruções, as portas, a organização dos registradores, a temporização — é idêntico. Material de curso escrito para o 8051 se aplica sem alterações ao chip da sua mesa.

O que existe dentro do encapsulamento

Um DIP de 40 pinos contém um computador completo: uma CPU de 8 bits, memória flash de programa, RAM de dados, três temporizadores/contadores, uma porta serial totalmente bidirecional, um controlador de interrupções e quatro portas de E/S de 8 bits. Não há sistema operacional nem nada em execução além do seu código.

Pinagem do 8051 em seu encapsulamento DIP de 40 pinos, desenhada verticalmente com o entalhe do pino 1 no topo. A coluna esquerda vai dos pinos 1 a 20: pinos da porta 1, P1.0 a P1.7, com suas funções alternativas T2, T2EX, MOSI, MISO e SCK, depois RST, depois os pinos da porta 3, P3.0 a P3.7, rotulados como RXD, TXD, INT0, INT1, T0, T1, WR e RD, depois XTAL2, XTAL1 e GND. A coluna direita vai dos pinos 40 a 21: VCC, pinos da porta 0, P0.0 a P0.7, que também funcionam como AD0 a AD7, depois EA, ALE e PSEN, depois os pinos da porta 2, P2.7 a P2.0, que também funcionam como linhas de endereço A15 a A8. A codificação por cores separa as portas de E/S, as funções alternativas da porta 3, os pinos de relógio e controle e a alimentação.
Trinta e dois dos quarenta pinos são de E/S. A porta 0 é numerada ao contrário em relação às outras, e os rótulos alternativos da porta 3 indicam onde ficam a porta serial, as interrupções externas e as entradas dos temporizadores. Baixar SVG

Quatro pinos não são de E/S e todos precisam estar corretamente conectados antes que qualquer coisa funcione: XTAL1 e XTAL2 para o cristal, RST para a rede de reset e EA para escolher entre memória de programa interna e externa. Se EA estiver conectado incorretamente, o chip não faz nada, sem dar nenhum sinal.

O circuito mínimo necessário para que um 8051 funcione. Um bloco do chip AT89S52 mostra seis pinos: VCC, pino 40, ligado ao trilho de cinco volts, e GND, pino 20, ligado à massa; o pino 31 (EA), ligado em vermelho ao trilho de cinco volts, com a anotação de que EA deve ficar alto ou o chip não funciona; XTAL2, pino 18, e XTAL1, pino 19, ligados aos dois lados de um cristal de 11,0592 MHz, com um capacitor de 33 picofarads de cada lado do cristal à massa; e RST, pino 9, ligado a um capacitor de 10 microfarads que sobe até o trilho de cinco volts e a um resistor de 10 quilo-ohms que desce à massa, com a anotação de que o reset é ativo em nível ALTO.
Quatro conexões e alguns componentes passivos. Observe a rede de reset: o capacitor vai para a fonte, não para a massa, porque RST é ativo em nível alto. Baixar SVG

Harvard: código e dados são mundos diferentes

O 8051 mantém a memória de programa e a memória de dados em espaços de endereço separados. Um endereço 0x0030 significa uma coisa para a busca de uma instrução e outra completamente diferente para um acesso a dados — são memórias diferentes, acessadas por instruções diferentes.

É por isso que compiladores C para o 8051 fazem você pensar em classes de armazenamento que outras plataformas ocultam. Um literal de string que você nunca modifica pertence à memória code, onde há vários quilobytes disponíveis. Se o colocar acidentalmente em data, ele consome os 256 bytes de que você precisava para todo o resto:

// In code (flash) — costs nothing from your 256 bytes of RAM.
const char code banner[] = "Line follower v1";

// In RAM — 17 of your 256 bytes, gone, for a string that never changes.
const char banner_bad[] = "Line follower v1";

Em um Arduino, essa distinção é o motivo de existir o PROGMEM. No 8051, ela não é uma otimização: é a diferença entre um programa que cabe e outro que não cabe.

O mapa da RAM interna

Os 256 bytes de RAM interna não formam uma área de trabalho plana. São divididos em regiões com capacidades diferentes, e conhecer a função de cada uma é o essencial para entender o mapa de memória.

Mapa da memória de dados interna do 8051, desenhado como blocos empilhados do endereço 00h na parte inferior até FFh no topo. De baixo para cima: quatro bancos de registradores de 8 bytes em 00h a 07h, 08h a 0Fh, 10h a 17h e 18h a 1Fh; uma região de 16 bytes endereçável por bit em 20h a 2Fh, contendo 128 bits individualmente endereçáveis; 80 bytes de RAM de trabalho e pilha de 30h a 7Fh; e, em 80h a FFh, um bloco que contém os registradores de funções especiais, acessados por endereçamento direto, e os 128 bytes superiores de RAM, acessados apenas por endereçamento indireto. Uma seta indica que o ponteiro da pilha é redefinido para 07h, de modo que a pilha começa em 08h, no banco de registradores 1; uma segunda seta marca a região de 80h a FFh como duas memórias que compartilham uma faixa de endereços.
Quatro regiões com quatro funções diferentes. Os dois fatos sinalizados são os que causam problemas: a pilha começa em 08h, no banco de registradores 1, e a metade superior da faixa de endereços contém duas memórias distintas. Baixar SVG

00h–1Fh — quatro bancos de registradores. R0 a R7 não são locais fixos; são uma janela para um dos quatro bancos de 8 bytes, selecionado por dois bits (RS0 e RS1) na palavra de status do programa. Trocar de banco é uma escrita de dois bits, o que torna muito barato dar a uma interrupção seus próprios registradores, em vez de empilhar e desempilhar oito registradores.

20h–2Fh — endereçável por bit. Esses 16 bytes também podem ser endereçados como 128 bits individuais, de 00h a 7Fh. O 8051 tem instruções reais para um único bit — SETB, CLR, JB, JNB — então uma flag aqui ocupa um bit e uma instrução, em vez de um byte e uma máscara. É por isso que compiladores C do 8051 oferecem um tipo bit que não existe em nenhum outro lugar.

30h–7Fh — memória de trabalho e pilha. Oitenta bytes para suas variáveis e sua pilha de chamadas; esse é o recurso que realmente acaba.

80h–FFh — duas memórias, uma faixa de endereços. O endereçamento direto aqui alcança os registradores de funções especiais; o endereçamento indireto (por R0 ou R1) alcança os 128 bytes superiores de RAM. Mesmos números, memórias diferentes, selecionadas pela forma da instrução que você usa. No 8051 original de 128 bytes, a RAM superior simplesmente não existe.

Registradores de funções especiais são apenas memória

Todo periférico do 8051 é controlado escrevendo bytes em endereços da faixa direta 80h–FFh. Não existe API — existe um registrador, e definir um bit nele muda o que o silício faz.

Registrador Endereço O que controla
P0 P1 P2 P3 80h, 90h, A0h, B0h As quatro portas de E/S
TMOD 89h Seleção de modo dos temporizadores 0 e 1
TCON 88h Bits de controle dos temporizadores e flags de transbordamento
TH0 TL0 TH1 TL1 8Ch, 8Ah, 8Dh, 8Bh Registradores de contagem dos temporizadores
SCON SBUF 98h, 99h Controle e dados da porta serial
IE IP A8h, B8h Habilitação e prioridade das interrupções
PSW D0h Flags e bits de seleção do banco de registradores
SP 81h Ponteiro da pilha

Escrever P1 = 0x0F; em C é um armazenamento no endereço 90h, e oito pinos mudam de estado. Toda a atrativa do chip como dispositivo didático está nessa simplicidade de acesso direto.

Temporização que você pode contar

Em um núcleo 8051 clássico, um ciclo de máquina corresponde a doze períodos do oscilador, e a maioria das instruções leva um ou dois ciclos de máquina. Essa razão fixa permite calcular o tempo de execução exatamente, em vez de medi-lo:

machine cycle = 12 / f_osc

at 11.0592 MHz : 12 / 11 059 200 = 1.085 µs
at 12 MHz      : 12 / 12 000 000 = 1.000 µs

Um laço de três instruções de ciclo único a 11,0592 MHz leva 3,26 µs, sempre, sem cache, sem pipeline e sem incerteza de temporização causada por interrupções além daquelas que você próprio habilitar. Pouquíssimos processadores modernos permitem raciocinar assim, e é por isso que o 8051 sobrevive em periféricos críticos quanto à temporização.

Por que o cristal é de 11,0592 MHz

Esse número parece arbitrário, mas não é. A porta serial deriva sua taxa de baud a partir do relógio dos ciclos de máquina, e 11,0592 MHz produz taxas de baud padrão exatamente:

baud = f_osc / (12 × 32 × (256 − TH1))

11.0592 MHz, TH1 = 253 :  11 059 200 / (12 × 32 × 3) = 9600.0   ✓ exact
12 MHz,      TH1 = 253 :  12 000 000 / (12 × 32 × 3) = 10416.7  ✗ 8.5% off

Uma UART tolera alguns pontos percentuais de erro; 8,5% corrompe todos os quadros. Se sua placa 8051 imprime dados ilegíveis pela porta serial, examine o cristal antes de examinar o código.

O que o 8051 não tem

Todo projeto com 8051 é moldado por duas ausências, e nenhuma delas é óbvia em uma lista de recursos:

  • Sem conversor analógico-digital. Ler um potenciômetro, um termistor ou um sensor de linha analógico exige um chip ADC externo, como o ADC0804. Não existe analogRead() para usar.
  • Sem PWM por hardware. Nada no chip gera uma forma de onda com ciclo de trabalho variável. Diminuir o brilho de um LED ou definir a velocidade de um motor significa construir PWM com uma interrupção de temporizador e pagar por isso com tempo de CPU.

Um Arduino Uno tem os dois recursos integrados. Essa é a comparação honesta: o 8051 não é um Arduino pior; é a camada por baixo de um, com as conveniências removidas para que você veja o que elas faziam.

Quando algo dá errado

  • A placa está morta e nada aquece. Verifique se EA (pino 31) está em +5 V. Se estiver flutuante ou conectado à massa, o chip busca código em uma memória externa que não existe e não executa nada, sem nenhum sintoma.
  • Ele reinicia constantemente ou nunca inicia. O reset do 8051 é ativo em nível alto. No circuito de alimentação, um capacitor de 10 µF é ligado de +5 V a RST, e um resistor de 10 kΩ, de RST à massa. Ligá-lo como um reset ativo em nível baixo mantém o chip em reset permanente.
  • A saída serial é ilegível. Quase sempre a causa é o cristal. Uma peça de 12 MHz não alcança as taxas de baud padrão.
  • As variáveis se corrompem sem motivo. Você provavelmente esgotou os 80 bytes em 30h–7Fh, ou sua pilha cresceu para baixo e atingiu suas variáveis. Verifique a saída do mapa de memória do compilador.
  • Registradores mudam inesperadamente dentro de uma interrupção. O ponteiro da pilha é redefinido para 07h, então a pilha começa em 08h — que é o banco de registradores 1. Mova SP no código de inicialização ou deixe o banco 1 como está.

Explore o grafo

Faz parte destas montagens

Projetos e caminhos de aprendizagem que incluem este tutorial.

Leitura complementar

Referências