(HAL_UART_Transmit_DMA函数发送一次后就卡死的现象)STM32CUBEMX HAL库 USART+DMA+ESP8266模块透传,接收不定长数据的一些踩坑点

一、现象

我在使用HAL_UART_Transmit_DMA(&huart1,str,sizeof(str));函数循环发送数据时,发现这个函数只执行的一次,后面就再也不执行,而且该usart的发送功能也会失效。给我困扰很大

二、原因

HAL_UART_Transmit_DMA函数代码如下:我分析发现,调用一次HAL_UART_Transmit_DMA函数发送一次数据后,该usart句柄的状态:huart->gState就被设置成了HAL_UART_STATE_BUSY_TX(忙碌)状态。此后,下次再调用HAL_UART_Transmit_DMA函数时,如果是忙碌状态。会直接略过发送代码。因此需要更改huart->gState为HAL_UART_STATE_READY状态

HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size)
{
  const uint32_t *tmp;

  /* Check that a Tx process is not already ongoing */
  if (huart->gState == HAL_UART_STATE_READY)
  {
    if ((pData == NULL) || (Size == 0U))
    {
      return HAL_ERROR;
    }

    huart->pTxBuffPtr = pData;
    huart->TxXferSize = Size;
    huart->TxXferCount = Size;

    huart->ErrorCode = HAL_UART_ERROR_NONE;
    huart->gState = HAL_UART_STATE_BUSY_TX;

    /* Set the UART DMA transfer complete callback */
    huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt;

    /* Set the UART DMA Half transfer complete callback */
    huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt;

    /* Set the DMA error callback */
    huart->hdmatx->XferErrorCallback = UART_DMAError;

    /* Set the DMA abort callback */
    huart->hdmatx->XferAbortCallback = NULL;

    /* Enable the UART transmit DMA channel */
    tmp = (const uint32_t *)&pData;
    HAL_DMA_Start_IT(huart->hdmatx, *(const uint32_t *)tmp, (uint32_t)&huart->Instance->DR, Size);

    /* Clear the TC flag in the SR register by writing 0 to it */
    __HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);

    /* Enable the DMA transfer for transmit request by setting the DMAT bit
       in the UART CR3 register */
    ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);

    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}

三、解决方法

方法1:每次调用HAL_UART_Transmit_DMA函数发送前加上下列代码,手动修改usart的状态

 huart1.gState = HAL_UART_STATE_READY;
 hdma_usart1_tx.State = HAL_DMA_STATE_READY;
 __HAL_UNLOCK(&hdma_usart1_tx);

方法2:在cubemx中开启tx_dma的中断,我才这样会在HAL_DMA_IRQHandler函数中,自动处理usart的状态。

以上即为两种解决思路

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值