У меня есть плата STM32F411, и я хочу выводить сигнал ШИМ с использованием таймеров/ШИМ/DMA: каждые 2 мс отправляется 16 импульсов, каждый из которых представляет один бит. Каждый импульс имеет период ~3 микросекунды с различной скважностью.
Чтобы изменить рабочий цикл, я записываю в 32-битный выходной регистр захвата/сравнения (TIMx->CCRx) посредством передачи DMA из буфера в памяти (буфер содержит 16 32-битных целых чисел). По сути, выходной сигнал ВЫСОКИЙ, пока счетчик таймера меньше значения этого регистра, затем он меняется на НИЗКИЙ, пока таймер не переполнится.
У меня есть два вопроса:
Буду признателен за любые подсказки!
Кстати, я использую libopencm3.
Однако вы можете включить предварительную загрузку 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.
Как я уже говорил, если вы настроите DMA правильно, за период будет только один DMA, так что надежды нет. Одно слово предостережения: если таймер работает с установленным TIMx_DIER.UDE (или любым другим битом включения DMA TIMx_DIER.xxDE), когда DMA выключен, триггер получает и остается установленным, и при последующем включении DMA он немедленно срабатывает один раз. . Вам необходимо очистить TIMx_DIER.xxDE, чтобы очистить триггер.
Спасибо за объяснение! Итак, действительно ли нет способа предотвратить перезапись промежуточного CCR? Тогда буду надеяться на лучшее... Отличная идея со стопором; значительно упрощает задачу :)