output compare что это

output compare что это. Смотреть фото output compare что это. Смотреть картинку output compare что это. Картинка про output compare что это. Фото output compare что это Продолжаем тему таймеров в STM32. В прошлый раз мы рассмотрели базовые таймеры, которые довольно-таки просты. Но сегодня мы поиграемся с более крутой игрушкой — таймерами общего назначения, которые на голову выше предыдущих.

Вот как вы думаете, если у таймеров общего назначения так много функций, чем тогда продвинутые (advanced-control) таймеры отличаются от них? o_O
Правильный ответ — почти ничем, это по факту просто таймеры общего назначения, которые не имеют никаких ограничений: в них напихано по 4 канала (с комплементарными) и есть все возможности сразу, без какого-то ни было разброса. Так что остальная часть статьи будет относиться ко всем таймерам выше базовых, а продвинутые таймеры я отдельно упоминать не буду.

В даташите на STM32F100xx ( ещё ссылка ) есть сводная таблица возможностей таймеров, в которую тоже удобно поглядывать для справки:

output compare что это. Смотреть фото output compare что это. Смотреть картинку output compare что это. Картинка про output compare что это. Фото output compare что это

Кстати, обращайте внимание на сноски. Например, там написано, что у МК семейства Low density Value line нет таймера TIM4.

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

В этом режиме с выбранного канала захватываются импульсы, на каждый из них текущее значение счётчика таймера кладётся в регистр TIM_CCRx, где x — номер канала. Таким образом, период следования импульсов равен разнице между текущим значением TIM_CCRx и предыдущим. Ну а для того, чтобы получить период в каких-то внятных единицах измерения, нужно настроить предделитель через функции базового таймера.

При этом можно настроить генерацию прерывания и запроса DMA на приход очередного импульса, и если в это время предыдущее значение TIM_CCRx не было считано, будет сгенерировано так называемое прерывание over-capture, т.е. сигнал о том, что предыдущее значение потерялось.

Ловить можно фронты, спады или и то, и другое вместе. Есть настройка так называемого фильтра — числа выборок, после которого переход уровня будет считаться состоявшимся (полезно для устранения дребезга). Значение фильтра может принимать значения от 0 (фильтр выключен) до 15 (0xF). Также настраивается делитель входной частоты — 2, 4 или 8: будет ловиться каждый 2й, 4й или 8й импульс соответственно.

Примера ради подёргаем вывод PB15 и замерим таймером TIM3 период, подключив PB15 к его каналу 1 (PA6):

Также существует режим захвата ШИМ. На самом деле, это не отдельный режим, а просто особое сочетание настроек с таким эффектом. Таймер настраивается так, чтобы один канал ловил фронты и сбрасывал счётчик таймера, а второй ловил спады — тогда первый будет захватывать период ШИМ, а второй — заполнение. При этом оба канала подключаются к одному и тому же физическому входу. Суть работы этого «режима» показана в даташите следующим образом:

output compare что это. Смотреть фото output compare что это. Смотреть картинку output compare что это. Картинка про output compare что это. Фото output compare что это

Изменим предыдущий пример, используя захват ШИМ (прокомментированы только изменения):

Режим чтения энкодера

Так как мне захотелось ещё и прерывание заиметь, я сделал период равным 4 и разрешил счёт в обе стороны, так что теперь прерывание будет возникать при каждом щелчке энкодера. Использовал я каналы 1 и 2 таймера TIM3 (PA6 и PA7):

Сравнение вывода (output compare)

В этом режиме выбранный канал таймера будет подключен к соответствующему выводу и будет изменять его (вывода) состояние каждый раз, когда счётчик таймера досчитает до значения регистра TIM_CCRx. Состояние вывода, в зависимости от настройки, будет меняться на ноль, на единицу или на противоположное текущему. У многих таймеров у каналов есть комплементарные выводы, которые по умолчанию являются инверсными: на такой выход подаётся тот же сигнал, что и на обычный, но с противоположным уровнем.

Смотрим в сводную таблицу по таймерам в даташите и видим, что комплементарных выводов у TIM3 нет, но вот у единственного канала таймера TIM16 есть такой вывод — этот таймер я и использую для примера. Вообще, комплементарные выводы есть и у нескольких других таймеров, но вот TIM15 — особенный: у него есть два канала, но комплементарный вывод имеет только 1й канал. Будьте бдительны!

В таблице пинаутов находим выводы канала 1 таймера TIM16 — PB8 (основной) и PB6 (комплементарный). Для иллюстрации работы таймера подключим эти выводы к светодиодам на плате STM32VLDiscovery — PC8 и PC9, которые в коде мы отключим от греха подальше. Таким образом, выводы канала таймера будут напрямую мигать светодиодами:

В это примере я выбрал режим переключения вывода в противоположное состояние (TIM_OCMode_Toggle), а остальные настройки оставил по умолчанию. Кстати, не забывайте вызывать функции типа TIM_OCStructInit() для инициализации соответствующих структур, даже если заполняете все поля структур вручную: copy&paste-ориентированное программирование никто не отменял, но при нём легко забыть заполнить какое-нибудь поле и ловить потом баги.

Для обоих выводов канала можно настроить (поля TIM_OCPolarity и TIM_OCNPolarity структуры) так называемую «полярность» — состояние вывода в промежуток времени от начала отсчёта и до TIM_Pulse. По умолчанию для выводов выставляются значения TIM_OCPolarity_High и TIM_OCNPolarity_High, но комплементарный вывод является инверсным — поэтому, если на нём нужен обычный (не инверсный) сигнал, нужно ему выставить TIM_OCNPolarity_Low.

В режиме сравнения генерируется то же самое прерывание, что и в режиме захвата сигнала — TIM_IT_CCx, но здесь оно было не нужно, поэтому я его не разрешал.

Генерация ШИМ

Настройка этого режима не слишком отличается от настройки output compare: вместо режима TIM_OCMode_Toggle нужно выбрать один из режимов ШИМ, тогда TIM_Period будет трактоваться как период ШИМ, а поле TIM_Pulse — как заполнение (duty cycle). Режимов ШИМ имеется два — выровненный по границе и по центру (edge-aligned и center-aligned). У микроконтроллеров AVR они называются Fast PWM и Phase Correct PWM, соответственно.

Отличной иллюстрацией крутизны таймеров STM32 для генерации ШИМ будет типичная прикладная задача — управление сервомашинкой : Как известно, сервы управляются импульсами переменной ширины, которые шлются с частотой примерно 50 Гц (каждые 20 мс). У сервы, которая оказалась под рукой (Robbe 4.3 g), ширина управляющего импульса от 500 мкс (0°) до 2250 мкс (175°), судя по замерам — то есть, по 10 мкс на каждый градус поворота:

ΔT = T₂ — T₁ = 2250 — 500 = 1750 мкс
∠A = 175°
ΔT/A = 10 мкс/°

Dead-time

Если кто не знает, это задержка фронтов сигналов на основном и комплементарном выводах канала таймера. Эта функция есть у некоторых таймеров (смотрите руководство), и нужна она бывает для исключения сквозных токов при управлении силовыми ключами [полу]мостовых схем. Даже не спрашивайте меня, что это такое — это вне моей компетенции.

Настраивается этот самый dead-time в поле TIM_DeadTime структуры TIM_BDTRInitTypeDef и имеет диапазон значений с 0 по 255 (0xFF). Но смысл этого числа не так уж прямолинеен:

output compare что это. Смотреть фото output compare что это. Смотреть картинку output compare что это. Картинка про output compare что это. Фото output compare что это

Ага, вот так оно и рассчитывается. Здесь Tdts — это длительность такта генератора dead-time (DTG), зависящая от Tdts — текущей частоты тактирования таймера. Обычно таймеры тактируются системной частотой, и TIM_Prescaler на это никак не влияет, а влияет поле TIM_ClockDivision структуры TIM_TimeBaseInitTypeDef — делитель частоты таймера.

Для примера положим, что таймер затактирован без деления частоты (делитель равен 1, TIM_CKD_DIV1), системная частота F равна 24 МГц, а значение DTG = 150. Тогда:

Tdts = 1/F = 1/24 мкс
DTG = 150 = 100101102 ⇒ DTG[7:5] = 1002
Tdtg = 2⋅Tdts = 1/12 мкс
DT = (64 + DTG[5:0])Tdtg = (64 + 6)/12 = 5.8(3) мкс

«Just like that» ☯ ChosunNinja

Я тут для примера набросал код с dead-time попроще для расчёта: DTG=96 ⇒ DT=96.

Для того, чтобы узреть этот самый dead-time на одноканальном осциллографе, нужно подключить PB8 и PB6 через резисторы 1 кОм к его щупу:

output compare что это. Смотреть фото output compare что это. Смотреть картинку output compare что это. Картинка про output compare что это. Фото output compare что это

Т.к. на эти выводы идут взаимно инверсные сигналы, на экране будут прекрасно видны места, где во время dead-time уровень на обоих входах одинаков из-за задержки фронтов:

output compare что это. Смотреть фото output compare что это. Смотреть картинку output compare что это. Картинка про output compare что это. Фото output compare что это

Ну, и напоследок — имейте ввиду, что если длительность dead-time превышает длительность импульса на выводе, то соответствующий импульс не будет сгенерирован вообще.

Счётчик повторений

Этот счётчик имеется у нескольких таймеров (TIM15, TIM16 и TIM17) и выполняет он очень простую функцию: генерировать событие (прерывание или запрос DMA) update не на каждое переполнение счётчика, а на каждые N переполнений. То есть, вы задаёте счётчик повторений, таймер его копирует в скрытый регистр и при каждом переполнении уменьшает значение копии на 1. Когда значение достигает нуля, генерируется событие update, таймер снова копирует счётчик повторений и т.д. На самом деле, перечисленные таймеры и так задействуют этот счётчик, просто по умолчанию его значение равно нулю, и событие генерируется на каждое переполнение.

Счётчик может принимать значения от 0 до 255 (0xFF). Описывать тут особо нечего, потому что для использования этой функции достаточно при инициализации таймера написать что-то вроде:

и всё. В этом случае событие update будет генерироваться каждые 8 переполнений (7 повторений).

Вход BRK

Если вам вдруг понадобится резко перевести выводы каналов таймера в заранее определённое состояние (например, выключить), то эта функция — то, что нужно. Включить её проще пареной репы — нужно сконфигурировать пин TIMx_BKIN на вход, и при инициализации BDTR включить вход BRK:

По умолчанию для активации функции break нужно на вход BRK подать логический ноль, но это можно настроить в поле TIM_BreakPolarity. Как только break активирован, все выводы каналов переходят в состояние, которое задаётся при их инициализации полями TIM_OCIdleState и TIM_OCNIdleState в структуре TIM_OCInitTypeDef (по умолчанию на выводах будет низкий уровень). Dead-time при этом учитывается.

Синхронизация таймеров

Таймеры можно соединять друг с другом для синхронизации или образования цепочек таймеров. В первом случае появляется возможность синхронного старта нескольких таймеров по внешнему триггеру, а во втором — возможность одному таймеру управлять счётчиком другого — запускать, разрешать, сбрасывать.

Второй случай (цепочка таймеров) больше подойдёт для иллюстрации, ибо интереснее он. Сделаем-ка для примера 32-битный таймер из двух обычных 16-битных. Для примера я возьму таймеры TIM2 и TIM3. Задача состоит в том, таймер TIM3 тактировал таймер TIM2 по переполнению своего счётчика: то есть, счётчик таймера TIM2 будет увеличиваться при переполнении счётчика TIM3 — получаем 32-битный счётчик, «состоящий» из TIM2_CNT (старшие биты) и TIM3_CNT (младшие).

Для этого нужно настроить выходной триггер таймера TIM3 на переполнение (update), а входной триггер таймера TIM2 — на вход с триггера TIM3. Смотрим в таблицу соединения триггеров для таймеров TIM2-TIM4 (таких таблиц несколько — для разных групп таймеров):

output compare что это. Смотреть фото output compare что это. Смотреть картинку output compare что это. Картинка про output compare что это. Фото output compare что это

Здесь мы видим, что TIM3 соединён с входом ITR2 таймера TIM2. И тут выясняется, что в Reference manual рассматриваемый случай описан в разделе «Using one timer as prescaler for another», но там допущена ошибка: вместо ITR2 там указан ITR1. Я джва года час искал ошибку в коде!

Источник

STM32. TIMx OUTPUT COMPARE MODE.

В своей прошлой статье я как-то не полностью раскрыл вопросы по использованию таймера. Теперь восполняю этот пробел. Дело в том, что при обилии информации по STM32, конкретных примеров использования таймера в указанном режиме я не встретил в сети. Были подобные статьи, однако описано всё как-то слишком общими фразами.
В своём макете генератора меандра я использовал таймер 2, но это не суть важно, просто пояснять материал я буду именно на нём, и это ни с чем не сязано, просто так легли карты. �?так, управление таймером (да и всем контроллером) заключается в записи в управляющие регистры определённых значений, и контроль определённых разрядов (флагов) в тех же регистрах, если это необходимо. Так вот для правильного управления просто необходимо знать назначение каждого разряда каждого регистра и иметь перед глазами структурную схему таймера.
Сводная таблица регистров таймеров 2-5 микроконтроллера STM32F100xx представлена в документе под названием «RM0041 Reference manual», в Table 73. «TIMx register map and reset values», а структурная схема — Figure 88 на стр.276 того же документа. Я для себя распечатал описание всех регистров контроллера, структурные схемы узлов и сшил листы в виде этакой книжицы.Рассмотрим, что же делает код, представленный в прошлой статье:

AFIO->MAPR = 0x02000300;
output compare что это. Смотреть фото output compare что это. Смотреть картинку output compare что это. Картинка про output compare что это. Фото output compare что это

Группе бит 26-24, которые управляют JTAG/SWD — интерфейсами, установили значение = 010: (JTAG-DP Disabled and SW-DP Enabled), т.е отключили JTAG при включенном SWD. Группе бит 9-8, которые ремапят таймер 2 установили значение = 11: Full remap (CH1/ETR/PA15, CH2/PB3, CH3/PB10, CH4/PB11), т.е выход его канала CH1 подключили на PA15. Я долго не мог понять, почему же при правильных настройках таймера на его выходе CH1 (PA15) я тупо наблюдаю лог. «1». Переключался на CH2 (PB3), а там вообще какая-то постоянная байтовая посылка! �? именно эта байтовая посылка толкнула меня посмотреть ещё раз на распиновку контроллера. Естественно, я увидел там, что по умолчанию PA15 — это вход JTDI (вот почему там лог. «1»), а PB3 — это выход JTDO (вот откуда байтовая посылка). Надеюсь действия с битами 26-24 (SWJ_CFG) теперь не требуют пояснения

GPIOA->CRH = 0xB0000000;
output compare что это. Смотреть фото output compare что это. Смотреть картинку output compare что это. Картинка про output compare что это. Фото output compare что это
Ну, этот регистр разжёван во многих статьях. Вывод PA15 настраиваем как выход MODE15[1:0] = 11: Output mode, max speed 50 MHz. с максимальной частотой 50 МГц. При этом CNF15[1:0] = 10: Alternate function output Push-pull, он управляется таймером в режиме «тяни-толкай».

RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
output compare что это. Смотреть фото output compare что это. Смотреть картинку output compare что это. Картинка про output compare что это. Фото output compare что этоДля работы таймера на него нужно подать тактирование, что мы и делаем устанавливая бит 0 (TIM2EN), не изменяя остальных, возможно уже установленных битов.

TIM2->CR1 = 0x00000000;
output compare что это. Смотреть фото output compare что это. Смотреть картинку output compare что это. Картинка про output compare что это. Фото output compare что это
Многие настройки таймера необходимо делать при выключенном таймере, поэтому мы его останавливаем, так, на всякий случай, а то вдруг он где-то в программе запущен был. Для этого сбрасываем бит 0 CEN. Заодно сбрасываем и все остальные биты, хотя для нас здесь значение имеет, пожалуй, бит 4 DIR — он задаёт направление счёта. При нуле — счётчик инкементирует значение. Хотя, в принципе это не важно — можно и декрементировать, импульсы всё равно будут.

TIM2->ARR = 1;
Это шестнадцатиразрядный регистр переполнения, до значения которого (0xFFFF — max) счётчик будет считать, а потом обнуляться и считать заново. По нашим условиям он будет считать до 1, т.е. 0,1…0,1…0,1 и т.д.

TIM2->CCMR1 = 0x00000038;
output compare что это. Смотреть фото output compare что это. Смотреть картинку output compare что это. Картинка про output compare что это. Фото output compare что это
Для бит 6-4 OC1M: Output compare 1 mode устанавливаем значение = 011. Оно определяет поведение вывода CH1 (PA15) при равенстве счётного и TIMx_CCR1 — регистра. В нашем случае значение вывода будет меняться на противоположное, ведь мы хотим формировать меандр! Бит 3 OC1PE определяет порядок изменения значения регистра сравнения TIMx_CCR1. Если он сброшен — изменение будет проведено немедленно, даже во время счёта, если установлен — изменение значения произойдет после обновления события. Я решил его установить, хоть это и не важно.

TIM2->CCR1 = 1;
Шестнадцатиразрядный регистр сравнения. Значение должно быть не нулевое и не больше значения регистра переполнения TIM2->ARR, а то сравнение никогда не произойдет. При совпадении значения счётного регистра со значением регистра сравнения произойдёт событие — переключение значения вывода CH1 (PA15). �?менно такое событие мы установили в регистре TIM2->CCMR1.

TIM2->CCER = 0x00000001;
output compare что это. Смотреть фото output compare что это. Смотреть картинку output compare что это. Картинка про output compare что это. Фото output compare что этоБит 0 CC1E, если канал блока сравнения 1 сконфигурирован как выход, подключает его на соответствующий выходной контакт CH1 (PA15).

Вот таким образом инициализируется таймер для работы в режиме сравнения 1 канала. Вообще-то сюда ещё необходимо добавить оператор, устанавливающий значение делителя счётных импульсов (регистр TIMx prescaler (TIMx_PSC)), однако по умолчанию он нулевой, и я зашарился одной строчкой ))) После инициализации таймера логику его работы можно визуально отследить по структурной схеме ниже:
output compare что это. Смотреть фото output compare что это. Смотреть картинку output compare что это. Картинка про output compare что это. Фото output compare что это

Как я уже упоминал выше, имея перед глазами структурную схему и описания регистров довольно легко разобраться в работе таймера во всех режимах. На ней видны все настройки, флаги, когда происходят события и пр.

Источник

ОБОРУДОВАНИЕ
ТЕХНОЛОГИИ
РАЗРАБОТКИ

Блог технической поддержки моих разработок

Урок 16. Таймеры STM32 в режиме счетчиков. Генерация циклических прерываний от таймеров.

output compare что это. Смотреть фото output compare что это. Смотреть картинку output compare что это. Картинка про output compare что это. Фото output compare что это

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

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

В этом уроке мы будем рассматривать таймеры в качестве именно такого функционального применения. Т.е. будем использовать их для генерации циклических прерываний.

Таймеры STM32.

У нашего микроконтроллера STM32F103C8T6 есть 4 таймера:

Все таймеры имеют одинаковую архитектуру. Расширенный таймер отличается наличием дополнительных аппаратных узлов для формирования противофазных сигналов ШИМ. В результате его можно конфигурировать на работу в режиме 6-канального ШИМ и управлять им тремя полумостовыми усилителями мощности.

У таймеров большой выбор источников тактирования, есть предделители, обеспечивается цифровая фильтрация входных сигналов, возможна синхронизация между собой и много еще чего.

Но сейчас нас интересует исключительно режим счетчика с перезагрузкой. Именно в этом режиме удобнее всего формировать циклические прерывания.

Функциональная схема таймера достаточно сложная. Я выделил только необходимую нам часть.

output compare что это. Смотреть фото output compare что это. Смотреть картинку output compare что это. Картинка про output compare что это. Фото output compare что это

Собственно отсчет импульсов или времени происходит на 16-ти разрядном счетчике CNT. Когда код счетчика достигает значения регистра перезагрузки, счетчик сбрасывается в 0. Таким образом, счетчик считает по циклу от 0 до значения регистра перезагрузки.

Частота сигнала тактирования таймера может быть уменьшена с помощью 16-ти разрядного предделителя PSC.

Перезагрузка счетчика формирует событие (прерывание). Частота его появления также может быть уменьшена счетчиком повторов (8 разрядов). Коэффициент деления задается в регистре повторов.

Код счетчика используется другими узлами таймера, например, для формирования ШИМ. Но об этом в других уроках.

В качестве источника тактирования могут быть выбраны:

Сейчас мы будем использовать только внутренний источник тактирования.

Режимы счета таймера.

При использовании таймера в качестве счетчика импульсов можно выбрать один из режимов:

При прямом счете содержимое счетчика с каждым импульсом тактирования увеличивается на 1. Когда оно достигает значения регистра перезагрузки, то счетчик сбрасывается. Таким образом,таймер считает по циклу от 0 до значения перезагрузки. В момент перезагрузки формируется прерывание.

В режиме обратного (реверсивного) счета с каждым входным импульсом содержимое счетчика уменьшается на 1. При достижении 0 в счетчик загружается значение регистра перезагрузки и реверсивный счет продолжается. Таймер считает по циклу от значения перезагрузки до 0. В момент перезагрузки формируется прерывание.

Двунаправленный режим означает, что счетчик считает в прямом направлении от 0 до значения перезагрузки, а затем переходит в реверсивный режим и счет ведется до 0. При изменении направления счета и сбросе генерируется прерывание.

Установка конфигурации таймера с помощью STM32CubeMX.

Давайте научимся конфигурировать таймеры через STM32CubeMX. Заодно в строгой форме перечислим регистры, задающие режимы таймера и выясним, что конкретно в них загружать.

Создадим проект Lesson16_1. Настроим конфигурацию системы тактирования. Обратим внимание на то, что частота тактирования таймеров на шинах APB1 и APB2 задана 72 мГц.

output compare что это. Смотреть фото output compare что это. Смотреть картинку output compare что это. Картинка про output compare что это. Фото output compare что это

output compare что это. Смотреть фото output compare что это. Смотреть картинку output compare что это. Картинка про output compare что это. Фото output compare что это

Теперь будем конфигурировать таймер 1. В нашем микроконтроллере он самый многофункциональный.

output compare что это. Смотреть фото output compare что это. Смотреть картинку output compare что это. Картинка про output compare что это. Фото output compare что это

Ниже появилось поле Parameter Settings.

output compare что это. Смотреть фото output compare что это. Смотреть картинку output compare что это. Картинка про output compare что это. Фото output compare что это

Давайте подробно разберем, что в нем.

Prescaler (PSC).

Это регистр предделителя. Предделитель делит частоту тактирования таймера, поступающую на основной счетчик. По сути, он, вместе с входной частотой, определяет разрешающую способность таймера.

Счетчик предделителя считает входные импульсы от 0 до значения этого регистра. При равенстве кода счетчика и регистра счетчик сбрасывается и начинает считать заново. В момент сброса формируется импульс тактирования основного счетчика таймера. Таким образом, значение регистра предделителя определяет коэффициент деления частоты входного сигнала.

Счетчик и регистр предделителя 16-ти разрядные. Т.е. максимальный коэффициент деления 65536.

Надо помнить, что реальный коэффициент деления на 1 больше, чем значение регистра предделителя. Например:

Значение регистра предделителяКоэффициент деления
01
9991000
65535 (максимальное значение)65536

Регистр предделителя имеет буферный регистр. Поэтому его значение можно устанавливать в любой момент. Реальное изменение коэффициента деления произойдет при перезагрузке буферного регистра в момент перезагрузки основного счетчика таймера.

Counter mode.

Режим счетчика, определяет в какую сторону считать.

output compare что это. Смотреть фото output compare что это. Смотреть картинку output compare что это. Картинка про output compare что это. Фото output compare что это

Counter Period (Auto Reload Register).

Регистр перезагрузки. Его значение задает период работы таймера. Конечно, на время периода влияет еще режим счета.

Счетчик 16-ти разрядный. Значит, для однонаправленного счета период может длиться от 1 до 65536 длительностей импульсов предделителя. Реальная длительность периода на 1 больше значения регистра перезагрузки. Все как для регистра предделителя.

Internal Clock Division (CKD).

Делитель входной частоты для внутренних нужд таймера.

output compare что это. Смотреть фото output compare что это. Смотреть картинку output compare что это. Картинка про output compare что это. Фото output compare что это

Частота используется при фильтрации внешних сигналов, формировании “мертвого времени” ШИМ и т.п. Сейчас это нам не интересно.

Repetition Counter (RCR).

Регистр счетчика повторов. Присутствует не во всех таймерах. Счетчик повторов считает импульсы событий на выходе таймера и при достижении значения регистра повторов сбрасывается и формирует реальное событие. Т.е. он делит частоту генерации событий (прерываний) таймера.

Auto-reload preload.

Управляет режимом перезагрузки специальный бит, а в STM32CubeMX выбор делается в выпадающем меню.

output compare что это. Смотреть фото output compare что это. Смотреть картинку output compare что это. Картинка про output compare что это. Фото output compare что это

Вкладка NVIC Settings позволяет выбрать нужный тип прерывания, связанного с таймером.

output compare что это. Смотреть фото output compare что это. Смотреть картинку output compare что это. Картинка про output compare что это. Фото output compare что это

Пример конфигурации таймера и реализации программы.

Сделаем практическую задачу. Установим конфигурацию таймера 1, обеспечивающую циклические прерывания с периодом 0,5 секунд. В обработчике прерывания будем инвертировать состояние светодиода. В результате получим мигающий светодиод, но с использованием таймера и прерывания.

Частота тактирования у нас 72 мГц. Превратим ее с помощью предделителя в круглое значение.

Например, если задать 720 – 1 = 719, то частота после предделителя будет 72 000 000 / 720 = 100 000 Гц, или период 10 мкс.

Если в регистр перезагрузки задать значение 50 000, то получим требуемый период 0,5 секунд.

output compare что это. Смотреть фото output compare что это. Смотреть картинку output compare что это. Картинка про output compare что это. Фото output compare что это

Во вкладке NVIC Settings выберем прерывание по перезагрузке счетчика.

output compare что это. Смотреть фото output compare что это. Смотреть картинку output compare что это. Картинка про output compare что это. Фото output compare что это

Создаем проект и открываем его в Atollic TrueStudio.

В папке Src проекта создан файл stm32f1xx_it.c. Он существовал и во всех предыдущих проектах. Просто мы на него до времени не обращали внимания.

Это файл обработчиков прерываний. Хороший стиль размещать функции обработки прерываний в нем.

В самом конце файла появилась функция:

void TIM1_UP_IRQHandler(void) <

/* USER CODE BEGIN TIM1_UP_IRQn 0 */
/* USER CODE END TIM1_UP_IRQn 0 */

/* USER CODE BEGIN TIM1_UP_IRQn 1 */
/* USER CODE END TIM1_UP_IRQn 1 */
>

Это и есть обработчик прерывания таймера 1. Код, который мы поместим в функцию, будет вызываться с периодом 0,5 секунд.

Вызовем в обработчике прерывания функции инверсии состояния для обоих светодиодов.

void TIM1_UP_IRQHandler(void) <

/* USER CODE BEGIN TIM1_UP_IRQn 0 */

HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_13);

Мы установили конфигурацию таймера, но не запустили его. Сделаем это HAL-функцией в файле main.c.

/* Initialize all configured peripherals */

HAL_TIM_Base_Start_IT(&htim1); // запуск таймера

Функция запускает таймер в режиме генерации прерываний.

Все. Компилируем, загружаем, проверяем. Оба светодиода мигают раз в секунду.

Полностью проект можно загрузить по ссылке:

Зарегистрируйтесь и оплатите. Всего 60 руб. в месяц за доступ ко всем ресурсам сайта!

Основной цикл у нас пустой. Программа просто крутится в нем.

while (1) <

/* USER CODE END WHILE */

По отношению к нему светодиоды мигают в фоновом режиме, сами по себе. Если мы будем выполнять в цикле какие-либо действия, это никак не скажется на равномерном мигании светодиодов. Единственное условие – надолго не запрещать прерывания.

В следующем уроке будем разрабатывать программу, обрабатывающую сигнал кнопки параллельным процессом. Научимся связывать переменные разных файлов одной программы. Разберемся в специфике использования функций обработки прерываний.

Источник

Добавить комментарий

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