Jump to content

    
Sign in to follow this  
kostyan1

STM32F4: по EXTI запускать чтение SPI по DMA

Recommended Posts

Народ помогите разобраться! Готовность данных во внешнем АЦП сигнализируется перепадом в ноль на пине. После этого надо прочитать из АЦП 3 байта, и далее ждать следующей оцифровки. Есть какой то механизм в STM32F4 чтобы по перепаду на пине запускать чтение SPI через DMA, не пользуя прерывание?

Edited by kostyan

Share this post


Link to post
Share on other sites

Я бы сделал запуск таймера по сигналу от АЦП, а таймер может выдавать нужное чисто запросов DMA с нужными интервалами через каналы Compare, к примеру. В свою очередь, DMA может запускать SPI.

Короче, всё можно сделать. Нужно просто правильно состыковать все кусочки.

Share this post


Link to post
Share on other sites

спасибо, начал гуглить в заданном направлении, наткнулся на местную тему http://electronix.ru/forum/index.php?showt...02445&st=15 , в теме нашел пример, который в данный момент и медитирую.

Share this post


Link to post
Share on other sites

Так, "многоходовочка" вроде бы вырисовывается: настраиваем таймер TIM1_CH1 на падающий фронт; таймер генерит запрос на DMA2_Stream6 Channel_0, который настроен на передачу по SPI1 трех нулевых байтов, плюс настроен еще DMA2_Stream3 Channel_3 на чтение из SPI1, которое начинается по записи в передатчик SPI1 первого байта.

В оконцове цепочки мы прочитаем 3 байта из внешнего АЦП - 24х битное значение и получим прерывание об окончании чтения (если настроим его естественно) . А хотелось бы прочитать кучу значений АЦП в десятки кБ, и только потом получить прерывание какое то об достигнутом. Можно это реализовать?

Share this post


Link to post
Share on other sites

В этой теме задача практически такая же.

есть внешний АЦП. передает данные по SPI. О готовности данных сообщает отрицательным фронтом на ноге.

 

Последовательность работы должна быть такая:

1)каждые 10мкс приходит отрицательный фронт на ногу

2) с приходом каждого фронта один канал DMA пишет в SPI_TX несколько байт

3) другой канал DMA натсроен на событие от SPI_RX и принимает столько данных сколько отправили в SPI_TX.

 

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

Share this post


Link to post
Share on other sites

спасибо за наводку, буду медитировать это:

 

Я бы предложил так:

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 срабатываний готовности одно прерывание с данными в кольцевом буфере. Пока шаманим с этими данными, заполняется вторая часть кольцевого буфера - никто не потеряется.

Edited by kostyan

Share this post


Link to post
Share on other sites
спасибо за наводку, буду медитировать это:

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

Share this post


Link to post
Share on other sites

Подходит время расставлять точки над Ё:

 

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

Я правильно понимаю, что надо настроить таймер на режим захвата? Какой то минимальный пример или сцылу на пример бы...

 

Share this post


Link to post
Share on other sites
Я правильно понимаю, что надо настроить таймер на режим захвата? Какой то минимальный пример или сцылу на пример бы...

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

Share this post


Link to post
Share on other sites

А вроде даже и заработало, но есть нюанс!

 

В доках написано: "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).

 

Вопрос один - собственно КАК? Как от одного таймера настроить два запроса на разные каналы ДМА? Каплю кода бы в пример...

Edited by kostyan

Share this post


Link to post
Share on other sites

Сделал в итоге через EXTI, как уже ранее предлагалось:

А я б не парился, и сделал запуск DMA-обмена с SPI в прерывании от EXTI.

Хотя в качестве разминки для мозгов такие комбинации наверное полезны, да:)

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

 

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this