STM32 DMA от таймера к памяти - PullRequest
1 голос
/ 12 апреля 2020

Я использую STM32H743. У меня есть внешний сигнал синхронизации, поступающий на вывод GPIO, и я хочу очень точно измерить прошедшее время между каждым нарастающим (или падающим) фронтом во внешнем тактовом сигнале. Поэтому я настроил все так, чтобы TIM4 запускался внешними часами, а TIM5 - внутренним генератором.

Я написал IRQ так, чтобы всякий раз, когда срабатывал TIM4, запускалось прерывание, которое захватывает значение TIM5. Кажется, все работает хорошо, но мне интересно, смогу ли я сделать это через DMA, чтобы избежать всех переключений контекста и освободить процессор. По сути, я хочу настроить DMA таким образом, чтобы каждое событие TIM4 инициировало передачу DMA, которая копирует значение счетчика TIM5 куда-то в кольцевой буфер.

Я искал по форумам и документации DMA, но я не уверен о том, может ли регистр таймера быть действительным источником DMA. Я думал, может быть, я мог бы сделать что-то вроде этого:

hDma->PAR = (uint32_t) &htim5.Instance->CNT;
hDma->M0AR = (uint32_t) myBufferPtr;
hDma->NDTR = myBufferSize;
hDma->CR |= (uint32_t)DMA_SxCR_EN;

Но я не уверен, может ли это сработать.

Короткая версия: Могу ли я использовать регистр CNT таймера в качестве прямого доступа к памяти источник передачи? Будет ли это передача с периферийного устройства в память? Или передача из памяти в память? Есть ли другие флаги, которые мне нужны, чтобы эта работа работала? Или это невозможно? Или есть другая особенность STM32, которая облегчит подсчет времени между импульсами?

1 Ответ

2 голосов
/ 15 апреля 2020

Отказ от ответственности

Я должен признаться, что мой длительный практический опыт работы с STM32 к настоящему времени остался с основными семействами контроллеров, такими как STM32F0, STM32F3, STM32F4 и STM32L4. Поэтому я отвечаю на основании того, что эти контроллеры предложат вам в вашей ситуации. Серия STM32H7 намного сильнее, не говоря уже о том, что она предлагает несколько дополнительных технологий DMA, таких как DMA2D, MDMA и многие другие, в которых я не уверен. Но я думаю, что упрощенный ответ может также помочь вам на данный момент, поэтому я осмелюсь написать его.


Могу ли я использовать регистр CNT таймера в качестве источника передачи DMA? Будет ли это передача с периферийного устройства в память? Или передача из памяти в память? Есть ли другие флаги, которые мне нужны, чтобы эта работа работала? Или это невозможно?

Я бы ожидал, что это сработает. Я не вижу причины не читать регистр TIMx_CNT при передаче DMA.

Регистр CNT, безусловно, является периферийным адресом , поэтому вы должны настроить его как периферийное устройство к ... передача памяти. Я полагаю, что разделение периферии / памяти относится к шине, с которой контроллер DMA извлекает данные (или к какой шине он их доставляет) в матрице шин, реализованной в каждом STM32.

Или есть еще одна функция STM32, которая облегчит подсчет времени между импульсами?

Да, есть: многие из периферийных устройств TIM (не все одинаковые) предлагают вам функцию, называемую «захват ввода» который соединяет канал (под) периферийного устройства экземпляра TIM со входом и имеет часть main периферийного устройства (того же самого!) для выполнения внутреннего тактирования. Предварительным условием этого является то, что вывод, который вы хотите измерить, имеет альтернативную функцию TIMx_CHy, а не «только» функцию TIMx_ETR.

Периферийные устройства TIM предлагают богатый диапазон различных вариантов конфигурации - и сложную беспорядок, пока вы не привыкли к этому. В качестве вступления и хорошего обзора я рекомендую два замечания по применению из ST:

Просматривая эти два, я нашел третий, который вы могли бы проверить для большей точности, связанный с таймерами HRTIM:

...