Top.Mail.Ru

Stm32. Переходим на современный C++. Часть 6. Таймеры общего назначения и модуль сравнения.

Вступление.

Прошу прощения, если кого-то расстроил столь долгим перерывом, но конец года постоянно не оставляет ни минуты свободного времени.

Ранее мы начали изучение таймеров в контроллерах Stm32 и рассмотрели базовый таймер, функционал которого ограничен увеличением счетчика (регистра CNT) и генерацией события (на которое можно "повесить" прерывание и DMA-запрос) при его переполнении. Переходим к следующему в иерархии виду таймеров - таймерам общего назначения (general-purpose).

Таймеры общего назначения в Stm32.

В контроллерах, как правило, представлено несколько таймеров общего назначения, которые, в свою очередь, согласно Reference Manual можно разбить на несколько групп с незначительными отличиями, к которым относятся:

  • разрядность счетчика (некоторые таймеры общего назначения могут быть 32-битными, например, "таймер 2" для контроллеров Stm32f0x);
  • направление счета (некоторые считают только вверх, некоторые позволяют вести счет вниз или вверх/вниз);
  • количество каналов захвата/сравнения (два или четыре);
  • поддержка внешнего триггера/сигнала тактирования (некоторые таймеры имеют, некоторые нет).

Конкретные возможности того или иного таймера можно найти в Reference Manual, мы же рассмотрим полный список возможностей таймеров общего назначения. К основным возможностям, согласно RM, можно отнести следующее:

  • 16/32-битный счетчик с автоперезагрузкой (прямого, обратного, прямого/обратного счета);
  • 16-битный программируемый предделитель, используемый для деления входного тактирующего сигнала на любое значение в промежутке 1 ... 65536;
  • до 4 независимых каналов для
    • захвата;
    • сравнения;
    • генерации ШИМ;
    • выхода в режиме one-pulse.
  • схема синхронизации с внешними сигналами и другими таймерами;
  • генерация прерывания/DMA-запроса для следующих событий:
    • обновление счетчика (переполнение вверх/вниз, сброс таймера (программный или по триггеру);
    • событие триггера (начало/остановка счета);
    • событие захвата;
    • событие сравнения;
  • поддержка инкрементного (квадратурного) энкодера и датчика Холла;
  • вход триггера для внешнего тактирования;

На рисунке ниже представлена диаграмма блока базового таймера, где красным цветом выделена часть, общая с рассмотренным ранее базовым таймером:

Несложно увидеть, что непосредственно счет (он же целиком базовый таймер) - это лишь малая часть полного модуля таймера, поэтому последовательно разберем составные части таймеров общего назначения.

Линия Internal clock (CK_INT).

CK_INT - внутренний тактирующий сигнал от шины, используется для "обычного" тактирования таймера от системной шины.

Вход TIMx_ETR.

TIMx_ETR - вход для внешнего сигнала, который можно использовать как триггер или тактовый сигнал. Сигнал с этого входа проходит через два промежуточных модуля:

  • Polarity selection & edge detector & prescaler выполняет следующие функции:
    • выбор полярности: вход ETR может быть неинвертированным, в этом случае активным считается высокий уровень или восходящий фронт, либо инвертированным, при котором активным считается низкий уровень или нисходящий фронт. Настройка задается битом ETP регистра TIMx_SMCR;
    • детектор фронтов;
    • настраиваемый предделитель: выходной сигнал модуля может иметь частоту не более 1/4 частоты CK_INT, поэтому в случае высокочастотного входного сигнала может быть полезным его деление. Доступно деление на 1, 2, 4, 8, настройка задается битами ETPS регистра TIMx_SMCR.
  • Input filter является цифровым фильтром для сигнала ETRP, его настройка задается битами ETF регистра TIMx_SMCR, конкретное описание значений можно найти в Reference Manual.

Входы ITR0 ... ITR4.

Каждый вход ITRx является внутренней линией к другому таймеру (мастер-таймеру), конкретное их перечисление указано также в RM. Например, для таймера 2 контроллера Stm32f103, ITR0 ... ITR1 подключены соответственно к таймерам 1, 8, 3, 4. Мультиплексор позволяет выбрать одну из четырех линий в качестве выходной, что задается двумя младшими битами TS регистра TIMx_SMCR.

Входы TI1FP1 и TI2FP2.

Эти линии являются выходами детектора фронтов первого канала, поэтому будут описаны ниже.

Trigger controller.

Перечисленные выше линии после цепочек деления частоты, фильтрации и мультиплексирования в итоге попадают в модуль Trigger controller, который имеет два выхода:

  • TRGO: выход для синхронизации с другими таймерами (те самые линии ITRx) и запуска ЦАП/АЦП. Выход активируется битом MSM регистра TIMx_SMCR;
  • Reset, enable, up, count - линия (точнее несколько) управления счетом таймера, где:
    • reset - сброс счетчика;
    • enable - активация (запуск) таймера;
    • up - направление счета;
    • count - сигнал счета (изменения счетчика на единицу вверх/вниз).

Данный выход настраивается с помощью битов SMS регистра TIMx_SMCR и может иметь следующие значения:

  • 000 (Slave mode disabled) : slave-режим отключен, таймер тактируется от линии CK_INT;
  • 001 (Encoder mode 1): режим энкодера 1, счетчик изменяется по фронту TI2FP1 на единицу вверх/вниз в зависимости от состояния TI1FP2;
  • 010 (Encoder mode 2): режим энкодера 2, счетчик изменяется по фронту TI1FP2 на единицу вверх/вниз в зависимости от состояния TI2FP1;
  • 011 (Encoder mode 3): режим энкодера 3, счетчик изменяется по фронтам TI1FP1 и TI2FP2 на единицу вверх/вниз в зависимости от их состояния;
  • 100 (Reset Mode): режим сброса, выбранный триггер сбрасывает счетчик;
  • 101 (Gated Mode): режима шлюза, счетчик включен только при высоком уровне сигнала триггера. При переходе его в низкий уровень счет останавливается, но счетчик не сбрасывается. При переходе триггерного сигнала обратно в высокий уровень счет возобновляется;
  • 110 (Trigger Mode): режим триггера