Перейти к содержанию

Режим CTC (сброс таймера при совпадении)

Чтобы получить прерывание ровно раз в миллисекунду, счётчик таймера должен считать не до своего максимума, а до заданного значения. Режим CTC делает именно это: при совпадении с регистром сравнения счётчик сбрасывается в ноль и начинает новый период.

Обновлено Редакция GAW

CTC (clear timer on compare match, сброс таймера при совпадении) — режим таймера AVR, в котором счётчик считает от нуля до значения регистра сравнения OCRnA и при совпадении обнуляется. Значение OCRnA становится вершиной счёта TOP и задаёт период точно, с шагом в один такт счётчика. Каждое совпадение ставит флаг OCFnA и может вызвать прерывание (DS40002061B, разд. 15.7.2).

Формулы

Период совпадений при предделителе N (1, 8, 64, 256 или 1024) и тактовой частоте fclk:

T=N⋅(1+OCR)fclkT = \frac{N \cdot (1 + OCR)}{f_{clk}}

Если выход OCnA переключается при каждом совпадении (COMnA1:0 = 01), на выводе получается меандр:

f=fclk2⋅N⋅(1+OCR)f = \frac{f_{clk}}{2 \cdot N \cdot (1 + OCR)}

Наибольшая частота — fclk / 2 при OCR = 0 и N = 1. Обозначения те же, что в статье о таймерах AVR и в калькуляторе таймера; N — предделитель.

Режимы CTC у ATmega328P

ТаймерWGMВершина TOP
Timer0 (8 бит)2OCR0A
Timer1 (16 бит)4OCR1A
Timer1 (16 бит)12ICR1
Timer2 (8 бит)2OCR2A

Вершину у Timer1 можно задать регистром ICR1 — тогда оба регистра сравнения OCR1A и OCR1B свободны для своих событий внутри периода (разд. 16.9.2).

Что учесть

  • Нет буферизации OCRnA. Новое значение меньше текущего счётчика пропускает совпадение, и счётчик идёт до максимума и через ноль. Менять вершину лучше в обработчике совпадения.
  • TOV в CTC. Флаг переполнения TOV0 ставится только при переходе от максимума 0xFF к нулю (разд. 15.7.2). Наш вывод: если OCR0A меньше 0xFF, в обычной работе CTC он не ставится, и период дают флаги совпадения.
  • У STM32 отдельного режима нет: при счёте вверх счётчик и так считает до ARR и обнуляется (у таймеров STM32 есть ещё счёт вниз и по центру, RM0090, разд. 17.3.2), а переключение вывода даёт output compare в режиме toggle.

Задержки на основе таймера и циклов считает калькулятор задержек AVR.

Частые вопросы

Как получить прерывание раз в 1 мс на ATmega328P при 16 МГц?

Timer1 в режиме CTC с вершиной OCR1A, предделитель N = 8: OCR1A = 16 000 000 / (8 · 1000) − 1 = 1999 (наш расчёт). Счётчик 2000 раз за миллисекунду проходит 0…1999, и при каждом совпадении ставится флаг OCF1A — его прерывание и вызывается раз в 1 мс. Тот же расчёт для Timer0 и других частот делает калькулятор таймера.

Почему после изменения OCR0A прерывание пропало на целый период?

В режиме CTC у регистра OCR0A нет двойной буферизации. Если записать значение меньше текущего TCNT0, совпадение будет пропущено, и счётчик дойдёт до 0xFF, перевалит через ноль и только потом совпадёт (DS40002061B, разд. 15.7.2). Новое значение безопаснее писать сразу после совпадения, в обработчике его прерывания.

Есть ли режим CTC у STM32?

Отдельного режима нет, потому что у таймеров STM32 счётчик всегда считает до значения ARR и обнуляется — это и есть поведение CTC. Аналог переключения вывода в CTC у STM32 — режим output compare с переключением (toggle) при совпадении.

Источники

  1. Microchip. ATmega48A/PA/88A/PA/168A/PA/328/P Data Sheet, DS40002061B — разд. 15.7.2 — CTC (WGM02:0 = 2): счётчик TCNT0 обнуляется при совпадении с OCR0A, OCR0A задаёт вершину счёта; прерывание по флагу OCF0A при достижении TOP; двойной буферизации нет: если записать OCR0A меньше текущего TCNT0, совпадение пропустится и счётчик дойдёт до 0xFF; переключение OC0A при каждом совпадении (COM0A1:0 = 1), максимум f_clk/2 при OCR0A = 0, f = f_clk / (2 · N · (1 + OCR0A)), N = 1, 8, 64, 256, 1024; флаг TOV0 ставится при переходе MAX → 0x00; разд. 16.9.2 — у Timer1 вершину CTC задаёт OCR1A (режим 4) или ICR1 (режим 12); 18.7.2 — у Timer2 CTC при WGM22:0 = 2 с вершиной OCR2A
  2. STMicroelectronics. RM0090 Reference manual: STM32F405/415, STM32F407/417, STM32F427/437 and STM32F429/439, Rev 21 — разд. 17.3.2 — счёт вверх от 0 до ARR с переполнением: у STM32 вершину счёта всегда задаёт ARR, отдельного режима CTC нет (для сравнения)

Нашли ошибку?