ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Пятница
10 мая
1194655 Топик полностью
Kceния (31.03.2022 13:41, просмотров: 508) ответил Argon на По HALу STM32 подскажите, плиз, а то напрочь все забыл за три месяца... Можно ли настроить передачу UART через DMA таким образом, чтобы подкидывать данных в буфер по мере их появления и чтоб DMA их само отправляло?
STM32'у кольцевой буфер не нужен :), т.к. у него существует аппаратное прерывание в середине DMA-буфера. А потому возможно использовать непрерывный/циклический режим приема/передачи, успевая в обработчике этого прерывания заполнять первую половину DMA-буфера новыми данными или забирать их оттуда (в зависимости от того, на прием или передачу тот буфера работает). Что касается HAL'а, то там DMA-прерывания уже имплементированы в функции работы с периферией. Например: 

ConvCpltCallback(...); // ADC conversion complete callback

ConvHalfCpltCallback(...); // ADC conversion DMA half-transfer callback

В таких случаях никого программирования DMA-прерываний от программиста не требуется, а достаточно лишь употребить эти функции в программном коде (строго соблюдая синтаксис их параметров), чтобы нужные прерывания были разрешены и эти функции вызывали. Скажем, если вы использовали в своей программе функцию ConvHalfCpltCallback, то и прерывание на середине DMA-буфера будет автоматически включено при инициализации ADC. Аналогично этому, использование функции ConvCpltCallback разрешает прерывание по концу DMA-буфера. При использовании обеих этих функций тактика такая: в первой функции забираю оцифрованные ADC'ом данные из 1-ой половины буфера, а во второй функции забираю данные из 2-ой половины буфера. Причем оцифровка данных идет непрерывно в циклическом режиме без останова на отсос данных.

Рассказываю это на примере ADC, поскольку сама это делала, но полагаю, что в случае SPI и UART механизм работает точно так же. Например, для UART'а в HAL'е тоже имеются зарезервированные функции с именами:

RxCpltCallback

RxHalfCpltCallback

- для приема и

TxCpltCallback

TxHalfCpltCallback

- для передачи.