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.
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.
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.
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