Що таке ШІМ (PWM)?
Звичайні цифрові виводи GPIO можуть бути лише у двох станах: 0 або 1, вимкнено або увімкнено. Але багато задач у мікроелектроніці вимагають чогось більш гнучкого — наприклад, плавно регулювати яскравість світлодіода, швидкість двигуна чи положення сервоприводу. Одних лише вмикань та вимикань тут уже недостатньо.
Саме для таких випадків існує ШІМ (PWM) — спосіб “обманути” пристрій частими імпульсами так, що він сприймає їх як плавну зміну потужності. Це дозволяє отримати майже аналоговий сигнал, навіть якщо мікроконтролер видає тільки цифрові рівні.
ШІМ працює дуже просто: замість того щоб подавати на вихід постійну напругу, мікроконтролер дуже швидко вмикає і вимикає вихід. Важливий не сам факт вимкнення або увімкнення, а частка часу, протягом якого сигнал перебуває у стані “1”. Ця частка називається duty cycle (скважність).
Наприклад:

Пристрої на кшталт світлодіодів, моторів чи сервоприводів інерційні — вони не реагують на кожен окремий імпульс, а сприймають середній ефект. Тому око бачить плавну зміну яскравості світлодіода, а двигун плавно змінює швидкість.
ШІМ складається з двох ключових параметрів:
- Частота — як швидко повторюються імпульси.
- Скважність (duty cycle) — який відсоток часу сигнал знаходиться у стані “1”.
Змінюючи скважність, ми керуємо “силою” сигналу, а частота визначає, наскільки плавним і безшумним буде результат. Саме на цій простій ідеї побудовано більшість способів керування потужністю в мікроконтролерах.
Типи ШІМ
Хоча принцип ШІМ скрізь однаковий — швидке вмикання й вимикання сигналу — у мікроконтролерах існують різні режими його генерування. Вони відрізняються тим, як таймер рахує час і коли саме формується імпульс. Це важливо для двигунів, підсвіток, сервоприводів та силової електроніки. Ось основні типи PWM, з якими найчастіше працюють:
Fast PWM (швидкий режим) - у цьому режимі таймер рахує від 0 до максимуму й одразу стрибає назад у 0. Імпульси виходять максимально швидко, частота — вища. Такий PWM добре підходить для керування світлодіодами, моторами, загалом — для більшості повсякденних задач. Особливості: максимальна частота, проста логіка роботи, трохи більший “джитер”, ніж у симетричних режимах
Phase Correct PWM (фазово-коректний) - таймер рахує від 0 до максимуму, а потім назад — від максимуму до 0. Це дає симетричну форму сигналу: фронт і спад розташовані рівномірно. Переваги: менше шумів, плавніша робота двигунів, стабільніший імпульс у чутливих схемах. Недоліки: частота вдвічі нижча порівняно з Fast PWM.
Center-Aligned PWM (центрально-симетричний) - це розширена версія phase-correct, характерна для STM32 та інших сучасних MCU. Імпульс "вирівняний" по центру періоду, тому сигнал максимально симетричний. Де використовується: драйвери моторів, інвертори, H-bridge, силова електроніка, де важлива мінімізація електромагнітних завад.
Complementary PWM (комплементарний) - використовується, коли один таймер генерує два протилежні сигнали: коли перший канал увімкнено — другий вимкнений (і навпаки). Застосування: напівмости та повні мости, керування потужними ключами, роботи й дрони (ESC). Часто доповнюється функцією dead-time — затримка між перемиканням каналів, щоб уникнути короткого замикання ключів.
Програмний PWM - формується не апаратно таймером, а кодом у перериваннях. Використовується, коли апаратних каналів не вистачає. Плюси: можна зробити на будь-якому GPIO, повна гнучкість. Мінуси: нижча точність, завантажує процесор, можливі збої при високих частотах.
У більшості випадків розробник використовує Fast PWM або Center-Aligned PWM, але важливо знати й інші режими — вони стають незамінними, коли потрібна тиха робота двигуна, низькі шуми або точний контроль у силових схемах.
Резолюція та частота PWM
Резолюція PWM — це те, наскільки точно ми можемо змінювати скважність сигналу. Вона визначає, на скільки “кроків” можна поділити один період ШІМ. Чим більше цих кроків — тим плавніше регулювання. Наприклад при 8-бітній резолюції маємо 256 рівнів (0…255), при 10-бітній — вже 1024 рівні, а при 12-бітній — 4096 рівнів.
Що це означає на практиці? Якщо ви керуєте LED, то при низькій резолюції перехід між яскравостями буде помітним “сходинками”, а при високій — плавним. У моторах висока резолюція дозволяє точніше контролювати швидкість, а в сервоприводах — положення. Але тут є важливий нюанс: чим вища резолюція, тим нижча максимальна частота PWM. Таймер має рахувати більше значень, а отже — період довший.
Частота PWM — це те, як швидко повторюються імпульси. Вона визначає, як пристрій сприйматиме наш сигнал і наскільки плавно він працюватиме. У різних задачах потрібна різна частота, і неправильний вибір може призвести до мерехтіння, шуму або перегріву. Ось як це працює на практиці:
Світлодіоди дуже швидко реагують на зміни, тому при низькій частоті (наприклад, 100–200 Гц) буде помітне мерехтіння, особливо на камеру. Комфортно — 1…2 кГц, а для повного комфорту — 5 кГц і більше.
Сервоприводи не використовують звичайний PWM по частоті — у них фіксована частота 50 Гц, а керування відбувається шириною імпульсу (1–2 мс). Тому тут частота задана стандартом.
DC-мотори. На низьких частотах двигун може деренчати, свистіти, або працювати нерівно. Оптимально — 20–25 кГц, бо це вище межі чутного діапазону людини.
Аудіо та генерація сигналів. Тут частота PWM повинна бути в рази вищою за частоту аудіо. Зазвичай використовують 30–40 кГц або більше.
Компроміс між частотою та резолюцією
Якщо підвищувати частоту, зменшується резолюція (кількість кроків duty cycle), і навпаки. Це пов’язано з тим, що таймер має обмежену швидкість.
Тому при налаштуванні завжди доводиться обирати: або плавність (висока резолюція), або швидкість (висока частота). Правильно підібрана частота PWM — ключ до стабільної, тихої та ефективної роботи будь-якого пристрою, від LED до електродвигунів.
PWM у мікроконтролерах
Хоч PWM зовні виглядає як проста послідовність імпульсів, усередині мікроконтролера це робота спеціального апаратного блоку — таймера. Саме таймер відповідає за точне відлічування часу та формування сигналу без участі процесора. Розглянемо, що відбувається “під капотом”:
Таймер рахує від 0 до певного максимального значення. У кожного таймера є лічильник — змінна, яка автоматично збільшується з кожним тактом. Коли лічильник доходить до заданої вершини — він обнуляється і починає цикл заново. Цей цикл і є періодом PWM.
Порівняння лічильника з регістром duty cycle. Для кожного PWM-каналу є реєстр, куди ми записуємо значення скважності — наприклад, число від 0 до 255. Всередині MCU відбувається просте правило: коли лічильник < duty, вихід у стані “1”, коли лічильник ≥ duty, вихід у стані “0”. Зміна duty змінює тривалість імпульсу.
Результат формується апаратно. Найголовніше: весь процес працює без участі CPU. Мікроконтролер просто виставляє вихідний пін у потрібний стан на основі порівняння, а процесор може займатися іншими задачами. Тому апаратний PWM: точний, стабільний, не залежить від затримок у програмі і може працювати на високих частотах.
Режими роботи визначають форму сигналу. Залежно від налаштувань таймера ми можемо отримати: Fast PWM — лічильник рахує тільки вперед. Phase Correct / Center-Aligned — рахує вперед і назад. Complementary PWM — генерує два протилежні сигнали. Усе це теж реалізується апаратно.
Prescaler задає швидкість лічильника. Таймери можуть використовувати дільник частоти (1, 2, 8, 64…): більший prescaler → таймер рахує повільніше → нижча частота PWM, менший prescaler → швидше → вища частота PWM. Це дає змогу точно налаштовувати і частоту, і резолюцію.
Порівняння реалізацій PWM у різних мікроконтролерах
Хоч принцип формування PWM скрізь однаковий, різні сімейства мікроконтролерів реалізують його по-своєму. Вони відрізняються кількістю каналів, точністю, можливостями таймерів і додатковими функціями. Нижче — коротке і практичне порівняння найпопулярніших платформ.
AVR (Arduino, ATmega328)
AVR — прості та наочні мікроконтролери, у яких PWM реалізовано дуже базово, але зрозуміло.
Особливості:
-
3 таймери: 8-бітні і 16-бітний
-
кілька режимів: Fast PWM, Phase Correct
-
обмежена кількість каналів (звичайно 6 PWM-виводів)
-
висока частота PWM досягається вже з низькою роздільністю
-
чудово підходять для LED, простих моторів, сервоприводів
Плюси: простота, легкість налаштування
Мінуси: мало каналів, невисока частота та гнучкість
STM32 (Cortex-M0/M3/M4)
STM32 мають одну з найсильніших реалізацій апаратного PWM серед доступних MCU.
Особливості:
-
16-бітні та 32-бітні таймери
-
Center-aligned PWM, complementary виходи
-
підтримка dead-time для драйверів моторів
-
апаратні тригери, синхронізація таймерів між собою
-
дуже високі частоти PWM (десятки та сотні кГц)
-
десятки каналів у залежності від серії
Працюють чудово для:
-
двигунів BLDC
-
інверторів
-
високоточних систем керування
Плюси: гнучкість, потужні таймери
Мінуси: складніше налаштовувати
ESP32
ESP32 має одну з найцікавіших систем PWM — LEDC (LED Controller).
Особливості:
-
до 16 каналів PWM
-
роздільність до 20 біт (!)
-
частоти від кількох Гц до сотень кГц
-
можливість групувати канали у таймери
-
підходить не лише для LED, а й для звуку, моторів
Також є RMT та MCPWM — вони дозволяють створювати складні сигнали та керувати моторними драйверами.
Плюси: багато каналів, висока роздільність
Мінуси: інколи обмеження LEDC призводять до компромісів між частотою та роздільністю
RP2040 (Raspberry Pi Pico)
RP2040 використовує інший підхід: slice-таймери, кожен з яких може створювати по два PWM-виходи.
Особливості:
-
8 slice → 16 PWM-каналів
-
16-бітна роздільність
-
дуже висока частота таймера (125 МГц)
-
можливість одночасної роботи багатьох PWM без навантаження на CPU
-
гнучке налаштування топології каналів
Плюси: багато каналів, прекрасна швидкість
Мінуси: менш гнучкий у режимах, ніж STM32
PIC / dsPIC
У PIC реалізація PWM проста, а в dsPIC — дуже потужна.
PIC:
-
базові PWM для LED і простих моторів
dsPIC:
-
спеціалізовані модулятори для моторів
-
advanced complementary PWM
-
dead-time
-
синхронізація для трьохфазних драйверів
Плюси: ідеально для моторів та силової електроніки
Мінуси: PIC дуже базові, dsPIC — вузька спеціалізація
| MCU | Канали | Роздільність | Частоти | Особливості |
|---|---|---|---|---|
| AVR | 6 | 8–16 біт | до ~30 кГц | просто, базові режими |
| STM32 | десятки | 16–32 біт | до сотень кГц | complementary, dead-time, сильна моторика |
| ESP32 | 16 | до 20 біт | до 300+ кГц | LEDC, RMT, MCPWM |
| RP2040 | 16 | 16 біт | дуже високі | slice-архітектура |
| dsPIC | багато | 15–16 біт | високі | заточений під двигуни |
Керування PWM в коді Arduino
Найпростішим прикладом використання ШІМ є управління яскравістю світлодіодом в Arduino. Фреймворк в даному випадку бере на себе всі необхідні налаштування, нам же залишається мінімум роботи. Наприклад:
void setup() {pinMode(9, OUTPUT); // оголошуємо PWM-пін як вихід}void loop() {analogWrite(9, 128); // встановлюємо 50% скважність (128 з 255)delay(1000);analogWrite(9, 255); // максимальна яскравістьdelay(1000);analogWrite(9, 0); // вимкdelay(1000);}
Важливо обрати правильний пін - він має підтримувати ШІМ і позначені в datasheet мікроконтролера/плати. В прикладі вище світлодіод має бути підключений до 9-го піну.
Якщо треба керувати двигуном, в такому випадку використовується спеціальна плата-драйвер до якої підключається двигун (L298N, L9110S, TB6612FNG тощо). Такі плати зазвичай мають керуючі виводи для напрямку і швидкості обертання. Приклад коду:
void setup() {pinMode(9, OUTPUT); // PWMpinMode(8, OUTPUT); // напрямок}void loop() {digitalWrite(8, HIGH); // вибираємо напрямокanalogWrite(9, 150); // швидкість (0..255)delay(2000);analogWrite(9, 255); // максимумdelay(2000);analogWrite(9, 0); // стопdelay(2000);}
Налаштування і керування сервоприводом дещо складніше, але існують відповідні бібліотеки, які спрощують роботу максимально. Приклад Arduino:
#include <Servo.h>Servo myServo;void setup() {myServo.attach(9); // підключаємо серво до піну 9}void loop() {myServo.write(0); // повернути у 0°delay(1000);myServo.write(90); // повернути у 90°delay(1000);myServo.write(180); // повернути у 180°delay(1000);}
