Режим 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:
Если выход OCnA переключается при каждом совпадении (COMnA1:0 = 01), на выводе получается меандр:
Наибольшая частота — fclk / 2 при OCR = 0 и N = 1. Обозначения те же, что в статье о таймерах AVR и в калькуляторе таймера; N — предделитель.
Режимы CTC у ATmega328P
| Таймер | WGM | Вершина TOP |
|---|---|---|
| Timer0 (8 бит) | 2 | OCR0A |
| Timer1 (16 бит) | 4 | OCR1A |
| Timer1 (16 бит) | 12 | ICR1 |
| Timer2 (8 бит) | 2 | OCR2A |
Вершину у 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) при совпадении.
Источники
- 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
- STMicroelectronics. RM0090 Reference manual: STM32F405/415, STM32F407/417, STM32F427/437 and STM32F429/439, Rev 21 — разд. 17.3.2 — счёт вверх от 0 до ARR с переполнением: у STM32 вершину счёта всегда задаёт ARR, отдельного режима CTC нет (для сравнения)
Нашли ошибку?
Смотрите также
- Таймеры AVRTimer0/1/2, режимы WGM, предделители, формулы ШИМ, захват, примеры
- Таймер AVR и STM32Предделитель, OCRnA, PSC и ARR под частоту, мёртвое время, энкодер
- Предделитель таймераPrescaler: делитель тактов перед счётчиком таймера
- Output compare (сравнение)Действие на выводе и флаг при совпадении счётчика с регистром
- Задержки AVR: _delay_msТакты и фактическое время _delay_ms, _delay_us, циклов; пределы и округление