01 · Punto de partida
Analógico a partir de digital
Un pin de salida solo tiene dos niveles. Pero si alterna entre ambos mucho más rápido de lo que el dispositivo conectado puede seguir, ese dispositivo «ve» el promedio. Un LED encendido la mitad del tiempo a miles de veces por segundo se ve a media luz; un motor recibe, en promedio, media tensión; un filtro RC convierte la señal en una tensión continua intermedia. Esa técnica se llama modulación por ancho de pulso (pulse-width modulation, PWM).
Es la forma barata de salida analógica de casi todos los microcontroladores: no hace falta un conversor digital-analógico, solo un temporizador. En el tema 24 viste que el comparador puede cambiar un pin por hardware en un valor de cuenta preciso; la PWM combina esas ideas con un modo de funcionamiento del contador que repite el ciclo sin ayuda de la CPU.
Retomamos los temporizadores (tema 23), las salidas del comparador (tema 24) y la electrónica de los pines (tema 16).
02 · Los parámetros
Tres números: ciclo, frecuencia y resolución
| Parámetro | Definición | Qué decide |
|---|---|---|
| Ciclo de trabajo (duty cycle) | D = talto / T | El valor medio: Vmedio = D · VCC. Es lo que se varía para «regular» |
| Frecuencia | f = 1 / T | Qué tan «lisa» ve la carga el promedio: si es baja, un LED titila y un motor vibra; si es alta, mejor |
| Resolución | Cantidad de valores de ciclo de trabajo distintos: TOP + 1 niveles | La finura del control: 8 bits dan pasos de 0,39 % |
Los tres están ligados por el mismo contador: la frecuencia es freloj / (N · pasos por período), y los pasos por período son la resolución. A reloj y prescaler fijos, más resolución significa menos frecuencia, y viceversa. Esa es la tensión central del diseño de una PWM y volverá en la sección 6.
03 · Cómo se genera
PWM por hardware: salidas y pines
Se podría generar una PWM con una interrupción periódica que subiera y bajara un pin, pero consumiría CPU y tendría jitter. Los temporizadores del ATmega328P lo hacen por hardware: el contador recorre su ciclo, el comparador marca dos instantes por período, y el pin de salida sube y baja solo, sin una sola instrucción por flanco. Hay seis canales:
| Canal | Pin del chip | Pin de la placa Uno | Temporizador | Registro de comparación |
|---|---|---|---|---|
| OC0A | PD6 | D6 | Timer0 (8 bits) | OCR0A |
| OC0B | PD5 | D5 | Timer0 (8 bits) | OCR0B |
| OC1A | PB1 | D9 | Timer1 (16 bits) | OCR1A |
| OC1B | PB2 | D10 | Timer1 (16 bits) | OCR1B |
| OC2A | PB3 | D11 | Timer2 (8 bits) | OCR2A |
| OC2B | PD3 | D3 | Timer2 (8 bits) | OCR2B |
Cada temporizador maneja dos canales con la misma frecuencia (la del contador) y ciclos de trabajo independientes (OCRnA y OCRnB). Si necesitás frecuencias diferentes, hay que usar temporizadores distintos. Son los pines marcados con «~» en la placa Uno: D3, D5, D6, D9, D10 y D11.
Los bits COMnx1:0 de TCCRnA deciden cómo se conecta el pin en los modos de PWM:
| COMnx1:0 | Modo de salida | Comportamiento |
|---|---|---|
00 | Desconectado | El pin es un GPIO común |
10 | No inversor | Pin en alto durante el «ancho»: a mayor OCR, mayor ciclo de trabajo |
11 | Inversor | Pin en bajo durante el «ancho»: a mayor OCR, menor ciclo de trabajo |
El pin tiene que estar configurado como salida en DDRx (el temporizador maneja el nivel pero no la dirección). Y recordá que los canales PWM comparten pines con otras funciones: D10 y D11 con el bus SPI (SS y MOSI) y D3 con la interrupción externa INT1.
04 · El modo más sencillo
Fast PWM
En el modo rápido (Fast PWM) el contador es de pendiente simple: sube de 0 a TOP y vuelve a 0. Con la salida no inversora, el pin sube en 0 y baja al coincidir con OCR. Resultan:
Con TOP = 255 (8 bits) y un reloj de 16 MHz, el prescaler ÷64 da 976,56 Hz y el ÷1, 62,5 kHz. Como la salida siempre empieza en alto, el ciclo de trabajo mínimo no es 0 %: con OCR = 0 hay un pulso de una cuenta (1/256 = 0,39 %). El 100 % se logra con OCR = TOP, que mantiene la salida siempre en alto. Para tener 0 % de verdad hay que desconectar la salida (COM = 00) y poner el pin en bajo.
// PWM de ~976 Hz y 25 % en OC0A (PD6, pin D6)
DDRD |= (1 << PD6); // el pin debe ser una salida
TCCR0A = (1 << COM0A1) | (1 << WGM01) | (1 << WGM00); // Fast PWM, salida no inversora
OCR0A = 63; // (63 + 1) / 256 = 25 %
TCCR0B = (1 << CS01) | (1 << CS00); // ÷64: el temporizador arranca
// Para cambiar el brillo después, basta con escribir OCR0A:
OCR0A = 191; // 75 %
Una vez arrancado, el programa solo escribe OCR0A y el hardware hace el resto. El registro OCR0A tiene doble buffer en los modos de PWM: el valor nuevo se aplica recién al comenzar el período siguiente, de modo que cambiar el ciclo de trabajo en cualquier momento no produce pulsos truncados.
Existe también la variante con OCRnA como TOP (modo 7 de los temporizadores de 8 bits): permite elegir la frecuencia con precisión, pero el canal A deja de servir como salida de PWM y queda solo el B.
05 · Pendiente doble
PWM de fase correcta
En el modo de fase correcta (phase correct) el contador es de doble pendiente: sube de 0 a TOP y después baja de TOP a 0. La salida no inversora se baja en la coincidencia al subir y se sube en la coincidencia al bajar. El pulso queda centrado en el período, y:
Con TOP = 255, la frecuencia es de freloj/(N · 510): la mitad aproximadamente que en el modo rápido para el mismo prescaler (31,37 kHz con ÷1; 490,2 Hz con ÷64). A cambio:
- El ciclo de trabajo llega a 0 % y a 100 % (
OCR = 0es una salida siempre baja), y el paso es OCR/TOP. - El pulso es simétrico, centrado en el período. En el control de motores con puentes H, eso reduce las corrientes pico y el ruido, y por eso es el modo preferido para cargas inductivas.
- El cambio de OCR se aplica en la cima (en el modo rápido, al comenzar el período), lo que evita pulsos asimétricos durante la actualización.
El criterio de elección es simple: modo rápido cuando importa la frecuencia más alta o la mayor resolución por frecuencia; fase correcta cuando importa la simetría y el rango completo de 0 a 100 %. Para un LED o un servo, cualquiera de los dos funciona.
Las funciones analogWrite() de Arduino usan, por defecto, modo rápido a 976,56 Hz en los pines 5 y 6 (temporizador 0, ÷64) y fase correcta a 490,2 Hz en los pines 3, 9, 10 y 11 (temporizadores 1 y 2, ÷64). Esas frecuencias son modestas: audibles en motores y con sensible parpadeo en algunas cámaras. Con registros se pueden cambiar.
06 · Un compromiso inevitable
Frecuencia contra resolución
Como la frecuencia depende de los pasos por período, subir la resolución baja la frecuencia. El temporizador 1, de 16 bits, permite elegir TOP libremente con el registro ICR1 (modo 14 para rápido, modo 10 para fase correcta) o usar los valores fijos de 8, 9 y 10 bits.
| Resolución | Niveles | Frecuencia |
|---|---|---|
| 8 bits | 256 | 62,5 kHz |
| 10 bits | 1024 | 15,6 kHz |
| 12 bits | 4096 | 3,9 kHz |
| 14 bits | 16 384 | 977 Hz |
| 16 bits | 65 536 | 244 Hz |
Para elegir TOP a partir de la frecuencia deseada: TOP + 1 = freloj / (N · f). La resolución resultante es el logaritmo en base 2 de ese número: para 20 kHz a 16 MHz con ÷1, TOP + 1 = 800 (unos 9,6 bits).
Frecuencia mínima razonable: para un LED, por encima de unos 100 Hz para que no se vea el parpadeo (mejor 400 Hz o más para evitar efectos estroboscópicos con movimiento); para un motor, por encima de 20 kHz si se quiere evitar el zumbido audible; para un servo, exactamente 50 Hz.
07 · Para qué sirve
Aplicaciones
Brillo de un LED
El ojo percibe el brillo de forma no lineal: duplicar el ciclo de trabajo no parece duplicar el brillo. Con una PWM lineal, la mitad inferior del rango parece cubrir casi todo el cambio visible. Se corrige con una tabla de gamma (potencia 2,2 aproximadamente): para ocho brillos que se perciban parejos, el ciclo de trabajo va 0, 1,6, 6,3, 15,7, 29, 47,8, 71,4 y 100 %. En el programa se guarda la tabla en Flash (tema 8) y se la indexa.
Velocidad de un motor
La PWM entrega tensión media variable a un motor de corriente continua a través de un transistor (nunca directamente desde el pin, tema 38). La inductancia del motor suaviza la corriente. Una frecuencia por debajo de unos 20 kHz puede producir un zumbido; una muy alta aumenta las pérdidas de conmutación del transistor.
Posición de un servo
Un servo de aeromodelismo espera un pulso cada 20 ms (50 Hz) cuyo ancho codifica el ángulo: 1 ms en un extremo, 1,5 ms en el centro y 2 ms en el otro. No es una PWM de valor medio, sino una señal de temporización. Con el temporizador 1 en modo rápido, ÷8 (0,5 µs por cuenta) y ICR1 = 39999 se obtiene exactamente 50 Hz; el pulso dura OCR1A + 1 cuentas, de modo que OCR1A = 1999 es 1 ms, 2999 es 1,5 ms y 3999 es 2 ms: unos 2000 pasos de resolución.
Una tensión analógica con un filtro RC
Un filtro pasa-bajo de una resistencia y un capacitor convierte la PWM en una tensión continua proporcional al ciclo de trabajo: es un conversor digital-analógico económico (DAC). Su frecuencia de corte es fc = 1 / (2π R C) y debe estar muy por debajo de la frecuencia de la PWM. La ondulación residual es aproximadamente VCC · D · (1 − D) / (R · C · f): con 62,5 kHz, 10 kΩ y 1 µF queda en unos 2 mV, menos de un décimo de un paso de 8 bits (19,5 mV). El precio es la velocidad: con τ = 10 ms, la tensión tarda unos 46 ms en asentarse. Y la tensión de salida baja si se conecta una carga, de modo que a menudo hace falta un seguidor con amplificador operacional.
08 · Analogía con programación
Calcular una PWM y verla desde el ojo
Este programa reúne los cálculos del tema: las frecuencias por defecto de analogWrite(), la relación frecuencia-resolución del temporizador 1, los valores de OCR1A para un servo, la tabla de gamma para ocho brillos parejos y la ondulación de un filtro RC como DAC.
Python en tu navegador. Los bloques son editables: cambiá los valores y presioná «Ejecutar Python». La primera vez tarda unos segundos en cargar.
import math
F_CPU = 16_000_000
def fast(preescaler, top=255):
return F_CPU / (preescaler * (top + 1))
def fase_correcta(preescaler, top=255):
return F_CPU / (preescaler * 2 * top)
print("Frecuencias por defecto de analogWrite en una Uno (todas con ÷64):")
print(f" pines 5 y 6 (Timer0, Fast PWM) : {fast(64):7.2f} Hz")
print(f" pines 9 y 10 (Timer1, fase correcta) : {fase_correcta(64):7.2f} Hz")
print(f" pines 3 y 11 (Timer2, fase correcta) : {fase_correcta(64):7.2f} Hz")
print()
print("Frecuencia contra resolución (Timer1, Fast PWM con ICR1 como TOP, sin prescaler):")
for bits in (8, 10, 12, 14, 16):
top = (1 << bits) - 1
print(f" {bits:>2} bits ({top + 1:>6} niveles) -> {fast(1, top):10.1f} Hz")
print()
# Servo: 50 Hz (período de 20 ms) y pulso de 1 a 2 ms con ÷8 (0,5 µs por cuenta).
TOP_SERVO = 20_000 // 0.5 - 1 # 39999
print(f"Servo: TOP = {TOP_SERVO:.0f} -> {fast(8, int(TOP_SERVO)):.2f} Hz")
for ancho_us in (1000, 1500, 2000):
ocr = round(ancho_us / 0.5) - 1 # el pulso dura OCR + 1 cuentas
print(f" pulso de {ancho_us} µs -> OCR1A = {ocr} ({(ocr + 1) * 0.5:.1f} µs reales)")
print()
# Brillo percibido: la respuesta del ojo no es lineal. Con gamma 2,2, 8 pasos de brillo parejo:
print("Ciclo de trabajo para 8 brillos percibidos parejos (gamma 2,2):")
niveles = [round(255 * (i / 7) ** 2.2) for i in range(8)]
print(" OCR =", niveles, " ->", [f"{100 * n / 255:.1f} %" for n in niveles])
print()
# Filtro RC como conversor digital-analógico
def rc(frecuencia_pwm, r, c, duty, vcc=5.0):
tau = r * c
fc = 1 / (2 * math.pi * tau)
ondulacion = vcc * duty * (1 - duty) / (tau * frecuencia_pwm)
return fc, tau, ondulacion
for f_pwm, r, c in ((62_500, 10_000, 1e-6), (62_500, 1_000, 1e-6), (976.56, 10_000, 1e-6)):
fc, tau, onda = rc(f_pwm, r, c, 0.5)
print(f"PWM {f_pwm:9.1f} Hz, R={r / 1000:>4.0f} kΩ, C={c * 1e6:.0f} µF: corte {fc:6.1f} Hz, "
f"τ={tau * 1000:6.1f} ms, ondulación ≈ {onda * 1000:7.1f} mV (un paso de 8 bits = {5000 / 256:.1f} mV)")
Resultado: 976,56 Hz en los pines 5 y 6 y 490,2 Hz en los demás; 62,5 kHz con 8 bits y 244 Hz con 16; para el servo, OCR1A = 1999, 2999 y 3999; la tabla de gamma 0, 4, 16, 40, 74, 122, 182 y 255; y una ondulación de 2 mV con R = 10 kΩ y 62,5 kHz frente a 128 mV si la PWM fuera de 976 Hz. Probá cambiar el exponente de gamma o el valor de C.
El modelo del filtro es el de primer orden con una carga ideal. Un capacitor real tiene tolerancia amplia (20 %) y la resistencia de salida del pin, de unas decenas de ohmios, se suma a R.
09 · Exploración interactiva
Calculadora, ondas y filtro
La primera herramienta calcula frecuencia, resolución y registros de una PWM en cualquiera de los tres temporizadores y los dos modos. La segunda dibuja el contador y la salida para ver la diferencia entre ambos modos. La tercera calcula el filtro RC de un DAC por PWM.
Banco de PWM
1. Calcular una PWM
2. Formas de onda (contador de 4 bits, TOP = 15)
Fast PWM (contador en azul, OCR en naranja, salida no inversora en amarillo)
Fase correcta
3. Filtro RC como conversor digital-analógico
Las formas de onda usan un contador de 4 bits para que se vean las cuentas una por una; el comportamiento es el mismo con TOP = 255. En el modo de fase correcta, los instantes de cambio siguen la regla del hardware: la salida baja tras la coincidencia al subir y sube tras la coincidencia al bajar.
Recorrido guiado
- En la calculadora, Timer0, Fast PWM, ÷64 y 50 %: 976,56 Hz,
OCR = 127y 2,5 V de media. Cambiá a fase correcta: 490,2 Hz yOCR = 128(50,196 %). - Elegí Timer1, Fast PWM, TOP personalizado 39999, ÷8 y 7,5 %: 50 Hz y
OCR1A = 2999. Es un servo en el centro (pulso de 1,5 ms). - Pasá a 0 %: en Fast PWM el ciclo real es 0,391 %. Probá fase correcta: llega a 0 % exacto.
- En las formas de onda, movés OCR de 0 a 15: en el modo rápido el ancho crece de 1/16 a 16/16; en fase correcta de 0/15 a 15/15, centrado en el período.
- En el filtro, con 62,5 kHz, 10 kΩ y 1 µF: ondulación de 2 mV. Cambiá la frecuencia de la PWM a 976 Hz: la ondulación sube a unos 128 mV, varios pasos de 8 bits.
Desafío: una PWM de 20 kHz con la mayor resolución
Con el Timer1, 16 MHz, Fast PWM y ÷1: TOP + 1 = 16 000 000 / 20 000 = 800, es decir, ICR1 = 799, unos 9,6 bits. Es la mayor resolución posible a 20 kHz con ese reloj: la frecuencia sube y la resolución baja. Probalo en la calculadora con TOP personalizado 799.
10 · Método de trabajo
Cómo configurar una PWM
- Definí qué necesitás: frecuencia mínima aceptable, resolución, rango (¿0–100 % exacto?), polaridad.
- Elegí el canal según el pin disponible; revisá que no compita con otra función (SPI, UART,
millis()en el temporizador 0). - Elegí el modo: rápido para frecuencia máxima; fase correcta para simetría y 0–100 % exacto; Timer1 con
ICR1para frecuencia exacta y alta resolución. - Calculá TOP y el prescaler con
f = freloj / (N · pasos)y verificá que la resolución alcance. - Configurá en orden: el pin como salida, el modo y las salidas en
TCCRnA, los registros de comparación y, al final, el prescaler enTCCRnB(que arranca el temporizador). - Calculá el OCR para cada ciclo de trabajo, con el «+1» del modo rápido.
- Verificá con el osciloscopio la frecuencia y el ancho; con el multímetro, la tensión media (en un filtro RC).
Si la señal no aparece, el orden de sospecha es: el DDRx sin configurar, los bits COM en 00, el prescaler sin escribir (temporizador detenido) o un pin ocupado por otra función.
11 · Comprensión
Confusiones frecuentes
«OCR = 0 da 0 % en Fast PWM»
Da un pulso de una cuenta por período (1/256 = 0,39 % con 8 bits). Para 0 % hay que desconectar la salida y poner el pin en bajo, o usar el modo de fase correcta.
«Con 8 bits de resolución siempre tengo 256 valores de ciclo de trabajo a la misma frecuencia»
En fase correcta con TOP = 255, hay 256 valores, pero la frecuencia es la mitad que en el modo rápido. La resolución, la frecuencia y el modo están ligados por los pasos del contador.
«Los dos canales del mismo temporizador pueden tener distinta frecuencia»
No: comparten el contador, así que tienen la misma frecuencia. Solo difiere el ciclo de trabajo.
«Más frecuencia siempre es mejor»
Ayuda a suavizar y evitar el zumbido, pero baja la resolución y aumenta las pérdidas de conmutación del transistor que maneja la carga.
«Un servo se controla con el valor medio de la PWM»
Un servo responde al ancho del pulso (1 a 2 ms) con una frecuencia de 50 Hz, no al valor medio. El ciclo de trabajo del 5 al 10 % solo es una consecuencia de eso.
12 · Práctica guiada
Predecí antes de comprobar
1. Frecuencia del modo rápido
Timer0, Fast PWM con TOP = 255, prescaler ÷8 y reloj de 16 MHz. ¿Qué frecuencia tiene la PWM?
Ver solución
16 000 000 / (8 × 256) = 7812,5 Hz.
2. Frecuencia de la fase correcta
La misma configuración sin prescaler (÷1), en modo de fase correcta con TOP = 255: ¿cuál es la frecuencia?
Ver solución
16 000 000 / (1 × 2 × 255) = 31 372 Hz (unos 31,4 kHz).
3. Un OCR para el 30 %
En Fast PWM de 8 bits, ¿qué OCR da lo más cercano al 30 % y qué ciclo real resulta?
Ver solución
0,30 × 256 = 76,8 → 77 niveles en alto → OCR = 76. Ciclo real: 77/256 = 30,08 %.
4. Resolución a 20 kHz
Con el Timer1 a 16 MHz, Fast PWM y ÷1, ¿qué TOP da 20 kHz y qué resolución en bits resulta?
Ver solución
TOP + 1 = 16 000 000 / 20 000 = 800, así que ICR1 = 799. Resolución: log₂(800) ≈ 9,6 bits.
5. Ondulación de un DAC
Una PWM de 62 500 Hz y 50 % alimenta un filtro RC de 10 kΩ y 1 µF a 5 V. ¿Cuánta ondulación pico a pico queda?
Ver solución
5 V × 0,5 × 0,5 / (10 000 Ω × 1 µF × 62 500 Hz) = 1,25 / 625 = 2 mV, una décima de un paso de 8 bits (19,5 mV).
13 · Síntesis
Ideas para recordar
- La PWM regula una carga encendiendo y apagando un pin: el valor medio es el ciclo de trabajo por la tensión de alimentación.
- Tres números la definen: ciclo de trabajo, frecuencia y resolución; con un reloj fijo, más resolución implica menos frecuencia.
- El ATmega328P tiene seis canales de PWM por hardware: OC0A/B, OC1A/B y OC2A/B; cada temporizador comparte la frecuencia entre sus dos canales.
- Fast PWM: f = freloj/(N·(TOP+1)), D = (OCR+1)/(TOP+1); no llega a 0 %.
- Fase correcta: f = freloj/(N·2·TOP), D = OCR/TOP; pulso centrado y rango de 0 a 100 %.
- Con
ICR1el temporizador 1 permite elegir TOP, y así la frecuencia exacta (50 Hz para un servo) y resoluciones de hasta 16 bits. - Aplicaciones: LED con corrección de gamma, motores a través de un transistor, servos con pulsos de 1 a 2 ms y un DAC con filtro RC.
¿Listo para el tema 26?
Antes de avanzar, calculá la frecuencia de una PWM dada, elegí un OCR para un ciclo de trabajo y justificá cuándo usarías fase correcta en lugar de modo rápido. Si podés justificar las tres respuestas, ya podés generar señales analógicas con el hardware.
En el próximo tema, un taller de PWM: atenuamos un LED con una curva de brillo perceptual y movemos un servo, con las manos en la placa.