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

Калькулятор таймера AVR и STM32

Задайте тактовую частоту и нужную частоту прерываний или ШИМ — калькулятор подберёт предделитель и значение регистра периода для таймеров ATmega328P и STM32, покажет фактическую частоту, ошибку и код настройки.

Исходные данные

Микроконтроллер

16 МГц, 8 МГц, 1 МГц

Что задано

1 кГц, 38 кГц, 50 Гц

Результат

Предделитель и OCRnA
1 и 15999
CS = 001, режим CTC
Фактическая частота
1 кГцпериод 1 мс
Ошибка
0 %
Разрешение ШИМ
14 бит16000 шагов
Меандр на выводе OCnA
500 Гцпри переключении вывода в режиме CTC

Другие варианты:

  • N = 8, OCRnA = 1999 → 1 кГц (0 %)
  • N = 64, OCRnA = 249 → 1 кГц (0 %)
  • N = 256, OCRnA = 62 → 992,063 Гц (−0,794 %)
TCCR1A = 0;
TCCR1B = (1 << WGM12) | (1 << CS10);  // CTC, clk/1
OCR1A = 15999;
TIMSK1 = (1 << OCIE1A);         // ISR(TIMER1_COMPA_vect)

Аппаратный таймер отсчитывает такты, поделённые предделителем, и формирует событие — прерывание или период ШИМ — каждые TOP + 1 отсчётов. Задача сводится к тому, чтобы подобрать предделитель и значение регистра периода так, чтобы частота событий была как можно ближе к нужной.

Формулы

Для ATmega328P в режиме CTC (сброс по совпадению) и в Fast PWM с регистром периода:

f=fclkN⋅(1+TOP),fOCnA=fclk2 N (1+OCRnA),f = \frac{f_{clk}}{N \cdot (1 + TOP)}, \qquad f_{OCnA} = \frac{f_{clk}}{2 \, N \, (1 + OCRnA)},

где N — предделитель, TOP — значение OCRnA (или ICR1 у Timer1), fOCnA — частота меандра на выводе OCnA, когда вывод переключается при каждом совпадении. У Timer0 и Timer1 предделители 1, 8, 64, 256 и 1024, у Timer2 добавлены 32 и 128.

Для таймера STM32 событие обновления происходит каждые (PSC + 1) · (ARR + 1) тактов:

f=fTIM(PSC+1)⋅(ARR+1).f = \frac{f_{TIM}}{(PSC + 1) \cdot (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, и период задаётся точно, с шагом в один такт после предделителя.

Источники

  1. Microchip. ATmega48A/PA/88A/PA/168A/PA/328/P Data Sheet (DS40002061B) — Timer/Counter0, 1 и 2: режим CTC, частота на выводе OCnA, Fast PWM, коды предделителя CSn2:0
  2. STMicroelectronics. RM0008 Reference manual STM32F101xx–STM32F107xx — предделитель PSC и регистр ARR таймеров, частота тактирования таймеров от шины APB

Обновлено . Нашли ошибку в расчёте? Напишите нам.