01 · Punto de partida
Cambiar el comportamiento sin cambiar los cables
En el curso anterior armaste una alarma con memoria: una puerta lógica calculaba el próximo estado y un flip-flop lo guardaba en cada flanco del reloj. Para construirla hicieron falta varios circuitos integrados, un reloj y un cableado cuidadoso. Si después querías que la alarma alternara en cada pulsación o contara aperturas, tenías que desarmar y volver a cablear.
Un programador está acostumbrado a lo contrario: el hardware es fijo y el comportamiento se cambia editando código. El microcontrolador lleva esa idea al mundo de los circuitos. Es un chip con entradas y salidas eléctricas cuyo comportamiento está definido por un programa guardado en su memoria.
El punto de partida son los cursos anteriores: niveles lógicos, puertas, registros, contadores y memorias. Nada de eso desaparece; ahora está dentro del chip, y el programa lo controla a través de registros.
02 · Definición
Un computador completo en un solo circuito integrado
Un microcontrolador (MCU, de microcontroller unit) integra en un mismo encapsulado:
- una CPU que ejecuta instrucciones;
- memoria para el programa y para los datos;
- un reloj que marca el ritmo de ejecución;
- periféricos como pines de entrada y salida, temporizadores, conversores analógicos y puertos de comunicación.
Su objetivo no es calcular rápido ni ejecutar muchas aplicaciones, sino interactuar con el mundo físico: leer un pulsador, medir una temperatura, encender un motor, hablar con otro chip. Por eso es pequeño, barato, de bajo consumo y no necesita componentes externos para funcionar, aparte de la alimentación y, a veces, un cristal.
| Opción | Qué es | Cómo se define el comportamiento | Ejemplo |
|---|---|---|---|
| Lógica cableada | Puertas, flip-flops y contadores interconectados | Por las conexiones físicas | La alarma del curso 6 |
| Microcontrolador | CPU, memoria y periféricos en un chip | Por un programa (firmware) | ATmega328P de una placa Arduino Uno |
| Microprocesador | Solo CPU; la memoria y los periféricos son externos | Por un programa, normalmente con sistema operativo | Procesador de una computadora |
| Computadora de placa única | Microprocesador, memoria y periféricos en una placa, con sistema operativo | Por programas y servicios | Raspberry Pi |
| FPGA | Bloques lógicos reconfigurables | Por una descripción del hardware que se carga en el chip | Lógica paralela de muy alta velocidad |
Un microcontrolador normalmente ejecuta un solo programa, sin sistema operativo, desde que se energiza hasta que se corta la alimentación. Ese programa se llama firmware: software que vive pegado al hardware.
03 · Por dentro
Los bloques de un microcontrolador
Todos los microcontroladores comparten una organización parecida. La CPU, las memorias y los periféricos se comunican a través de buses internos; algunos periféricos se conectan al exterior mediante los pines del chip.
Cada bloque ya te resulta conocido. La diferencia es que ahora están construidos en silicio, integrados y listos para configurarse desde el programa.
| Lo que ya sabés | Dentro del microcontrolador | Se estudia en |
|---|---|---|
| Puertas y circuitos combinacionales | ALU, decodificador de instrucciones y decodificadores de direcciones | Temas 6 y 7 |
| Flip-flops y registros | Registros de la CPU y registros de configuración de periféricos | Temas 9 a 11 |
| Contadores | Contador de programa y temporizadores | Temas 6 y 23 |
| Máquinas de estados | Control de la CPU, protocolos serie y la lógica de tu programa | Temas 31 a 35 y 42 |
| RAM, ROM, EEPROM y Flash | SRAM, memoria Flash de programa y EEPROM | Tema 8 |
| Osciladores y divisores de frecuencia | Reloj del sistema y prescalers | Tema 12 |
| Niveles lógicos, pull-up y antirrebote | Pines GPIO | Temas 15 a 18 |
| Comparadores y conversión analógica | ADC, DAC y comparador analógico | Temas 27 a 30 |
04 · El cambio de enfoque
El programa reemplaza el cableado
Veamos la alarma del curso anterior. Con lógica cableada, la ecuación Q próximo = NOT R AND (Q OR S) se materializa con puertas y un flip-flop. En un microcontrolador se escribe el mismo comportamiento como código. El sensor S entra por el pin PB0, el botón R por el pin PB4 y la alarma sale por el pin PB1:
#include <avr/io.h>
int main(void) {
DDRB |= (1 << PB1); // PB1 es salida; PB0 y PB4 quedan como entradas
while (1) {
if (PINB & (1 << PB4)) {
PORTB &= ~(1 << PB1); // R: apagar la alarma
} else if (PINB & (1 << PB0)) {
PORTB |= (1 << PB1); // S: encender y recordar
}
}
}
No te preocupes todavía por cada símbolo: DDRB, PORTB y PINB son registros de los pines, y los estudiaremos con detalle en los temas 9 y 15. Por ahora fijate en dos ideas:
- Leer
PINBequivale a mirar los voltajes de los pines de entrada. - Escribir
PORTBequivale a poner niveles altos o bajos en los pines de salida. Como ese registro conserva su valor, el bit de PORTB hace de memoria: no hizo falta un flip-flop externo.
Lógica cableada
El comportamiento está en las conexiones. Cambiarlo exige modificar el circuito. Todas las puertas trabajan en paralelo y responden en nanosegundos, pero cada función nueva consume más componentes y más espacio.
Programa en un microcontrolador
El comportamiento está en la memoria Flash. Cambiarlo exige grabar otro programa. Una sola CPU ejecuta las instrucciones una tras otra, pero puede resolver muchas funciones con el mismo hardware.
05 · La estructura básica
Leer, decidir y actuar, una y otra vez
Casi todos los programas de un microcontrolador siguen el mismo esquema. Primero se inicializa el hardware: se configuran pines, temporizadores y comunicación. Después se entra en un bucle infinito que se repite mientras el chip esté alimentado:
- Leer las entradas: pulsadores, sensores, mensajes recibidos.
- Decidir qué hacer, usando esas lecturas y las variables que guardan el estado.
- Actuar sobre las salidas: LED, motores, pantallas, mensajes enviados.
Es el mismo modelo secuencial del curso anterior: próximo estado = f(estado actual, entradas). La diferencia es que el «reloj» que marca cada actualización es ahora la propia ejecución del bucle, y el estado puede vivir en un registro de salida o en una variable en memoria.
Cuánto tarda cada vuelta
Una placa Arduino Uno usa un reloj de 16 MHz. Cada ciclo de reloj dura 1 / 16 000 000 s = 62,5 ns, y la mayoría de las instrucciones del ATmega328P tarda entre uno y dos ciclos. Un bucle de unas diez instrucciones puede entonces repetirse en el orden de un microsegundo, es decir, cerca de un millón de veces por segundo.
Ese tiempo determina la rapidez con que el sistema mira el mundo. Un evento que dure menos que una vuelta del bucle puede pasar inadvertido, igual que el pulso que se perdía entre dos flancos de reloj en el curso anterior. Más adelante veremos cómo las interrupciones y los temporizadores resuelven ese problema sin que la CPU esté vigilando todo el tiempo.
Lo que el hardware hace en paralelo
Aunque la CPU ejecute una instrucción por vez, los periféricos funcionan al mismo tiempo: un temporizador sigue contando, un conversor analógico mide y una UART recibe bytes mientras el programa hace otra cosa. La habilidad central al programar un microcontrolador es delegar en los periféricos todo lo que se pueda y reservar la CPU para decidir.
06 · Un caso concreto
El ATmega328P: nuestro chip de referencia
A lo largo del curso usamos como referencia el ATmega328P, el microcontrolador de la placa Arduino Uno. Es un chip de 8 bits, sencillo, bien documentado y muy difundido. Sus conceptos se trasladan a otras familias como ARM Cortex-M, ESP32 o RP2040: cambian los nombres de los registros, no las ideas.
| Recurso | Valor | Para qué sirve |
|---|---|---|
| CPU | AVR de 8 bits, 32 registros de trabajo | Ejecuta el programa |
| Reloj | Hasta 20 MHz; 16 MHz en la placa Uno | Marca el ritmo de las instrucciones |
| Memoria Flash | 32 KB | Guarda el programa, aunque se corte la alimentación |
| SRAM | 2 KB | Variables y pila, se pierde al apagar |
| EEPROM | 1 KB | Datos que deben sobrevivir al apagado |
| Líneas de entrada y salida | Hasta 23 (encapsulado de 28 pines) | Leer y controlar señales digitales |
| Temporizadores | 3 (dos de 8 bits y uno de 16 bits), con 6 canales PWM | Medir tiempo y generar señales |
| Conversor analógico-digital | 10 bits, 6 canales en el encapsulado DIP | Medir tensiones |
| Comunicación serie | UART, SPI e I2C (TWI) | Hablar con la computadora y con otros chips |
| Alimentación | 1,8 V a 5,5 V | Funciona con 5 V o 3,3 V |
Comparado con una computadora actual, parece diminuto: miles de veces menos memoria y velocidades que se miden en megahertz en lugar de gigahertz. Pero para encender un LED, leer un sensor de temperatura y enviar el dato por un cable, sobra. Además cuesta poco, consume muy poca energía y no requiere sistema operativo ni disco.
07 · Decidir bien
Cuándo conviene un microcontrolador y cuándo no
| Criterio | Lógica cableada | Microcontrolador |
|---|---|---|
| Cantidad de funciones | Poca, definida y fija | Muchas, con el mismo hardware |
| Cambios futuros | Requieren modificar el circuito | Se resuelven con otro programa |
| Velocidad de respuesta | Nanosegundos, en paralelo | Microsegundos, con un solo hilo de ejecución |
| Operaciones complejas | Difíciles: aritmética, tablas, protocolos | Naturales: cálculos, comunicación y decisiones |
| Tiempo de desarrollo | Montaje y pruebas del circuito | Programación y depuración |
| Comportamiento ante fallas | Muy previsible: sin software | Depende de la calidad del programa |
Una función simple como «encender un LED mientras un interruptor esté cerrado» no necesita programa: basta una conexión. Un reloj despertador con ajuste de hora, alarma, pantalla y memoria de configuración es un caso típico de microcontrolador: hacerlo con puertas sería un laberinto de chips.
Hay también una zona intermedia. Las señales más rápidas que el microcontrolador puede seguir se resuelven con hardware dedicado, como un contador de alta frecuencia, y el microcontrolador se limita a leer el resultado.
08 · Analogía con programación
Muestrear: qué se pierde entre dos lecturas
El código C del tema depende del chip, así que usamos Python para modelar una idea de fondo: un programa que consulta una entrada cada cierto tiempo solo ve lo que ocurre en esos instantes. La lista sensor_us contiene el valor del sensor en cada microsegundo: un pulso breve de 3 µs y otro más largo de 40 µs. El programa lo consulta cada periodo microsegundos y cuenta los flancos ascendentes.
Python en tu navegador. Los bloques son editables: cambiá los valores y presioná «Ejecutar Python». La primera vez tarda unos segundos en cargar.
# Valor del sensor en cada microsegundo (lo que ocurre en el mundo físico).
sensor_us = [0] * 11 + [1] * 3 + [0] * 9 + [1] * 40 + [0] * 20
def contar_pulsos(periodo):
"""Simula un bucle que lee el sensor cada `periodo` microsegundos."""
previo = 0
pulsos = 0
for t in range(0, len(sensor_us), periodo):
ahora = sensor_us[t] # leer
if ahora and not previo: # decidir: ¿flanco ascendente?
pulsos += 1 # actuar
previo = ahora
return pulsos
for periodo in (1, 2, 5, 20):
print(f"Lectura cada {periodo:2d} µs -> {contar_pulsos(periodo)} pulso(s) detectado(s)")
Resultado: con 1 µs y 2 µs se detectan los 2 pulsos; con 5 µs y 20 µs solo se detecta 1. Probá agrandar el pulso breve a 6 µs, o hacerlo más corto, y predecí el resultado antes de ejecutar.
Este modelo anticipa un problema real: si el bucle principal hace demasiadas cosas, tarda más en volver a leer la entrada y puede perderse eventos. Los temas de interrupciones, temporizadores y captura de entrada existen para evitarlo.
La analogía tiene un límite: el modelo ignora los rebotes, el ruido eléctrico y la forma real de las señales. Es una herramienta para razonar sobre el tiempo, no una simulación del chip.
09 · Exploración interactiva
El mismo hardware, cuatro comportamientos
Este microcontrolador virtual tiene un sensor en PB0, un botón R en PB4 y tres LED en las salidas PB1, PB2 y PB3. Elegí un programa, cambiá las entradas y ejecutá una vuelta del bucle por vez. Sin tocar el «circuito», solo cambiando el programa, el comportamiento es otro.
Microcontrolador virtual de 8 pines de entrada y salida
Cargando el programa…
| Vuelta | PINB leído | PORTB antes | PORTB después |
|---|---|---|---|
| Sin iteraciones registradas. | |||
Reset del microcontrolador lleva los registros y las variables a 0 y suelta las entradas. Cambiar de programa produce el mismo efecto, porque al grabar otro firmware el chip arranca de nuevo.
Recorrido guiado
- Con el programa 1, activá S y ejecutá una vuelta: PB1 se enciende. Desactivá S y ejecutá otra: se apaga. No hay memoria.
- Cambiá al programa 2. Activá S, ejecutá una vuelta y desactivá S. Ejecutá otra vuelta: PB1 sigue encendido, porque PORTB conserva su valor.
- Activá R y ejecutá una vuelta: la alarma se borra. Observá cómo se parece a la alarma con flip-flop del curso anterior.
- Con el programa 3, activá y desactivá S varias veces ejecutando una vuelta en cada cambio. El LED alterna solo con los flancos ascendentes.
- Con el programa 4, contá pulsaciones hasta 7 y mirá cómo la cuenta vuelve a 0. Usá R para borrarla en cualquier momento.
Desafío: perder un pulso
Con el programa 3 o 4, activá S y volvé a desactivarlo sin ejecutar ninguna vuelta del bucle entre ambos cambios. Ejecutá después una vuelta: el programa no registró nada. Es el mismo fenómeno del modelo en Python: lo que ocurre entre dos lecturas no existe para el programa.
10 · Método de trabajo
Cómo plantear un problema para un microcontrolador
- Listá las entradas y las salidas. Distinguí si son digitales (pulsador, LED), analógicas (potenciómetro, sensor de temperatura) o de comunicación (otro chip, la computadora).
- Definí el estado. ¿Qué debe recordar el sistema? Puede ser un bit de salida, una variable o un dato guardado en EEPROM.
- Precisá los tiempos. ¿Cada cuánto hay que leer? ¿Cuál es el evento más breve que no se puede perder? ¿Cuánto puede tardar la respuesta?
- Revisá los niveles eléctricos. Tensión de alimentación y de los sensores, corriente que pide cada salida y compatibilidad entre 5 V y 3,3 V.
- Elegí los periféricos. Decidí qué hará el hardware (temporizador, ADC, UART) y qué hará el programa.
- Escribí y probá en pasos pequeños. Empezá encendiendo un LED, luego leé una entrada y agregá funciones de a una.
En la mesa de trabajo, antes de culpar al programa, comprobá lo básico: la alimentación (con el multímetro), la masa común, el capacitor de desacople cerca del chip y el estado del reset. Cuando el comportamiento es temporal, un osciloscopio o un analizador lógico muestra lo que el multímetro no puede: flancos, anchos de pulso y rebotes.
11 · Comprensión
Confusiones frecuentes
«Un microcontrolador es lo mismo que Arduino»
Arduino es una plataforma de placas, bibliotecas y herramientas que usa microcontroladores de distintos fabricantes. El microcontrolador es el chip; la placa y el entorno de programación son productos construidos alrededor de él.
«Es una computadora común, pero más pequeña»
Comparte la estructura básica, pero no suele tener sistema operativo, memoria virtual ni disco. Ejecuta un único programa, con recursos medidos en kilobytes, y accede a sus periféricos directamente.
«Todo ocurre a la vez, como en un circuito»
La CPU ejecuta una instrucción tras otra. Lo que sí ocurre en paralelo son los periféricos y los temporizadores. Para que parezca que el sistema hace varias cosas, el programa se organiza con interrupciones o tareas que se alternan rápidamente.
«Más bits o más megahertz siempre es mejor»
Depende del problema. Muchas aplicaciones se resuelven con un microcontrolador de 8 bits y pocos megahertz. Un chip más potente consume más y cuesta más; conviene elegir según los periféricos, la memoria y el consumo necesarios.
«Un pin puede conectarse directamente a cualquier carga»
Cada pin entrega y soporta una corriente limitada y trabaja con una tensión determinada. Un motor, un relé o una tira de LED necesitan un transistor o un controlador intermedio. Lo veremos en el tema de actuadores.
12 · Práctica guiada
Predecí antes de comprobar
1. ¿Cableado o microcontrolador?
Decidí cuál de las dos opciones resulta más razonable: (a) encender un LED cuando dos interruptores están cerrados, sin cambios futuros; (b) medir una temperatura, compararla con un valor configurable y mostrar el resultado; (c) contar pulsos de una señal de 500 MHz; (d) un semáforo con tiempos configurables mediante un menú.
Ver solución razonada
(a) Una puerta AND o una conexión en serie basta. (b) y (d) son ideales para un microcontrolador: hay lectura analógica, configuración y decisiones. (c) supera la velocidad de un microcontrolador común: se usa un contador o divisor de hardware y el microcontrolador solo lee el resultado.
2. Tiempo de una vuelta
Un bucle principal tarda 40 ciclos de reloj con un reloj de 16 MHz. ¿Cuánto dura una vuelta y qué ancho mínimo debe tener un pulso para estar seguro de detectarlo?
Ver solución
Un ciclo dura 62,5 ns, de modo que 40 ciclos son 2,5 µs. El pulso debería durar más de 2,5 µs para que una lectura lo encuentre activo. Es equivalente a muestrear a 400 kHz.
3. Seguir el programa 3
El programa «Alternar» parte con PB1 = 0 y previo = 0. El sensor vale, en seis vueltas consecutivas: 0, 1, 1, 0, 1, 0. ¿Cuál es el valor de PB1 después de cada vuelta?
Ver solución
0, 1, 1, 1, 0, 0. PB1 se invierte solo en los flancos ascendentes: en la vuelta 2 (0→1) y en la vuelta 5 (0→1). Comprobalo en el laboratorio.
4. Cambiar una prioridad sin tocar un cable
En la alarma queremos que, si S y R valen 1 a la vez, gane la detección. ¿Qué cambia en el programa?
Ver solución
Se invierte el orden de las condiciones: primero if (PINB & (1 << PB0)) para encender y después else if (PINB & (1 << PB4)) para apagar. Con lógica cableada habría que rediseñar la ecuación y modificar las puertas.
5. ¿Entra en el ATmega328P?
Un proyecto necesita 12 KB de código, 300 bytes de variables y 200 bytes de configuración que deben sobrevivir cuando se desconecta la alimentación. ¿En qué memoria va cada cosa y alcanza la capacidad?
Ver solución razonada
El código va a la Flash (32 KB) y sobra espacio. Las variables van a la SRAM (2 KB): 300 bytes alcanzan, aunque hay que dejar lugar para la pila. La configuración persistente va a la EEPROM (1 KB): 200 bytes entran. El proyecto cabe con holgura.
13 · Síntesis
Ideas para recordar
- Un microcontrolador integra CPU, memoria, reloj y periféricos en un solo chip.
- Su comportamiento lo define un programa, el firmware, grabado en memoria Flash.
- Los bloques que ya conocés (puertas, registros, contadores y memorias) reaparecen dentro del chip.
- El esquema habitual es inicializar y luego repetir: leer, decidir y actuar.
- La CPU ejecuta instrucciones de a una; los periféricos trabajan en paralelo.
- Un evento más corto que una vuelta del bucle puede pasar inadvertido.
- Conviene usar un microcontrolador cuando hay muchas funciones, decisiones complejas o necesidad de cambiar el comportamiento sin rehacer el circuito.
¿Listo para el tema 2?
Antes de avanzar, explicá con tus palabras la diferencia entre un microcontrolador y un microprocesador, nombrá cuatro bloques internos con su equivalente en lógica digital y describí por qué un pulso muy breve puede perderse. Si podés justificar las tres respuestas, ya tenés el mapa general.
En el próximo tema vamos a recorrer las familias de microcontroladores (AVR, ARM Cortex-M, ESP32, RP2040 y PIC) y los criterios para elegir el más adecuado para cada proyecto.