Top.Mail.Ru
Уведомления
Очистить все

[Решено] UART по DMA

(@marat)
Level 1

Принимаю побайтно через HAL_UART_Receive_DMA(&huart1, index_uin, 1), настройки DMA "стандартные":

/* Peripheral DMA init*/

hdma_usart1_tx.Instance = DMA1_Channel4;
hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart1_tx.Init.MemInc = DMA_MINC_DISABLE; //ENABLE;
hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart1_tx.Init.Mode = DMA_NORMAL;
hdma_usart1_tx.Init.Priority = DMA_PRIORITY_HIGH;//LOW;
HAL_DMA_Init(&hdma_usart1_tx);

__HAL_LINKDMA(huart,hdmatx,hdma_usart1_tx);

hdma_usart1_rx.Instance = DMA1_Channel5;
hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart1_rx.Init.MemInc = DMA_MINC_DISABLE; //ENABLE;
hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart1_rx.Init.Mode = DMA_NORMAL;
hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW;
HAL_DMA_Init(&hdma_usart1_rx);

__HAL_LINKDMA(huart,hdmarx,hdma_usart1_rx);

однако отослать также побайтно не могу. Уходит только байт. Адреса приема и посылки инкрементирую в прерываниях:

void DMA1_Channel4_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel4_IRQn 0 */

//уход!

/* USER CODE END DMA1_Channel4_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart1_tx);
/* USER CODE BEGIN DMA1_Channel4_IRQn 1 */

delta_b--;
if ((index_bout - mass_cmx) == bufer_cmx) index_bout = mass_cmx;
else index_bout++;

/* USER CODE END DMA1_Channel4_IRQn 1 */
}
void DMA1_Channel5_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel5_IRQn 0 */

//приход!

/* USER CODE END DMA1_Channel5_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart1_rx);

/* USER CODE BEGIN DMA1_Channel5_IRQn 1 */

if ((index_uin - mass_u) == bufer_u) index_uin = mass_u;
else index_uin++;

delta_u++;
if (delta_u != bufer_u) HAL_UART_Receive_DMA(&huart1, index_uin, 1); //перезапуск !

/* USER CODE END DMA1_Channel5_IRQn 1 */
}
Перезапускаю передачу

HAL_UART_Transmit_DMA(&huart1, index_bout, 1);

Короче 4 канал DMA1 затыкается после первой отправки и это прерываение больше не работает. В чем может быть дело?

Цитата
Создатель темы Размещено : 12.04.2016 18:32
Aveal
(@aveal)
Top level Admin

А когда именно происходит повторный вызов функции отправки?

ОтветитьЦитата
Размещено : 12.04.2016 18:37
(@marat)
Level 1

вызываю из mail

if (delta_b) HAL_UART_Transmit_DMA(&huart1, index_bout, 1); //отправляем по УСАРТ

ОтветитьЦитата
Создатель темы Размещено : 12.04.2016 18:41
(@marat)
Level 1

в цикле while(1)

ОтветитьЦитата
Создатель темы Размещено : 12.04.2016 18:54
Aveal
(@aveal)
Top level Admin

Ну получается, что повторная отправка может быть запущена до того, как предыдущая завершилась.

ОтветитьЦитата
Размещено : 12.04.2016 19:28
(@marat)
Level 1

нет, проверял по программным флагам

ОтветитьЦитата
Создатель темы Размещено : 12.04.2016 19:34
(@marat)
Level 1

спасибо за помощь.
может для запуска есть еще какие-либо условия. После инициализации ведь первое прерывание на отправку срабатывает.

ОтветитьЦитата
Создатель темы Размещено : 12.04.2016 19:38
Aveal
(@aveal)
Top level Admin

Я думаю все-таки нужно добавить флаг точь-в-точь как статье про SPI и DMA и повторную передачу вызывать только после гарантированного окончания. В данном варианте этого нет.

Все остальные настройки вроде бы правильные.

ОтветитьЦитата
Размещено : 12.04.2016 19:55
Поделиться: