Описание DMA в РП К1921ВГ1Т

32-разрядные микроконтроллеры разработки АО "НИИЭТ"

Модераторы: ea, dav, bkolbov, Alis, pip, _sva_

durimar_13
Сообщения: 111
Зарегистрирован: 26 фев 2025, 13:06
Предприятие: Radioamateur
Откуда: Свердловская обл.

Re: Описание DMA в РП К1921ВГ1Т

Сообщение durimar_13 »

Проблему я решил!
По совету пользователя RabidRabbit обратился к ИИ по имени Алиса и (о, чудо!)
после нескольких итераций она предложила мне работающий как надо код.
Центральное место - использовать два переключаемых буфера для записи от DMA.
Дешево и сердито. Ну теперь буду знать, как это опытные программисты делают.
Модифицированный пример выкладываю, вдруг кому пригодится.
main.7z
(5.52 КБ) 85 скачиваний
С уважением, Виктор.
RabidRabbit
Сообщения: 259
Зарегистрирован: 10 июн 2025, 12:11
Предприятие: HomeWork

Re: Описание DMA в РП К1921ВГ1Т

Сообщение RabidRabbit »

Хорошо, что всё получилось :)
Мерседес
Сообщения: 37
Зарегистрирован: 05 авг 2026, 12:53
Предприятие: Каскад

Re: Описание DMA в РП К1921ВГ1Т

Сообщение Мерседес »

добрый день. хорошо что получилось. у меня вопрос/просьба. не могли бы вы попробовать ваш код с буферами большего размера. например 256 элементов. у меня в аналогичном примере значениями заполняется только 32 элемента, а остальной буфер нулями.
durimar_13
Сообщения: 111
Зарегистрирован: 26 фев 2025, 13:06
Предприятие: Radioamateur
Откуда: Свердловская обл.

Re: Описание DMA в РП К1921ВГ1Т

Сообщение durimar_13 »

Как всегда, я поторопился. Прошу прощения у сообщества, в предыдущем коде я оставил неработающий цикл очистки буфера. Поэтому будет виснуть после первой итерации.
Выкладываю новый код без этой очистки.
main.7z
(5.54 КБ) 80 скачиваний
Есть еще проблема: Для старта нужен RST. Причину не понимаю пока.
Может кто знает, подскажите, пожалуйста.
С уважением, Виктор.
RabidRabbit
Сообщения: 259
Зарегистрирован: 10 июн 2025, 12:11
Предприятие: HomeWork

Re: Описание DMA в РП К1921ВГ1Т

Сообщение RabidRabbit »

durimar_13 писал(а): 07 авг 2026, 09:27 Есть еще проблема: Для старта нужен RST. Причину не понимаю пока.
Что за RST?

Любой блок перед настройкой желательно "сбросить", т.е. например можно "сбрасывать" в самом начале кучку оборудования:

Код: Выделить всё

RCU->RSTDISAPB0 = 0;
RCU->RSTDISAPB1 = 0;
RCU->RSTDISAPB0;
Ну и как по классике делается "двойной буфер" на DMA:

Код: Выделить всё

__attribute__((aligned(0x10))) DMA_Channel_TypeDef descs[2];

void DMA_CH0_init() {
  //
  descs[0].DST_DATA_END_PTR = (uint32_t)adc_res_buf0;
  descs[0].SRC_DATA_END_PTR = (uint32_t)&(ADC->SEQ[0].SFIFO);
  descs[0].BUFFER_SIZE = sizeof(adc_res_buf0);
  descs[0].CHANNEL_CFG = (uint32_t)&descs[1] | (1 << DMA_CHANNEL_CFG_INTEN_Pos);
  //
  descs[1].DST_DATA_END_PTR = (uint32_t)adc_res_buf1;
  descs[1].SRC_DATA_END_PTR = (uint32_t)&(ADC->SEQ[0].SFIFO);
  descs[1].BUFFER_SIZE = sizeof(adc_res_buf1);
  descs[1].CHANNEL_CFG = (uint32_t)&descs[0] | (1 << DMA_CHANNEL_CFG_INTEN_Pos);

...

  //
  DMA->CH[0].DST_PTR = 0;
  DMA->CH[0].SRC_PTR = 0;
  //
  DMA->CH[0].NDTL_bit.BUFFER_SIZE = 0;
  // настройка первого (единственного) дескритора
  DMA->CH[0].CONFIG = (uint32_t)&(descs[0]);

...

}
Далее каждое прерывание от канала DMA->CH[0] будет заполнен очередная "половина" буфера:
1: adc_res_buf0
2: adc_res_buf1
3: adc_res_buf0
4: adc_res_buf0
...

Плюс такого подхода в том, что в прерывании от DMA нужно только увеличить на 1 глобальную переменную, указывающую как на номер заполненного буфера (младший бит), так и на то, что очередной буфер заполнен, ну и сбросить флаг ожидающего прерывания. Т.е. код обработчика вырождается в данном случае в такую конструкцию:

Код: Выделить всё

volatile uint32_t g_channel_next = 1;
void DMA_CH0_IRQHandler() {
 ++g_channel_next;
 DMA->CH[0].INT_CLEAR = DMA_CH_INT_CLEAR_CH_END_Msk;
}
Т.е. минимизируется время, проводимое в обработчике прерывания.
durimar_13
Сообщения: 111
Зарегистрирован: 26 фев 2025, 13:06
Предприятие: Radioamateur
Откуда: Свердловская обл.

Re: Описание DMA в РП К1921ВГ1Т

Сообщение durimar_13 »

Добрый вечер!
RST - это так кнопку "RESET" на плате я назвал. Не сам придумал, увидел у кого то...
В отладке вот на этом месте виснет при страте:
while(1) // вечный цикл
{
if(dma_flg) // TODO: Виснет в этом месте, требуется RST! В чем дело?
{
dma_flg = 0;
if(samples_count >= nsamples)
{
С уважением, Виктор.
durimar_13
Сообщения: 111
Зарегистрирован: 26 фев 2025, 13:06
Предприятие: Radioamateur
Откуда: Свердловская обл.

Re: Описание DMA в РП К1921ВГ1Т

Сообщение durimar_13 »

За пример кода спасибо. Красиво и понятно... . :)
С уважением, Виктор.
Мерседес
Сообщения: 37
Зарегистрирован: 05 авг 2026, 12:53
Предприятие: Каскад

Re: Описание DMA в РП К1921ВГ1Т

Сообщение Мерседес »

извините. начал писать сообщение, но не понял как его удалить.
Последний раз редактировалось Мерседес 07 авг 2026, 15:39, всего редактировалось 2 раза.
durimar_13
Сообщения: 111
Зарегистрирован: 26 фев 2025, 13:06
Предприятие: Radioamateur
Откуда: Свердловская обл.

Re: Описание DMA в РП К1921ВГ1Т

Сообщение durimar_13 »

Я так понимаю, в Вашем сообщении должно быть:
1: adc_res_buf0
2: adc_res_buf1
3: adc_res_buf0
4: adc_res_buf1
....
С уважением, Виктор.
RabidRabbit
Сообщения: 259
Зарегистрирован: 10 июн 2025, 12:11
Предприятие: HomeWork

Re: Описание DMA в РП К1921ВГ1Т

Сообщение RabidRabbit »

durimar_13 писал(а): 07 авг 2026, 15:04 RST - это так кнопку "RESET" на плате я назвал. Не сам придумал, увидел у кого то...
В отладке вот на этом месте виснет при страте:
Попробуйте всё же сброс периферии через регистры RCU->RSTDIS*
Ответить

Вернуться в «32-разрядные микроконтроллеры»