Saltar al contenido

Artículo técnico

Programar un microcontrolador desde cero: guía práctica paso a paso

Desde elegir el microcontrolador hasta cargar el firmware en la placa, esta guía recorre cada fase con criterios técnicos concretos y sin rodeos.

DCMI·17 Jul 2026·7 min de lectura
Programar un microcontrolador desde cero: guía práctica paso a paso
Firmware · DCMIFoto · Nicolas Thomas / Unsplash

Programar un microcontrolador desde cero no es difícil, pero sí requiere tomar decisiones en el orden correcto. Un error en la elección del chip obliga a rediseñar la placa. Un entorno de desarrollo mal configurado puede hacer que un firmware correcto parezca defectuoso. Esta guía ordena el proceso en fases claras para que cada decisión tenga sentido antes de pasar a la siguiente.

Fase 1: Elegir el microcontrolador adecuado

Antes de escribir una sola línea de código hay que saber qué chip se va a programar. La elección depende de tres factores principales:

  • Periféricos necesarios: UART, SPI, I²C, ADC, PWM, USB. Cuenta cuántos canales de cada tipo necesita el diseño.
  • Potencia de cálculo: un control de motor con lazo cerrado a 20 kHz exige más que un lector de temperatura cada segundo.
  • Consumo y formato: para batería, un STM32L0 o un ATmega328P en modo sleep puede ser suficiente. Para procesado intensivo, un ESP32-S3 o un STM32F4 son más razonables.

Comparativa de familias habituales

FamiliaNúcleoFlash típicaPeriféricos destacadosCaso de uso frecuente
ATmega328PAVR 8 bit / 16 MHz32 KBUART, SPI, I²C, 6 ADCPrototipos, control sencillo
STM32F103ARM Cortex-M3 / 72 MHz64–128 KBCAN, USB, 16 ADC, timers avanzadosIndustria, motores
STM32F4xxARM Cortex-M4 / 168 MHz512 KB–2 MBFPU, DSP, Ethernet, SDIOProcesado de señal, visión
ESP32-S3Xtensa dual-core / 240 MHz384 KB + PSRAMWi-Fi, BLE 5, USB OTGIoT, HMI con pantalla
SAMD21ARM Cortex-M0+ / 48 MHz256 KBUSB nativo, I²S, 12-bit DACAudio, instrumentación portátil

Elegir el más potente no siempre es la mejor decisión. Un STM32F4 consume entre 100 y 150 mA en funcionamiento pleno. Un ATmega328P en modo normal ronda los 10–15 mA. Si el producto va a funcionar con batería años, esa diferencia es determinante.

Fase 2: Preparar el entorno de desarrollo

El entorno de desarrollo agrupa el compilador, las bibliotecas y el sistema de construcción. Los más usados:

  • Arduino IDE / PlatformIO: accesibles para prototipos rápidos. PlatformIO permite gestionar dependencias y múltiples plataformas desde un mismo proyecto.
  • STM32CubeIDE: entorno oficial de STMicroelectronics, basado en Eclipse. Genera código de inicialización desde una interfaz gráfica de pines, lo que reduce errores de configuración de registros.
  • MPLAB X + XC8/XC16: para familias Microchip PIC.
  • GCC + Makefile a mano: máximo control, necesario cuando el proyecto tiene restricciones de tamaño o certificación.

Cualquiera que sea el entorno, conviene verificar desde el principio que el compilador genera código para la arquitectura correcta. Un error frecuente es compilar para ARM Cortex-M4 con las opciones de Cortex-M0, lo que produce instrucciones ilegales que el chip simplemente no ejecuta.

Configurar el reloj del sistema

Todos los microcontroladores arrancan con su oscilador interno, normalmente a una frecuencia reducida (8 MHz en STM32, 1 MHz en ATmega por defecto con fuses). Si el diseño necesita frecuencia máxima, hay que configurar el PLL antes de cualquier inicialización de periféricos. Hacerlo después puede dejar timers y baudrates desajustados.

Fase 3: Escribir el firmware mínimo funcional

El primer firmware no tiene que hacer nada útil. Tiene que demostrar que el chip arranca, el reloj está bien y la comunicación con el depurador funciona.

Un firmware mínimo contiene:

  1. Inicialización del reloj del sistema (si se cambia del valor por defecto).
  2. Configuración de un GPIO de salida (el LED más cercano al pin de prueba).
  3. Bucle principal que enciende y apaga ese GPIO con un retardo conocido.

Si el LED parpadea al ritmo esperado, el reloj está bien y el chip ejecuta código. A partir de ahí se añaden periféricos de uno en uno. Añadirlos todos a la vez dificulta localizar el origen de un fallo.

Gestión de interrupciones

Las interrupciones son el punto donde más errores se esconden en proyectos de principiantes. Dos reglas básicas:

  • Las rutinas de interrupción (ISR) deben ser lo más cortas posible. Captura el dato, activa una bandera, sal.
  • Las variables compartidas entre la ISR y el bucle principal deben declararse volatile. Sin este cualificador, el compilador puede optimizarlas fuera de la lectura y el comportamiento será impredecible.

Fase 4: Cargar el firmware en el chip

La carga del firmware (flashing) requiere un programador compatible con el chip elegido:

  • ST-Link V2 o V3: para STM32. Soporta SWD y JTAG, permite depuración en tiempo real.
  • AVRISP mkII / USBasp: para ATmega, usa el protocolo ISP.
  • J-Link: universal, compatible con prácticamente cualquier arquitectura ARM. Más caro, pero el soporte de depuración es muy completo.
  • Bootloader USB/UART: algunos chips permiten cargarse sin programador externo si se ha instalado previamente un bootloader en fábrica (STM32 por UART, ESP32 por USB).

El interfaz SWD de STM32 necesita solo dos señales (SWDIO y SWDCLK) más masa y alimentación. En un diseño nuevo, reservar estos cuatro pines en un conector de 2×5 o 1×4 desde el inicio evita tener que soldar cables a la placa más adelante. Es un detalle que en el diseño de PCB conviene planificar antes de enrutar.

Fase 5: Depurar el firmware

Depurar un microcontrolador en tiempo real es distinto a depurar software de escritorio. No hay sistema operativo que intercepte los fallos. Si el puntero de pila se corrompe, el chip puede reiniciarse sin avisar.

Herramientas útiles:

  • Puntos de interrupción por hardware (breakpoints): el depurador detiene la ejecución en una línea concreta. El Cortex-M tiene hasta 6 en STM32F4.
  • Watch points: detiene la ejecución cuando una variable cambia de valor. Muy útil para localizar escrituras inesperadas en memoria.
  • UART como canal de registro: imprimir el estado de variables por UART a 115200 baudios sigue siendo uno de los métodos más rápidos para entender qué ocurre en un bucle de control.
  • Analizador lógico: para verificar señales SPI, I²C o UART entre el microcontrolador y un periférico externo. Un modelo de 8 canales con el software Sigrok es suficiente para el 90 % de los casos.

Errores frecuentes y su causa

SíntomaCausa probable
El chip no responde al programadorSWD mal conectado o chip sin alimentación estable
Baudrate incorrecto en UARTReloj del sistema diferente al configurado en el registro
El ADC lee siempre 0 o 4095Pin configurado como salida digital en lugar de entrada analógica
La ISR se ejecuta en bucle sin pararBandera de interrupción no limpiada dentro de la ISR
El firmware arranca una vez y se cuelgaStack overflow por variables locales demasiado grandes

Del prototipo al producto

Cuando el firmware es estable en una placa de evaluación, el paso siguiente es integrarlo en un PCB propio. Aquí es donde los detalles de hardware que se tomaron como supuestos (decoupling, niveles de tensión de E/S, ruido en la alimentación del ADC) se vuelven críticos. Un PCB diseñado sin tener en cuenta las notas de aplicación del fabricante puede hacer que un firmware perfectamente válido se comporte de forma errática.

Si el proyecto va a pasar a fabricación en serie, los aspectos de testabilidad también forman parte del diseño desde el principio: puntos de prueba accesibles, pines de programación en posición conocida, posibilidad de cargar firmware en la línea de producción. Todo eso se decide en el diseño de la placa, no después.

Si tienes un proyecto en marcha y necesitas orientación sobre cómo estructurar el hardware alrededor del microcontrolador elegido, puedes describir el caso en la página de contacto.

Fin artículo · 7 min

Preguntas frecuentes

¿Qué microcontrolador es mejor para empezar desde cero?

Depende del proyecto. Si es un prototipo sencillo con pocos periféricos, un ATmega328P es suficiente y tiene abundante documentación. Si el proyecto va a escalar o necesita USB, CAN o mayor potencia de cálculo, merece la pena empezar directamente con un STM32F1 o STM32F4. Cambiar de chip a mitad de un desarrollo obliga a rehacer la inicialización de periféricos.

¿Necesito un programador externo para cargar el firmware?

No siempre. Muchos STM32 incluyen un bootloader de fábrica que permite cargar firmware por UART sin ningún hardware adicional. Los ESP32 se cargan por USB. Sin embargo, para depuración en tiempo real con puntos de interrupción sí se necesita un programador como ST-Link o J-Link.

¿En qué lenguaje se programa un microcontrolador?

C es el estándar en la industria. C++ se usa cuando la complejidad del proyecto justifica la sobrecarga (drivers orientados a objetos, contenedores STL con memoria estática). El ensamblador solo es necesario en rutinas de tiempo crítico o en la inicialización del arranque. Lenguajes de alto nivel como MicroPython existen, pero no son habituales en producción industrial.

¿Qué diferencia hay entre SWD y JTAG para depurar un STM32?

JTAG usa cuatro señales mínimo (TDI, TDO, TCK, TMS) y permite encadenar varios chips. SWD usa solo dos (SWDIO y SWDCLK), lo que ahorra pines en diseños compactos. Para la mayoría de proyectos con un único microcontrolador, SWD es suficiente y ocupa menos espacio en el PCB.