Таймер в режиме захвата stm32

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

Для чего это надо?
С помощью этого режима можно измерить длительность импульса или период сигнала.

Режим захвата у STM32 обладает некоторыми особенностями:

  • возможность выбрать какой фронт будет активным
  • возможность изменить частоту входного сигнала с помощью предделителя (1,2,4,8)
  • каждый канал захвата оснащён встроенным входным фильтром
  • источником сигнала захвата может служить другой таймер
  • для каждого канала предусмотрено по два флага, первый выставляется если произошёл захват, второй если произошёл захват при установленном первом флаге

Для настройки режима захвата предназначены регистры CCMR1(для 1 и 2 канала) и CCMR2(для 3 и 4), а также регистры CCER, DIER.

Давайте рассмотрим подробнее битовые поля регистра CCMR2, отвечающие за настройку 4 канала таймера, именно его мы будем настраивать в примере. Ещё хотелось бы отметить, что в этом же регистре находятся битовые поля, которые используются при настройке таймера в режиме сравнения.

CC4S — определяет направление работы четвёртого канала(вход или выход). При настройке канала как вход сопоставляет ему сигнал захвата

  • 00 — канал работает как выход
  • 01 — канал работает как вход, сигнал захвата — TI4
  • 10 — канал работает как вход, сигнал захвата — TI3
  • 11 — канал работает как вход, сигнал захвата — TRC

IC4PSC – определяют коэффициент деления, для сигнала захвата

  • 00 — делитель не используется, сигнал захвата IC1PS формируется по каждому событию
  • 01 — сигнал захвата формируется по каждому второму событию
  • 10 — сигнал захвата формируется по каждому четвёртому событию
  • 11 — сигнал захвата формируется по каждому восьмому событию

IC4F — предназначен для настройки входного фильтра, кроме количества выборок, в течение которых микроконтроллер не будет реагировать на входные сигналы, также можно настроить частоту выборок. По сути мы настраиваем время задержки с момента прихода фронта до "подтверждающей" выборки.

Теперь давайте рассмотрим регистр CCER.

CC4E — включает/выключает режим захвата.
CC4P — определяет фронт по которому будет производиться захват, 0 — передний, 1 — задний.

CC4DE — разрешает формировать запрос к DMA.
CC4IE — разрешает прерывание по захвату.

После того как произошёл захват формируется событие захвата, которое устанавливает соответствующий флаг. Это может привести к генерации прерывания и запросу DMA, если они разрешены в регистре DIER. Кроме того, событие захвата может быть сформировано программно, установкой битового поля в регистре генерации событий EGR:

Битовые поля CC1G, CC2G, CC3G и CC4G позволяют генерировать событие в соответствующем канале захвата/сравнения.

Кстати, CCR1, CCR2, CCR3 и CCR4 — регистры захвата, в которых сохраняется значение таймера по сигналу захвата.

Для того чтобы контролировать формирование сигнала захвата, в регистре SR для каждого канала выделено по два флага.

CC4IF — устанавливается когда формируется сигнал захвата, сбрасываются эти флаги программно или чтением соответствующего регистра захвата/сравнения.
CC4OF — устанавливается если флаг CC4IF не был очищен, а пришёл очередной сигнал захвата. Этот флаг очищается программно записью нуля.

Читайте также:  Как завести тесто на пирожки с капустой

Теперь давайте применим полученные знания на практике, с генератора сигналов на вход TIM5_CH4 подадим синусоиду с частотой 50Гц и попробуем измерить её период. Для того чтобы ускорить процесс предлагаю использовать DMA. Какой вывод МК соответствует 4 каналу TIM5 можно найти в даташите на МК в разделе Pinouts and pin description.

Для DMA необходим адрес регистра CCR4, вот как его найти. Открываем RM0008 и в таблице Register boundary addresses находим начальный адрес TIM5.

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

Для чего это надо?
С помощью этого режима можно измерить длительность импульса или период сигнала.

Режим захвата у STM32 обладает некоторыми особенностями:

  • возможность выбрать какой фронт будет активным
  • возможность изменить частоту входного сигнала с помощью предделителя (1,2,4,8)
  • каждый канал захвата оснащён встроенным входным фильтром
  • источником сигнала захвата может служить другой таймер
  • для каждого канала предусмотрено по два флага, первый выставляется если произошёл захват, второй если произошёл захват при установленном первом флаге

Для настройки режима захвата предназначены регистры CCMR1(для 1 и 2 канала) и CCMR2(для 3 и 4), а также регистры CCER, DIER.

Давайте рассмотрим подробнее битовые поля регистра CCMR2, отвечающие за настройку 4 канала таймера, именно его мы будем настраивать в примере. Ещё хотелось бы отметить, что в этом же регистре находятся битовые поля, которые используются при настройке таймера в режиме сравнения.

CC4S — определяет направление работы четвёртого канала(вход или выход). При настройке канала как вход сопоставляет ему сигнал захвата

  • 00 — канал работает как выход
  • 01 — канал работает как вход, сигнал захвата — TI4
  • 10 — канал работает как вход, сигнал захвата — TI3
  • 11 — канал работает как вход, сигнал захвата — TRC

IC4PSC – определяют коэффициент деления, для сигнала захвата

  • 00 — делитель не используется, сигнал захвата IC1PS формируется по каждому событию
  • 01 — сигнал захвата формируется по каждому второму событию
  • 10 — сигнал захвата формируется по каждому четвёртому событию
  • 11 — сигнал захвата формируется по каждому восьмому событию

IC4F — предназначен для настройки входного фильтра, кроме количества выборок, в течение которых микроконтроллер не будет реагировать на входные сигналы, также можно настроить частоту выборок. По сути мы настраиваем время задержки с момента прихода фронта до "подтверждающей" выборки.

Теперь давайте рассмотрим регистр CCER.

CC4E — включает/выключает режим захвата.
CC4P — определяет фронт по которому будет производиться захват, 0 — передний, 1 — задний.

CC4DE — разрешает формировать запрос к DMA.
CC4IE — разрешает прерывание по захвату.

После того как произошёл захват формируется событие захвата, которое устанавливает соответствующий флаг. Это может привести к генерации прерывания и запросу DMA, если они разрешены в регистре DIER. Кроме того, событие захвата может быть сформировано программно, установкой битового поля в регистре генерации событий EGR:

Битовые поля CC1G, CC2G, CC3G и CC4G позволяют генерировать событие в соответствующем канале захвата/сравнения.

Читайте также:  Ремонт в ванной комнате пошаговая инструкция

Кстати, CCR1, CCR2, CCR3 и CCR4 — регистры захвата, в которых сохраняется значение таймера по сигналу захвата.

Для того чтобы контролировать формирование сигнала захвата, в регистре SR для каждого канала выделено по два флага.

CC4IF — устанавливается когда формируется сигнал захвата, сбрасываются эти флаги программно или чтением соответствующего регистра захвата/сравнения.
CC4OF — устанавливается если флаг CC4IF не был очищен, а пришёл очередной сигнал захвата. Этот флаг очищается программно записью нуля.

Теперь давайте применим полученные знания на практике, с генератора сигналов на вход TIM5_CH4 подадим синусоиду с частотой 50Гц и попробуем измерить её период. Для того чтобы ускорить процесс предлагаю использовать DMA. Какой вывод МК соответствует 4 каналу TIM5 можно найти в даташите на МК в разделе Pinouts and pin description.

Для DMA необходим адрес регистра CCR4, вот как его найти. Открываем RM0008 и в таблице Register boundary addresses находим начальный адрес TIM5.

Одной из типичных задач для микроконтроллера является обработка входных сигналов. STM32 с этой задачей довольно ловко справляются с помощью таймера общего назначения. Но, прежде чем перейти к рассмотрению темы захвата сигнала таймером, сначала рассмотрим еще один пример, который является продолжением предыдущей статьи.

Работа с сонаром HC-SR04

Діаграма сигналів HC-SR04:

В работе с сонаром HC-SR04 используется внешнее прерывание. Подробнее с внешними прерываниями познакомимся чуть позже. В этом примере микроконтроллер посылает сонару импульс (Trigger), который запускает измерение. Через некоторое время сонар должен “поднять” сигнал Echo – именно в этот момент начинается отсчет времени. А потом сонар сигнал Echo “опускает”. В этот момент измерения заканчивается. С таймера считывается показатель счетчика и, в зависимости от измеренной длительности обратного импульса Echo, рассчитывается расстояние от сонара до препятствия. Фактически, мы измеряем время между двумя событиями. Мы это уже делали в предыдущей статье.

Диаграмма сигналов HC-SR04:

Схема подключения сонара к тестовой плате STM32F103C8:

Текст программы для работы с сонаром HC-SR04 можете скачать на странице с примерами.

Я не зря привел этот пример, потому что дальше пойдет речь о захвате сигнала таймером. Итак, измерения длины импульса на входе микроконтроллера – это типичная задача и счетчики измерять их в более простой способ, к тому же значительно точнее и без использования внешних прерываний.

Захват сигнала

На ноги контроллера выведены каналы таймеров (Смотри TIMn_CH #).
где,
n – номер таймера
# – номер канала.
Например, TIM2_CH1 – первый канал таймера TIM2.

Каналы таймеров могут работать как входы (для работы с входными сигналами), и как выходы, когда таймеры генерируют выходные сигналы.

Идея захвата сигнала состоит в том, что при изменении состояния входного сигнала таймер сохраняет в специальный регистр текущее значение счетчика и вызывает прерывание. Но это еще не все. Можно настроить делитель, чтобы таймер реагировал только на каждый n-ный импульс. Также можно настроить фильтр. Фильтр используется когда сигнал зашумлённый. Фильтр работает как обратный счетчик. То есть, когда на входе сигнал изменил состояние, таймер отнимает от числа указанного в фильтре единицу и ждет следующей выборки. Проверка сигнала повторяется, пока счетчик не досчитает к нулю, и, если после этого сигнал остался стабильным -викликаеться прерывания. Для наглядности приведу диаграмму. В ней сигнал имеет шумы и нам надо отфильтровать эти шумы. На диаграмме изображена работа таймера без фильтра и с фильтром = 5.

Читайте также:  Деревянный забор с бетонными столбами

Давайте рассмотрим пример разбора PPM сигнала. Если Вы не знаете что такое PPM, это не беда. Это довольно специфическая вещь. Важно понять, что PPM – периодический сигнал с 8-ми посылок различной длины. И нам надо измерить время между каждым из 8-ми импульсов. После 8-ми импульсов идет пауза. По ней мы будем знать, что посылка с 8-ми импульсов закончилась. За ней следует следующая посылка. PPM сигнал выглядит так:

Я приведу код программы, а ниже – объяснение:

Рассмотрим процедуру инициализации таймера TIM2. Сначала идет стандартная инициализация таймера с помощью структуры TIM_TimeBaseInitTypeDef. Нам важно знать, с какой частотой будет работать таймер, поэтому обязательно обращаем внимание на частоту тактирования и делитель (TIM_Prescaler):

А уже потом настраиваем захвата сигнала. Для этого используется структура TIM_ICInitTypeDef. Она имеет следующие параметры:

  • TIM_Channel – номер канала
  • TIM_ICPolarity – определяет активный фронт входного сигнала. Здесь небольшая засада. TIM_ICPolarity_BothEdge, то есть по нарастающему и убыванию фронта в STM32F103C8 не сработает. Или по на нарастающем или по убыванию фронта. В данном случае нас вполне устраивает по фронту. В начале статьи я не зря привел пример с внешними прерываниями. Именно потому, что таймер именно нашего контроллера можно настроить на захват или только фронта или только спада, пришлось искать выход, используя внешние прерывания.
  • TIM_ICSelection – определяет вход
  • TIM_ICPrescaler – делитель входного сигнала
  • TIM_ICFilter – Фильтр (0x0 … 0xF)

Что забыли? .. Конечно! Надо настроить ногу как вход, на которую заведен второй канал второго таймера:

Теперь, по переднему фронту сигнала, таймер будет сохранять показание счетчика в специальный регистр и вызвать прерывание TIM2_IRQHandler, где будет высчитываться время между импульсами и сохраняться в массив PPMBuffer:

И, пока мы будем разбирать и высчитывать наши данные, таймер будет шагать дальше. Даже если наш контроллер был занят и обработает прерывания с задержкой, а за это время таймер уже “пошел дальше”, это не беда. Значение счетчика было отложено в регистр и ожидает обработку. Считывается регистр функцией TIM_GetCapture2(). В отличие от приведенного в начале статьи примеру с внешним прерыванием, этот метод является более точным, так как на вызов прерывания и считывания показаний таймера тратится время. Иногда это бывает довольно критично. К тому же, не всегда обработка прерываний может быть выполнена немедленно.

В случае с сонаром использования захвата сигнала может и не принести заметного эффекта, но при разборе PPM сигнала результаты стали заметно стабильнее.

Оставьте ответ

Ваш адрес email не будет опубликован. Обязательные поля помечены *