Таймери Arduino UNO — Частина 3. Режими роботи таймерів (CTC, Fast PWM, Phase Correct PWM)
Теорія
Режим CTC (Clear Timer on Compare Match)
У режимі CTC (скидання таймера за збігом) лічильник таймера рахує до заданого значення в регістрі OCRnA, після чого автоматично скидається в нуль. Це зручно для генерації точних інтервалів часу та сигналів заданої частоти.
Режим Fast PWM
Fast PWM — це режим генерації ШІМ (широтно-імпульсної модуляції), у якому таймер швидко рахує від нуля до максимуму і одразу скидається. Використовується, коли потрібна максимальна частота ШІМ, наприклад, для керування яскравістю світлодіодів або швидкістю двигунів.
Режим Phase Correct PWM
Phase Correct PWM — режим, за якого таймер рахує вгору до максимального значення, а потім назад до нуля. Завдяки цьому форма сигналу симетрична, що зменшує спотворення, але частота вдвічі менша порівняно з Fast PWM.
Регістр TCCRnA і TCCRnB
Режим роботи таймера задається комбінацією бітів у регістрах TCCRnA та TCCRnB:
WGMn0..WGMn2— вибір режиму роботи (Normal, CTC, Fast PWM, Phase Correct PWM).COMnA1, COMnA0— налаштування поведінки виводу OCnA.CSn0..CSn2— вибір передільника (prescaler) — 1, 8, 64, 256, 1024.
Передільники (prescalers)
Передільник ділить частоту тактового генератора (зазвичай 16 МГц для Arduino UNO) для уповільнення рахунку таймера. Наприклад, при передільнику 64 частота таймера буде 16 МГц / 64 = 250 кГц.
Практика
Генерація точного сигналу 1 кГц на піні
void setup() {
pinMode(9, OUTPUT);
// Налаштування Timer1 у режимі CTC
TCCR1A = 0;
TCCR1B = 0;
OCR1A = 7999; // (16 МГц / (2 * 1 кГц)) - 1 при передільнику 1
TCCR1B |= (1 << WGM12); // CTC режим
TCCR1B |= (1 << CS10); // Передільник 1
TCCR1A |= (1 << COM1A0); // Перемикання стану піна OC1A (D9)
}
void loop() {
// Сигнал генерується апаратно
}
Налаштування частоти ШІМ на Timer2
void setup() {
pinMode(3, OUTPUT);
// Налаштування Timer2 у Fast PWM
TCCR2A = 0;
TCCR2B = 0;
TCCR2A |= (1 << WGM21) | (1 << WGM20); // Fast PWM
TCCR2A |= (1 << COM2B1); // Вивід ШІМ на OC2B (D3)
TCCR2B |= (1 << WGM22); // Встановлення TOP через OCR2A
OCR2A = 124; // TOP = 124 → Частота = 16МГц / (64 * (124+1)) ≈ 2 кГц
OCR2B = 62; // 50% скважність
TCCR2B |= (1 << CS22); // Передільник 64
}
void loop() {
}
Проєкт: Генератор квадратного сигналу із заданою частотою
У цьому проєкті ми генеруватимемо сигнал на піні D9 з частотою, яку задає змінна frequency.
int frequency = 2000; // Частота в Гц
void setup() {
pinMode(9, OUTPUT);
// Налаштування Timer1 для CTC
TCCR1A = 0;
TCCR1B = 0;
int prescaler = 8; // Вибір передільника
OCR1A = (16000000 / (2 * prescaler * frequency)) - 1;
TCCR1B |= (1 << WGM12); // CTC
TCCR1B |= (1 << CS11); // Передільник 8
TCCR1A |= (1 << COM1A0); // Перемикання стану на OC1A (D9)
}
void loop() {
// Сигнал генерується апаратно
}
Таким чином, можна легко генерувати стабільні частоти без використання delay() або millis(), що особливо корисно для точних вимірювальних і керуючих систем.




