Tutorial · Principiante · 30 min

Arquitectura del 8051: pines, mapa de memoria y registros

Qué contiene realmente el 8051: un núcleo Harvard, cuatro puertos con personalidades distintas, 256 bytes de RAM y un ciclo de máquina que puedes contar.

Introducción

La mayoría de los cursos de microcontroladores empiezan con el 8051, y la mayoría de los estudiantes lo conocen como una lista de datos para memorizar: cuatro puertos, 128 bytes de RAM, dos temporizadores, seis interrupciones. Memorizado así, se olvida. Entendido como un conjunto de decisiones deliberadas tomadas en 1980 —cuando la RAM costaba dinero de verdad y un chip tenía que caber en 40 pines— explica casi todo sobre cómo siguen funcionando hoy los microcontroladores pequeños.

Este es el recorrido por la arquitectura: qué hay dentro del encapsulado, cómo está dividida la memoria y por qué la aritmética de temporización es inusualmente sencilla. Los dos artículos siguientes cubren el manejo de los pines y la generación de PWM desde un temporizador.

«8051» es una familia, no un chip

Intel presentó el MCS-51 en 1980 y luego licenció el núcleo ampliamente, así que hoy nadie compra un 8051 de Intel. Lo que se compra es una pieza compatible —abrumadoramente el AT89S52 de Atmel (ahora Microchip), que añade memoria flash reprogramable por cuatro pines en lugar de la ROM borrable por UV del original.

Las diferencias que vale la pena conocer:

8051 (original) AT89S52 (el que tienes)
Memoria de programa 4 KB ROM 8 KB flash
RAM interna 128 bytes 256 bytes
Temporizadores 2 3
Fuentes de interrupción 5 6
Programación ROM de máscara en fábrica En el sistema, por pines SPI

Todo lo demás —el juego de instrucciones, los puertos, la disposición de los registros, la temporización— es idéntico. El material de los cursos escrito para el 8051 se aplica sin cambios al chip que tienes sobre la mesa.

Qué hay dentro del encapsulado

Un DIP de 40 pines contiene un ordenador completo: una CPU de 8 bits, flash de programa, RAM de datos, tres temporizadores/contadores, un puerto serie full-duplex, un controlador de interrupciones y cuatro puertos de E/S de 8 bits. No hay sistema operativo ni nada en ejecución salvo tu código.

Distribución de pines del 8051 en su encapsulado DIP de 40 pines, dibujado en vertical con la muesca del pin 1 arriba. La columna izquierda va de los pines 1 a 20: pines del puerto 1 P1.0 a P1.7 con sus funciones alternativas T2, T2EX, MOSI, MISO y SCK, luego RST, luego pines del puerto 3 P3.0 a P3.7 etiquetados RXD, TXD, INT0, INT1, T0, T1, WR y RD, luego XTAL2, XTAL1 y GND. La columna derecha va de los pines 40 a 21: VCC, pines del puerto 0 P0.0 a P0.7 que además son AD0 a AD7, luego EA, ALE y PSEN, luego pines del puerto 2 P2.7 a P2.0 que además son las líneas de dirección A15 a A8. El código de colores separa los puertos de E/S, las funciones alternativas del puerto 3, los pines de reloj y control, y la alimentación.
Treinta y dos de los cuarenta pines son de E/S. El puerto 0 está numerado al revés respecto a los demás, y las etiquetas alternativas del puerto 3 son donde viven el puerto serie, las interrupciones externas y las entradas de los temporizadores. Descargar SVG

Cuatro pines no son de E/S en absoluto y los cuatro deben estar bien antes de que nada funcione: XTAL1 y XTAL2 para el cristal, RST para la red de reset y EA para elegir entre memoria de programa interna o externa. Si EA está mal, el chip no hace nada, en silencio.

El circuito mínimo que un 8051 necesita para funcionar. Un bloque de chip AT89S52 muestra seis pines: VCC pin 40 conectado al riel de cinco voltios y GND pin 20 conectado a tierra; EA pin 31 conectado al riel de cinco voltios en rojo, anotado conecta EA a nivel alto o el chip no ejecuta nada; XTAL2 pin 18 y XTAL1 pin 19 conectados a un cristal de 11,0592 MHz, con un condensador de 33 picofaradios de cada pata del cristal a tierra; y RST pin 9 conectado a un condensador de 10 microfaradios hacia el riel de cinco voltios y una resistencia de 10 kiloohmios hacia tierra, anotado el reset es activo en ALTO.
Cuatro conexiones y un puñado de pasivos. Fíjate en la red de reset: el condensador va a la alimentación, no a tierra, porque RST es activo en alto. Descargar SVG

Harvard: el código y los datos son mundos distintos

El 8051 mantiene la memoria de programa y la de datos en espacios de direcciones separados. Una dirección 0x0030 significa una cosa para una búsqueda de instrucción y algo completamente distinto para un acceso a datos: son memorias diferentes, alcanzadas por instrucciones diferentes.

Por eso los compiladores de C para el 8051 te obligan a pensar en clases de almacenamiento que otras plataformas ocultan. Un literal de cadena que nunca modificas pertenece a la memoria code, donde hay kilobytes de sobra. Si lo pones en data por accidente, se come los 256 bytes que necesitabas para todo lo demás:

// En code (flash) — no cuesta nada de tus 256 bytes de RAM.
const char code banner[] = "Line follower v1";

// En RAM — 17 de tus 256 bytes, perdidos, por una cadena que nunca cambia.
const char banner_bad[] = "Line follower v1";

En un Arduino esta distinción es para lo que existe PROGMEM. En el 8051 no es una optimización, es la diferencia entre un programa que cabe y uno que no.

El mapa de la RAM interna

Los 256 bytes de RAM interna no son un bloc de notas plano. Están divididos en regiones con capacidades distintas, y saber cuál es cuál es la mayor parte de para qué sirve el mapa de memoria.

Un mapa de la memoria interna de datos del 8051 dibujado como bloques apilados desde la dirección 00h abajo hasta FFh arriba. Desde abajo: cuatro bancos de registros de 8 bytes en 00h a 07h, 08h a 0Fh, 10h a 17h y 18h a 1Fh; una región de 16 bytes direccionable por bit en 20h a 2Fh con 128 bits direccionables individualmente; 80 bytes de RAM de uso general y pila de 30h a 7Fh; y en 80h a FFh un bloque que contiene tanto los registros de función especial, alcanzados por direccionamiento directo, como los 128 bytes altos de RAM, alcanzados solo por direccionamiento indirecto. Una flecha marca que el puntero de pila se reinicia a 07h por lo que la pila empieza en 08h encima del banco de registros 1, y una segunda flecha marca la región de 80h a FFh como dos memorias que comparten un rango de direcciones.
Cuatro regiones con cuatro trabajos distintos. Los dos datos anotados son los que muerden: la pila cae sobre el banco de registros 1, y la mitad alta del rango de direcciones son dos memorias separadas. Descargar SVG

00h–1Fh — cuatro bancos de registros. R0 a R7 no son posiciones fijas; son una ventana a uno de cuatro bancos de 8 bytes, seleccionada por dos bits (RS0 y RS1) en la palabra de estado del programa. Cambiar de banco es una escritura de dos bits, lo que lo convierte en una forma muy barata de dar a una interrupción sus propios registros en lugar de apilar y desapilar ocho de ellos.

20h–2Fh — direccionable por bit. Estos 16 bytes también son direccionables como 128 bits individuales, de 00h a 7Fh. El 8051 tiene instrucciones reales de un solo bit —SETB, CLR, JB, JNB—, así que una bandera aquí cuesta un bit y una instrucción en lugar de un byte y una máscara. Por eso los compiladores de C para el 8051 ofrecen un tipo bit que no existe en ningún otro sitio.

30h–7Fh — uso general y pila. Ochenta bytes para tus variables y tu pila de llamadas, y este es el recurso que realmente se agota.

80h–FFh — dos memorias, un rango de direcciones. El direccionamiento directo aquí alcanza los registros de función especial; el direccionamiento indirecto (a través de R0 o R1) alcanza los 128 bytes altos de RAM. Mismos números, memorias distintas, seleccionadas por la forma de instrucción que uses. En el 8051 original de 128 bytes la RAM alta simplemente no existe.

Los registros de función especial son solo memoria

Cada periférico del 8051 se controla escribiendo bytes en direcciones del rango directo 80h–FFh. No hay API: hay un registro, y poner un bit en él cambia lo que hace el silicio.

Registro Dirección Qué controla
P0 P1 P2 P3 80h, 90h, A0h, B0h Los cuatro puertos de E/S
TMOD 89h Selección de modo de los temporizadores 0 y 1
TCON 88h Bits de marcha y banderas de desbordamiento de los temporizadores
TH0 TL0 TH1 TL1 8Ch, 8Ah, 8Dh, 8Bh Registros de conteo de los temporizadores
SCON SBUF 98h, 99h Control y datos del puerto serie
IE IP A8h, B8h Habilitación y prioridad de interrupciones
PSW D0h Banderas y bits de selección del banco de registros
SP 81h Puntero de pila

Escribir P1 = 0x0F; en C es un almacenamiento en la dirección 90h, y ocho pines cambian de estado. Esa franqueza es todo el atractivo del chip como dispositivo didáctico.

Temporización que puedes contar

Un ciclo de máquina son doce periodos del oscilador en un núcleo 8051 clásico, y la mayoría de las instrucciones tardan uno o dos ciclos de máquina. Esa relación fija significa que puedes calcular el tiempo de ejecución con exactitud en lugar de medirlo:

ciclo de máquina = 12 / f_osc

a 11,0592 MHz : 12 / 11 059 200 = 1,085 µs
a 12 MHz      : 12 / 12 000 000 = 1,000 µs

Un bucle de tres instrucciones de un solo ciclo a 11,0592 MHz tarda 3,26 µs, siempre, sin caché, sin segmentación y sin fluctuación de interrupciones más allá de la que tú mismo habilites. Muy pocos procesadores modernos te dejan razonar así, y por eso el 8051 sobrevive dentro de periféricos con temporización crítica.

Por qué el cristal es de 11,0592 MHz

Ese número parece arbitrario y no lo es. El puerto serie deriva su velocidad en baudios dividiendo el reloj del ciclo de máquina, y 11,0592 MHz se divide hasta las velocidades estándar con exactitud:

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

11,0592 MHz, TH1 = 253 :  11 059 200 / (12 × 32 × 3) = 9600,0   ✓ exacto
12 MHz,      TH1 = 253 :  12 000 000 / (12 × 32 × 3) = 10416,7  ✗ 8,5% de error

Una UART tolera unos pocos puntos porcentuales de error; un 8,5% corrompe cada trama. Si tu placa 8051 imprime basura por el puerto serie, mira el cristal antes de mirar tu código.

Lo que el 8051 no tiene

Dos ausencias marcan cada proyecto con el 8051, y ninguna es obvia en una lista de características:

  • Sin convertidor analógico-digital. Leer un potenciómetro, un termistor o un sensor de línea analógico necesita un chip ADC externo como el ADC0804. No hay ningún analogRead() al que recurrir.
  • Sin hardware de PWM. Nada en el chip genera una forma de onda de ciclo de trabajo variable. Atenuar un LED o fijar la velocidad de un motor significa construir tú mismo la PWM a partir de una interrupción de temporizador, y pagarlo en tiempo de CPU.

Un Arduino Uno trae ambas cosas integradas. Esa es la comparación honesta: el 8051 no es un Arduino peor, es la capa que hay debajo de uno, con las comodidades quitadas para que veas lo que hacían.

Cuando algo sale mal

  • La placa está muerta y nada se calienta. Comprueba que EA (pin 31) esté a +5 V. Flotante o a tierra, el chip busca código en una memoria externa que no existe y no ejecuta nada, sin ningún síntoma.
  • Se reinicia constantemente o nunca arranca. El reset en el 8051 es activo en alto. El circuito de encendido es un condensador de 10 µF de +5 V a RST y una resistencia de 10 kΩ de RST a tierra. Cablearlo como un reset activo en bajo mantiene el chip en reset permanente.
  • La salida serie es basura. Casi siempre el cristal. Una pieza de 12 MHz no puede alcanzar las velocidades estándar.
  • Las variables se corrompen entre sí sin motivo. Probablemente te has quedado sin los 80 bytes de 30h–7Fh, o tu pila ha crecido hacia abajo hasta tus variables. Revisa la salida del mapa de memoria de tu compilador.
  • Los registros cambian inesperadamente dentro de una interrupción. El puntero de pila se reinicia a 07h, así que la pila empieza en 08h, que es el banco de registros 1. O mueve SP en tu código de arranque o deja el banco 1 en paz.

Explora el grafo

Forma parte de estos montajes

Proyectos y rutas de aprendizaje que incluyen este tutorial.

Lecturas adicionales

Referencias