Завершите работу с UART и DMA

Я пытаюсь использовать UART и DMA. Когда я вставляю вызов HAL_Delay() в USART3_IRQHandler(), программа зависает в HAL_Delay(). Прерывание SysTick больше не вызывается. Я не понимаю?

int main(void)
{
    ...
  MX_DMA_Init();
  MX_USART3_UART_Init();
  uint32_t nextCall = uwTick;
  while (1)
  {
     if (nextCall < uwTick) {
        __HAL_UART_ENABLE_IT(&huart3, UART_IT_IDLE);
        HAL_UART_Transmit_DMA( &huart3, dataTx, sizeof( dataTx ) ); 
        nextCall = uwTick + 1000;
     }
  }
}

void USART3_IRQHandler(void)
{
    HAL_UART_IRQHandler(&huart3);
    if (( USART3->SR & UART_IT_IDLE) != 0 )
    {
        __HAL_UART_CLEAR_IDLEFLAG( &huart3 );
        HAL_UART_DMAStop(&huart3);
        uint8_t data_length  = sizeof( dataRx ) - __HAL_DMA_GET_COUNTER(&hdma_usart3_rx);
        memset( dataRx,0,sizeof( dataRx ));
        HAL_UART_Receive_DMA(&huart3, (uint8_t*)dataRx, sizeof( dataRx ));
        HAL_Delay( 1 );
        //  Delay() does not return
    }
}

person YvonBlais    schedule 03.06.2020    source источник
comment
Там все неправильно. Вы должны выбрать Interrupt или DMA. Вы не можете начать прием DMA в прерывании UART.   -  person 0___________    schedule 03.06.2020


Ответы (1)


Абстрагирование от совершенно неправильного кода UART HAL_Delay, который невозможно исправить, для работы в контексте прерывания требует, чтобы приоритет прерывания SYSTICK был выше, чем прерывание UART. В противном случае она не вызывается, внутренний счетчик не увеличивается и функция завершается в мертвом цикле.

person 0___________    schedule 03.06.2020