Перейти к содержанию
    

STM32F4 ACD->DMA->USART

Ситуация такая... Оцифровываю несколько датчиков и через DMA сохраняю их показания в памяти. После записи энного количества показаний хочу передать их опять же через DMA по USART на компьютер, для дальнейшей обработки. Первую половину цепочки настроил, данный записываются в память. А вот передать их не получается. Подозреваю, что проблема где-то в настройках DMA.

Вот так я настраиваю DMA на передачу данных:

    DMA_InitTypeDef DMA_InitStruct;
    DMA_InitStruct.DMA_Channel = DMA_Channel_4;
    DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&(USART1->DR);
    DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)&sensors_data;
    DMA_InitStruct.DMA_DIR = DMA_DIR_MemoryToPeripheral;
    DMA_InitStruct.DMA_BufferSize = 30000;    //Size of data in uint32_t sencors_data[]
    DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStruct.DMA_Priority = DMA_Priority_High;
    DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Enable;
    DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
    DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single;
    DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
    DMA_Init(DMA2_Stream7, &DMA_InitStruct);
    USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
    USART_Cmd(USART1, ENABLE);

 

Сомневаюсь в парвильности этих параметров:

DMA_InitStruct.DMA_BufferSize = 30000;
DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;
DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Enable;
DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;

Если у меня передаваемый массив состоит из 30000 16-битных значений, а передаю я его по одному байту, правильно ли я указал размер буфера?

Я так понимаю, что при передаче HalfWord -> Byte без FIFO не обойтись. На что влияет его размер (FIFOThreshold)?

Как правильно выбрать DMA_Mode? Что значат режим Circular и режим Normal?

И что такое MemoryBurst и PeripheralBurst?

 

И еще один момент. Как я понимаю, после команды

DMA_Cmd(DMA2_Stream7, ENABLE);

DMA сразу начинает передачу. Это так?

В дебагере заметил, что при запуске этой команды в регистре DMA_S7CR устанавливается бит EN, но на следуещем же такте он сбрасывается. Почему?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

прочитайте тут, большинство вопросов отсеится

Изменено пользователем Falkon_99

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

прочитайте тут, большинство вопросов отсеится

В том то и дело, что уже читал, но осталось непонимание. Хороший сайт, спасибо автору. Но в этой статье, как и в большинстве других есть указания, что и как настраивается, но не объясняется почему именно так.

 

Кстати, по поводу моего кода. Когда проверил работу уже на железе, а не в дебагере, оказалось что всё работает. Видимо как-то не туда смотрел в дебагере. Единственный момент, который следует исправить - это размер буфера. Так как я отправляю 30000 HalfWord'ов по одному байту, то таких байт, а соответсвенно и запросов к DMA должно быть в два раза больше.

Изменено пользователем Haamu

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И все-же...

DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Enable;
DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStruct.DMA_MemoryBurst = ???????
DMA_InitStruct.DMA_PeripheralBurst = ???????

Какими доолжны быть последние два параметра при таких вот настройках DMA? Есть кто-нибудь, кто разобрался в параметрах Burst?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

DMA_InitStruct.DMA_MemoryBurst = ???????

DMA_InitStruct.DMA_PeripheralBurst = ???????[/code]

Какими доолжны быть последние два параметра при таких вот настройках DMA? Есть кто-нибудь, кто разобрался в параметрах Burst?

Эхх... кто-бы знал, у меня для STM32F105 в настройках таких параметрок к сожалению нет.

Вы бы уж написали какой конкретно процессор используете.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Burst mode - режим, когда за раз передаётся сразу несколько байт (или не байт, смотря на какую "ширину" настроено DMA). В данном случае он не нужен.

 

А контроллер указан в заголовке темы (не полностью, но для понимания вопроса достаточно ;-) )

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У меня STM32F407VG. На сколько я понял в STM32F10x в контроллере DMA вообще FIFO буфера нет, поэтому и Burst режима тоже нет. Хотя, как же тогда передаются данные разного размера (в памяте и в периферии)?..

 

Burst mode - режим, когда за раз передаётся сразу несколько байт (или не байт, смотря на какую "ширину" настроено DMA). В данном случае он не нужен.

Вас не затруднит пояснить, в каких случаях он нужен и как им пользоваться?

Правильно я понял, что для разных размеров данных в памяти и периферии без FIFO не обойтись?

 

Я решил проблемму в лоб, без использования FIFO. Просто указал, что в памяти массив состоит из байтов и отключил FIFO. Передаю по одному байту, а наверху уже собираю в полуслова. Но ведь так поидее не правильно...

Еще сбивает с толку, что при отладке в CoIDE сразу посли запуска DMA появляется флаг FIFO error. При том, если не ошибаюсь, и при отключенном FIFO он выскакивает. Не пойму, это глюк в настройках DMA или в CoIDE...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

DMA - это не совсем процессор, поэтому вы вряд ли корректно увидите отладчиком что-то. Да и зачем?

Какая-то тенденция нехорошая, чуть ли не по шагам рассмотреть деятельность процессора. Одно время ряд спецов говорило, что вообще надо отказаться от отладчика. Я тогда не понимал зачем. Теперь вижу.

Смотрите отладчиком только ключевые моменты. Правильность передачи буфера, к примеру. Например остановится по прерыванию, завершения передачи DMA и проверить правильность выполнения. Иначе зароетесь, и толком ничего не увидите, а будет только сумбур в голове, ИМХО.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Какая-то тенденция нехорошая, чуть ли не по шагам рассмотреть деятельность процессора. Одно время ряд спецов говорило, что вообще надо отказаться от отладчика. Я тогда не понимал зачем. Теперь вижу.

Смотрите отладчиком только ключевые моменты. Правильность передачи буфера, к примеру. Например остановится по прерыванию, завершения передачи DMA и проверить правильность выполнения. Иначе зароетесь, и толком ничего не увидите, а будет только сумбур в голове, ИМХО.

 

Может Вы и правы на счет того, что не стоит каждый шаг отслеживать. Я так пол дня убил на эксперименты с настройками ДМА и отслеживанием его работы в отладчике, пока на проверел на железе, оказалось все работает прекрасно. Так же было, когда с USART разбирался. Всё не мог понять, почему у меня регистр данных пустой, пока не увидел, что на самом деле всё работает.

Я до STM32 c отладчиками не работал. AVRки в симуляторе гонял. Видимо в том и отличие отладчика от симулятора в том, что в симуляторе всё пошагово выполняется, а в отладчике только программа останавливается, а периферия, которая на автомате работает, продолжает выполнять свои действия.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, читайте Reference Manual - в DMA burst нужен для того, кто имеет у буфера FIFO: "Supports incremental burst transfers of 4, 8 or 16 beats. The size of the burst is

software-configurable, usually equal to half the FIFO size of the peripheral"

 

Т.е. например USART передает информацию побайтово, если нет FIFO, то DMA кладёт в буфер USART за каждую операцию только 1 байт, потом ждет окончания его передачи, кладёт следующий байт и т.д. Когда у буфера USART есть FIFO - тогда, DMA за одну операцию может сложить туда сразу несколько байт(в половину буфера), что разгружает шину.

 

FIFO error - это или неправильная настройка DMA или ошибки в работе DMA, почитай Reference Manual там описано когда она возникает.

 

Правильно я понял, что для разных размеров данных в памяти и периферии без FIFO не обойтись?

Нет, DMA без разницы какой размер данных лежит в памяти, он просто читает указанное количество байт(DMA_InitStruct.DMA_Memory0BaseAddr) начиная с указанного адреса(DMA_InitStruct.DMA_Memory0BaseAddr) из памяти и передает их в буфер приемника, или наоборот.

Количество передаваемых байт в каждом чтении должны совпадать с размером буфера приемника! Но если буфер приемника имеет FIFO, тогда они могут не совпадать:

"Independent source and destination transfer width (byte, half-word, word): when the data widths of the source and destination are not equal, the DMA automatically packs/unpacks the necessary transfers to optimize the bandwidth. This feature is only available in FIFO mode"

 

Я решил проблемму в лоб, без использования FIFO. Просто указал, что в памяти массив состоит из байтов и отключил FIFO. Передаю по одному байту, а наверху уже собираю в полуслова. Но ведь так поидее не правильно...

А так все и делают, ведь USART передает данные побайтово.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...