Оркестровка передачи DMA на периферийное устройство PWM на STM32

У меня есть плата STM32F411, и я хочу выводить сигнал ШИМ с использованием таймеров/ШИМ/DMA: каждые 2 мс отправляется 16 импульсов, каждый из которых представляет один бит. Каждый импульс имеет период ~3 микросекунды с различной скважностью.

Чтобы изменить рабочий цикл, я записываю в 32-битный выходной регистр захвата/сравнения (TIMx->CCRx) посредством передачи DMA из буфера в памяти (буфер содержит 16 32-битных целых чисел). По сути, выходной сигнал ВЫСОКИЙ, пока счетчик таймера меньше значения этого регистра, затем он меняется на НИЗКИЙ, пока таймер не переполнится.

У меня есть два вопроса:

  1. Что произойдет, если передача DMA не будет идеально синхронизирована с выходом ШИМ? Например, если первые два значения CCR, переданные через DMA, поступают в течение первого периода импульса. Пришедшее 2-е значение «выбрасывается» или периферийное устройство ШИМ сохраняет его и использует для 2-го импульса?
  2. Как я могу заставить периферийное устройство ШИМ выводить только 16 импульсов, затем установить линию на НИЗКИЙ уровень и ждать, пока не потребуется передать следующие 16 импульсов? На данный момент я могу только непрерывно выводить импульсы, но мне не удается реализовать задержку между сериями импульсов.

Буду признателен за любые подсказки!

Кстати, я использую libopencm3.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
129
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
  1. TIMx_CCRx — это регистр. Если вы запишете в него два значения, второе перезапишет первое.

Однако вы можете включить предварительную загрузку TIMx_CCRx, если установлен соответствующий бит TIMx_CCMRx.OCxPE. В этом случае процессор или DMA записывает не в «рабочий» регистр TIMx_CCRx (с которым сравнивается TIMx_CNT), а в «промежуточный» регистр (ST использует другую номенклатуру, но, по моему мнению, это более запутанно). Значение из «промежуточного» регистра копируется в «рабочий» регистр при следующем событии обновления (обычно при «опрокидывании» таймера, когда TIMx_CNT достигает TIMx_ARR и затем переходит в 0). Но даже в этом случае, если вы дважды записываете в TIMx_CCRx в течение одного периода TIM, обе записи идут в «промежуточный» регистр, а вторая перезаписывает первую.

Но вам вообще не нужно беспокоиться о двух операциях записи за период. Если вы не работаете на каких-то экстремальных тактовых частотах, механизм DMA вместе с вышеуказанной предварительной загрузкой гарантирует, что за период будет осуществляться только одна передача DMA. Только не запускайте DMA самим CC (как я часто вижу в примерах и в Cube/HAL), а Update.

  1. Добавьте в конце один «стопорный» период с нулевым рабочим циклом. Это делает выход таймера постоянно низким, даже если таймер продолжает работать.

Спасибо за объяснение! Итак, действительно ли нет способа предотвратить перезапись промежуточного CCR? Тогда буду надеяться на лучшее... Отличная идея со стопором; значительно упрощает задачу :)

Martin Fritz 07.04.2024 23:02

Как я уже говорил, если вы настроите DMA правильно, за период будет только один DMA, так что надежды нет. Одно слово предостережения: если таймер работает с установленным TIMx_DIER.UDE (или любым другим битом включения DMA TIMx_DIER.xxDE), когда DMA выключен, триггер получает и остается установленным, и при последующем включении DMA он немедленно срабатывает один раз. . Вам необходимо очистить TIMx_DIER.xxDE, чтобы очистить триггер.

wek 08.04.2024 08:56

Другие вопросы по теме