Un GPIO es un pin de propósito general que podemos configurar como entrada o salida para interactuar con el mundo exterior. Detrás de algo que parece una simple patita hay en realidad transistores, multiplexores y registros de configuración.
En lugar de quedarnos en el simple digitalWrite de Arduino, vamos a mirar qué ocurre realmente dentro del silicio. Este enfoque te sirve tanto si programas un ATmega en C como un STM32 o un ESP32.
En este artículo vamos a ignorar por un momento las funciones específicas de Arduino (digitalWrite) para entender la arquitectura universal de los puertos de entrada y salida, aplicable a AVR, PIC, STM32 o ESP32.
El GPIO digital: ¿qué hay dentro?
Un pin digital no es un simple cable directo a la CPU. Es un circuito periférico configurable que actúa como intermediario.
Modo salida (output)
Cuando configuramos un pin como salida, el microcontrolador conecta el pin físico a los raíles de alimentación interna (Vcc o GND) usando transistores (MOSFETs).
Existen dos topologías de salida fundamentales que debes conocer:
Push-pull (totem pole)
Es la configuración estándar. Usamos dos transistores: uno conectado a Vcc (PMOS) y otro a GND (NMOS).
- Para sacar un 1 (HIGH): Se activa el de arriba (Push). El pin entrega corriente desde Vcc.
- Para sacar un 0 (LOW): Se activa el de abajo (Pull). El pin drena corriente hacia GND.
- Ventaja: es rápido y puede controlar cargas pequeñas, como un LED con su resistencia, dentro de los límites de corriente del pin.
Open-drain (drenador abierto)
Aquí solo usamos el transistor de abajo (el que conecta a GND). El de arriba no existe (o se desactiva).
- Para sacar un 0: El transistor conecta el pin a GND.
- Para sacar un 1: El transistor se apaga. El pin queda “flotando” (desconectado).
¿Para qué sirve esto? Es la base de buses como I2C y permite fijar el nivel alto en el dominio de tensión adecuado. Necesitamos una resistencia pull-up para que, cuando el transistor se apague, la línea suba a ese nivel.
Modo entrada (input) y alta impedancia (Hi-Z)
Cuando configuramos un pin como entrada, desconectamos los transistores de salida. El pin entra en estado de Alta Impedancia (Hi-Z).
Eléctricamente, es como si el pin tuviera una resistencia enorme frente al circuito externo (del orden de megaohmios o más). “Escucha” el voltaje sin consumir apenas corriente y sin alterar el circuito.
El ADC: digitalizando la realidad
El mundo real es analógico. Para que la CPU entienda una temperatura o una posición, necesitamos el ADC (Analog-to-Digital Converter).
Muchos microcontroladores usan un ADC de tipo SAR (aproximaciones sucesivas). Es como una balanza que va probando pesas para estimar el valor.
La resolución (bits)
El ADC divide el voltaje de entrada en escalones discretos.
- 10 bits (Arduino Uno): 2¹⁰ niveles (0 a 1023).
- 12 bits (ESP32 / STM32): 2¹² niveles (0 a 4095).
El voltaje de referencia ( )
Este es el concepto crítico. El ADC no mide voltios absolutos, mide proporción respecto a su referencia.
Si tu
- Lectura 0 → 0V.
- Lectura 2048 → 1.65V.
- Lectura 4095 → 3.3V.
Si alimentas tu microcontrolador con una fuente ruidosa (USB de mala calidad) y usas esa misma alimentación como
PWM: el DAC del pobre
La mayoría de microcontroladores NO tienen un DAC (Convertidor Digital a Analógico) real. No pueden sacar 2.5V puros por un pin. Solo pueden sacar 0V o Vcc.
Para simular salidas analógicas (dimmear un LED, controlar un motor), usamos PWM (Pulse Width Modulation).
Consiste en generar una onda cuadrada a una frecuencia fija, variando el Duty Cycle (Ciclo de trabajo):
- 0%: Siempre apagado (0V promedio).
- 50%: Mitad encendido, mitad apagado (Vcc/2 promedio).
- 100%: Siempre encendido (Vcc promedio).
Frecuencia y resolución del PWM
Aquí también configuramos registros de hardware (Timers):
- Frecuencia: ¿Cuántas veces por segundo conmuta?
- Baja (50Hz): Ideal para Servomotores.
- Media (1kHz - 20kHz): Motores DC y LEDs.
- Alta (>20kHz): Inaudible para humanos (para evitar zumbidos en motores).
- Resolución: Cuántos pasos de anchura podemos definir (8 bits = 255 pasos).
Si conectas una señal PWM a un filtro RC (Resistencia + Condensador), puedes obtener un voltaje analógico real. El condensador promedia los pulsos.