Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32F4: по EXTI запускать чтение SPI по DMA
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
kostyan
Народ помогите разобраться! Готовность данных во внешнем АЦП сигнализируется перепадом в ноль на пине. После этого надо прочитать из АЦП 3 байта, и далее ждать следующей оцифровки. Есть какой то механизм в STM32F4 чтобы по перепаду на пине запускать чтение SPI через DMA, не пользуя прерывание?
scifi
Я бы сделал запуск таймера по сигналу от АЦП, а таймер может выдавать нужное чисто запросов DMA с нужными интервалами через каналы Compare, к примеру. В свою очередь, DMA может запускать SPI.
Короче, всё можно сделать. Нужно просто правильно состыковать все кусочки.
kostyan
спасибо, начал гуглить в заданном направлении, наткнулся на местную тему http://electronix.ru/forum/index.php?showt...02445&st=15 , в теме нашел пример, который в данный момент и медитирую.
kostyan
Так, "многоходовочка" вроде бы вырисовывается: настраиваем таймер TIM1_CH1 на падающий фронт; таймер генерит запрос на DMA2_Stream6 Channel_0, который настроен на передачу по SPI1 трех нулевых байтов, плюс настроен еще DMA2_Stream3 Channel_3 на чтение из SPI1, которое начинается по записи в передатчик SPI1 первого байта.
В оконцове цепочки мы прочитаем 3 байта из внешнего АЦП - 24х битное значение и получим прерывание об окончании чтения (если настроим его естественно) . А хотелось бы прочитать кучу значений АЦП в десятки кБ, и только потом получить прерывание какое то об достигнутом. Можно это реализовать?
adnega
В этой теме задача практически такая же.
Цитата
есть внешний АЦП. передает данные по SPI. О готовности данных сообщает отрицательным фронтом на ноге.

Последовательность работы должна быть такая:
1)каждые 10мкс приходит отрицательный фронт на ногу
2) с приходом каждого фронта один канал DMA пишет в SPI_TX несколько байт
3) другой канал DMA натсроен на событие от SPI_RX и принимает столько данных сколько отправили в SPI_TX.

В SPI_TX отправляются dummy данные, так как это нужно лишь для приёма данных от SPI_TX
kostyan
спасибо за наводку, буду медитировать это:

Цитата
Я бы предложил так:
1. Настраиваем один DMA на передачу 16 байт по событиям от SPI_TX.
2. Настраиваем другой DMA на прием N*2*16 байт по событиям от SPI_RX в кольцевой буфер с генерацией прерываний при заполнении и полузапонении.
3. Настраиваем таймер на одиночный запуск по спаду на ноге.
4. Первый канал совпадения таймера настраиваем на запись через еще один канал DMA числа 16 для NDTR первого DMA (M2M).
5. Второй канал совпадения таймера настраиваем на запись через еще один канал DMA управляющего слова (регистр CR) для первого DMA для запуска передачи (M2M).
6. Разрешаем таймер.
7. Имеем каждые N срабатываний готовности одно прерывание с данными в кольцевом буфере. Пока шаманим с этими данными, заполняется вторая часть кольцевого буфера - никто не потеряется.
scifi
Цитата(kostyan @ Dec 18 2014, 07:08) *
спасибо за наводку, буду медитировать это:

Там можно много вариантов придумать, в том числе каскады таймеров. Конкретно этот вариант как-то странно выглядит. Ну да ладно, вдруг что-то получится.
kostyan
Подходит время расставлять точки над Ё:

Цитата
3. Настраиваем таймер на одиночный запуск по спаду на ноге.

Я правильно понимаю, что надо настроить таймер на режим захвата? Какой то минимальный пример или сцылу на пример бы...
adnega
Цитата(kostyan @ Dec 29 2014, 15:04) *
Я правильно понимаю, что надо настроить таймер на режим захвата? Какой то минимальный пример или сцылу на пример бы...

Не совсем. У таймеров есть внешний вход "ETR". По фронту этого сигнала можно начать счет установкой "Trigger Mode" в поле "SMS" регистра "TIMx_SMCR".
kostyan
А вроде даже и заработало, но есть нюанс!

В доках написано: "TIM_SlaveMode_External1: Rising edges of the selected trigger (TRGI) clock the counter. " То есть нарастающий фронт ловится, а мне надо спадающий faling edges. Как то можно крутануть в контроллере это дело?

А пардон, сам нашел в доках.

Заработал таймер, теперь на повестке:

Цитата
4. Первый канал совпадения таймера настраиваем на запись через еще один канал DMA числа 16 для NDTR первого DMA (M2M).
5. Второй канал совпадения таймера настраиваем на запись через еще один канал DMA управляющего слова (регистр CR) для первого DMA для запуска передачи (M2M).


Вопрос один - собственно КАК? Как от одного таймера настроить два запроса на разные каналы ДМА? Каплю кода бы в пример...
kostyan
Сделал в итоге через EXTI, как уже ранее предлагалось:
Цитата(AHTOXA @ Sep 12 2014, 16:28) *
А я б не парился, и сделал запуск DMA-обмена с SPI в прерывании от EXTI.
Хотя в качестве разминки для мозгов такие комбинации наверное полезны, даsm.gif

Способ запуска одного дма через 2 других М2М дма не подходит, ибо помимо установки регистров DMA1_Stream4->NDTR и DMA1_Stream4->CR, необходимо еще устанавливать регистр DMA1->HIFCR.

И вроде вполне все бодро крутится - проц готов к свершениям помимо данной задачи. Тему можно закрывать.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.