Аппаратный таймер отсчитывает такты, поделённые предделителем, и формирует событие — прерывание или период ШИМ — каждые TOP + 1 отсчётов. Задача сводится к тому, чтобы подобрать предделитель и значение регистра периода так, чтобы частота событий была как можно ближе к нужной.
Формулы
Для ATmega328P в режиме CTC (сброс по совпадению) и в Fast PWM с регистром периода:
где N — предделитель, TOP — значение OCRnA (или ICR1 у Timer1), fOCnA — частота меандра на выводе OCnA, когда вывод переключается при каждом совпадении. У Timer0 и Timer1 предделители 1, 8, 64, 256 и 1024, у Timer2 добавлены 32 и 128.
Для таймера STM32 событие обновления происходит каждые (PSC + 1) · (ARR + 1) тактов:
PSC и ARR 16-битные; у TIM2 и TIM5 во многих семействах ARR 32-битный.
Как выбирается предделитель
Калькулятор перебирает предделители и для каждого находит ближайшее значение регистра периода. Из вариантов с наименьшей ошибкой выбирается тот, где предделитель меньше: регистр периода тогда больше, а значит, у ШИМ больше шагов скважности. Остальные варианты показаны списком — иногда удобнее «круглый» отсчёт, например 1 МГц.
Пример: несущая 38 кГц для ИК-передатчика на выводе OC2A ATmega328P при 16 МГц. Меандр на выводе вдвое медленнее событий, поэтому нужна частота событий 76 кГц: предделитель 1, OCR2A = 210, на выводе получится 37 915 Гц — на 0,22 % ниже 38 кГц, что приёмники ИК-сигналов допускают.
Тактирование таймеров STM32
Частоту fTIM берите из настройки тактирования, а не из частоты ядра. Если делитель шины APB, к которой подключён таймер, больше 1, таймеры этой шины тактируются удвоенной частотой шины. У STM32F103 на 72 МГц шина APB1 работает на 36 МГц, а TIM2–TIM4 — на 72 МГц.
Пример для ATmega328P
#include <avr/io.h>
#include <avr/interrupt.h>
volatile uint32_t ms_ticks;
ISR(TIMER1_COMPA_vect)
{
ms_ticks++; /* called every 1 ms */
}
int main(void)
{
TCCR1A = 0;
TCCR1B = (1 << WGM12) | (1 << CS11); /* CTC, clk/8 */
OCR1A = 1999; /* 16 MHz / 8 / 2000 = 1 kHz */
TIMSK1 = (1 << OCIE1A);
sei();
for (;;) {
}
}
Типичные ошибки
- Забыли глобально разрешить прерывания (
sei()): таймер считает, флаг совпадения ставится, но обработчик не вызывается. - Заняли таймер Arduino. Timer0 используют millis() и delay(), Timer1 — библиотека Servo, Timer2 — tone(). Перенастройка ломает эти функции.
- Не тот режим. В обычном режиме (Normal) счётчик досчитывает до максимума, и OCRnA задаёт только момент совпадения, а не период.
- Неверная частота таймера STM32 из-за удвоения на шине APB — частота получается вдвое выше или ниже ожидаемой.
- Ошибка частоты из-за кварца. Расчёт точен настолько, насколько точна тактовая частота; на внутреннем RC-генераторе ошибка доходит до процентов. Подбор конденсаторов для кварца — в калькуляторе конденсаторов для кварца, скорость UART — в калькуляторе скорости UART.
Частые вопросы
Как настроить прерывание таймера раз в 1 мс на ATmega328P при 16 МГц?
Timer1 в режиме CTC: предделитель 1 и OCR1A = 15999 или предделитель 8 и OCR1A = 1999 — оба варианта дают ровно 1 кГц. Для 8-битного Timer0 подходит предделитель 64 и OCR0A = 249. Учтите, что в Arduino Timer0 занят функциями millis() и delay().
Как рассчитать PSC и ARR для STM32?
Частота события f = fTIM / ((PSC + 1) · (ARR + 1)), где fTIM — частота тактирования таймера. Для 1 кГц при 72 МГц произведение (PSC + 1) · (ARR + 1) должно быть 72 000: например, PSC = 71 и ARR = 999 (счёт идёт с частотой 1 МГц) или PSC = 1 и ARR = 35 999 — так у ШИМ больше шагов.
Почему частота таймера STM32 вдвое больше частоты шины APB?
Так устроено тактирование: если делитель шины APB больше 1, таймеры на этой шине получают удвоенную частоту. Например, у STM32F103 на 72 МГц шина APB1 работает на 36 МГц, а таймеры TIM2–TIM4 тактируются от 72 МГц.
Чем режим CTC отличается от переполнения таймера?
При переполнении счётчик всегда досчитывает до максимума — 255 или 65 535, — и частота выбирается только предделителем. В CTC счётчик сбрасывается при совпадении с OCRnA, и период задаётся точно, с шагом в один такт после предделителя.
Источники
- Microchip. ATmega48A/PA/88A/PA/168A/PA/328/P Data Sheet (DS40002061B) — Timer/Counter0, 1 и 2: режим CTC, частота на выводе OCnA, Fast PWM, коды предделителя CSn2:0
- STMicroelectronics. RM0008 Reference manual STM32F101xx–STM32F107xx — предделитель PSC и регистр ARR таймеров, частота тактирования таймеров от шины APB
Обновлено . Нашли ошибку в расчёте? Напишите нам.