← Índice del curso

Microcontroladores · Tema 25

PWM: ciclo de trabajo, frecuencia y resolución

Un microcontrolador solo sabe encender y apagar un pin. La modulación por ancho de pulso convierte esa limitación en una virtud: encendiendo y apagando muy rápido y variando cuánto tiempo está encendido, se regula el brillo de un LED, la velocidad de un motor, la posición de un servo o incluso una tensión analógica.

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

Señales PWM con ciclos de trabajo de 25, 50 y 75 por ciento Tres ondas de la misma frecuencia. La primera está en alto un cuarto del período, la segunda la mitad y la tercera tres cuartos. El valor medio es proporcional al tiempo en alto. 25 %50 %75 % promedio 1,25 Vpromedio 2,5 Vpromedio 3,75 V período Tperíodo T
Los parámetros de una señal PWM.
ParámetroDefiniciónQué decide
Ciclo de trabajo (duty cycle)D = talto / TEl valor medio: Vmedio = D · VCC. Es lo que se varía para «regular»
Frecuenciaf = 1 / TQué tan «lisa» ve la carga el promedio: si es baja, un LED titila y un motor vibra; si es alta, mejor
ResoluciónCantidad de valores de ciclo de trabajo distintos: TOP + 1 nivelesLa 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:

Salidas de PWM por hardware del ATmega328P.
CanalPin del chipPin de la placa UnoTemporizadorRegistro de comparación
OC0APD6D6Timer0 (8 bits)OCR0A
OC0BPD5D5Timer0 (8 bits)OCR0B
OC1APB1D9Timer1 (16 bits)OCR1A
OC1BPB2D10Timer1 (16 bits)OCR1B
OC2APB3D11Timer2 (8 bits)OCR2A
OC2BPD3D3Timer2 (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:

Salida del canal en los modos de PWM (con TOP fijo en 0xFF o con ICR1).
COMnx1:0Modo de salidaComportamiento
00DesconectadoEl pin es un GPIO común
10No inversorPin en alto durante el «ancho»: a mayor OCR, mayor ciclo de trabajo
11InversorPin 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:

f = freloj / (N · (TOP + 1)) · D = (OCR + 1) / (TOP + 1)

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:

f = freloj / (N · 2 · TOP) · D = OCR / TOP

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 = 0 es 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.

Timer1 en Fast PWM, sin prescaler, a 16 MHz.
ResoluciónNivelesFrecuencia
8 bits25662,5 kHz
10 bits102415,6 kHz
12 bits40963,9 kHz
14 bits16 384977 Hz
16 bits65 536244 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

Frecuencia—
Resolución—
Valor de OCR—
Tensión media—

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

Frecuencia de corte—
Constante de tiempo—
Ondulación—
Tensión de salida—

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

  1. En la calculadora, Timer0, Fast PWM, ÷64 y 50 %: 976,56 Hz, OCR = 127 y 2,5 V de media. Cambiá a fase correcta: 490,2 Hz y OCR = 128 (50,196 %).
  2. 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).
  3. Pasá a 0 %: en Fast PWM el ciclo real es 0,391 %. Probá fase correcta: llega a 0 % exacto.
  4. 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.
  5. 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

  1. Definí qué necesitás: frecuencia mínima aceptable, resolución, rango (¿0–100 % exacto?), polaridad.
  2. Elegí el canal según el pin disponible; revisá que no compita con otra función (SPI, UART, millis() en el temporizador 0).
  3. Elegí el modo: rápido para frecuencia máxima; fase correcta para simetría y 0–100 % exacto; Timer1 con ICR1 para frecuencia exacta y alta resolución.
  4. Calculá TOP y el prescaler con f = freloj / (N · pasos) y verificá que la resolución alcance.
  5. Configurá en orden: el pin como salida, el modo y las salidas en TCCRnA, los registros de comparación y, al final, el prescaler en TCCRnB (que arranca el temporizador).
  6. Calculá el OCR para cada ciclo de trabajo, con el «+1» del modo rápido.
  7. 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 ICR1 el 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.