stm32 hal库uart使用 DMA中断只能发送一次的问题

1.stm32 uart使用DMA,无论发送还是接收都各自有一个数据流中断。这个数据流中断是框架代码不必过多关心。

2.使用了DMA后,uart的global中断是否要使用?标准做法是在cubemx上要勾选的,不然,就会产生只能发送一次的问题。

问题的原因?

我相信这是hal库的问题,理论上讲有一个数据流中断就可以了。实际上只发送一次的原因是在第二次调用 HAL_UART_Transmit_DMA时 huart->gState==HAL_UART_STATE_BUSY

解决办法 :

1.比较直接的做法是在调用HAL_UART_Transmit_DMA前,将huart->gState= HAL_UART_STATE_READY.

2.比较优雅的做法:开启uart的global中断,这中断中

HAL_UART_IRQHandler->UART_EndTransmit_IT.后面的函数会在dma发送完成后,将huart->gState= HAL_UART_STATE_READY

备注:

一般情况uart dma发送选择normal模式(只作用一次),接收采用circular模式(连接作用)。

如果想一直发送和接收可以采用以下两种办法

1.开启uart global中断,开启UART_IT_IDLE中断使能。在idle中断处理时,重启调用HAL_UART_Transmit_DMA发送。

2.在HAL_UART_RxCpltCallback回调处理中调用HAL_UART_Transmit_DMA。DMA发送注意增加小的延时

circular模式的 ***CpltCallback回调才有用,normal模式不使用回调。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面给出基于STM32 HAL库UART中断形式的发送函数示例。 注意事项: - 使用前请确保已经初始化了UART。 - 建议在使用前先判断一次是否可发送,避免发送堵塞。 - 本例采用了DMA方式发送,需要提前配置好DMA。 示例代码如下: ```c void UART_DMA_Send_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) { uint32_t *tmp; uint16_t tmp1 = 0; uint32_t tmpisr = DISABLE; tmp = (uint32_t*)pData; /* Disable the UART DMA Tx request */ huart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAT); /* Configure the DMA Tx interrupt */ /* Configure the DMA Tx interrupt */ tmpisr = __HAL_UART_DMA_GET_IT_SOURCE(huart, UART_DMA_TX_IT); if(tmpisr == SET) { __HAL_DMA_DISABLE_IT(huart->hdmatx, DMA_IT_TC | DMA_IT_HT | DMA_IT_TE); /* Set the DMA Tx transfer complete callback */ huart->hdmatx->XferCpltCallback = NULL; /* Set the DMA Tx transfer half complete callback */ huart->hdmatx->XferHalfCpltCallback = NULL; /* Set the DMA error callback */ huart->hdmatx->XferErrorCallback = NULL; /* Set the DMA abort callback */ huart->hdmatx->XferAbortCallback = NULL; /* Clear the DMA transfer complete flag */ __HAL_DMA_CLEAR_FLAG(huart->hdmatx, __HAL_DMA_GET_TC_FLAG_INDEX(huart->hdmatx)); /* Clear the DMA transfer half complete flag */ __HAL_DMA_CLEAR_FLAG(huart->hdmatx, __HAL_DMA_GET_HT_FLAG_INDEX(huart->hdmatx)); /* Clear the DMA transfer error flag */ __HAL_DMA_CLEAR_FLAG(huart->hdmatx, __HAL_DMA_GET_TE_FLAG_INDEX(huart->hdmatx)); } /* Enable the UART DMA Tx request */ huart->Instance->CR3 |= USART_CR3_DMAT; /* Enable the DMA Tx Channel */ HAL_DMA_Start_IT(huart->hdmatx, (uint32_t)tmp, (uint32_t)&huart->Instance->TDR, Size); /* Enable the DMA channel IRQ Channel */ HAL_NVIC_EnableIRQ(huart->hdmatx->IRQn); tmp1 = huart->TxXferSize; /* Check if a non-blocking transfer is ongoing or not */ if (huart->gState == HAL_UART_STATE_BUSY_TX) { return; } /* If it is a put buffer */ if (huart->Init.WordLength == UART_WORDLENGTH_9B) { while (Size--) { huart->pTxBuffPtr[tmp1++] = (*tmp & (uint32_t)0x01FF); tmp++; } } else { while (Size--) { huart->pTxBuffPtr[tmp1++] = (*tmp & (uint8_t)0xFF); tmp++; } } huart->TxXferSize = tmp1; huart->TxXferCount = tmp1; /* Process Unlocked */ __HAL_UNLOCK(huart); /* Enable the UART Transmit data register empty interrupt */ __HAL_UART_ENABLE_IT(huart, UART_IT_TXE); } ``` 以上是基于HAL库UART中断形式的发送函数示例,由于不同版本的HAL库实现细节有所不同,因此具体实现可能会有所差异。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值