各位好,最近调试基于HAL库的STM32L051 USART程序,用官方给的USARTDMA程序,USART发送给模块指令后经常只能接收到一个字节的数据,偶尔会接收外字节数据,DMA发送接收函数如下:
/**
* @brief Send an amount of data in DMA mode
* @param huart: uart handle
* @param pData: pointer to data buffer
* @param Size: amount of data to be sent
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
uint32_t *tmp;
if((huart->State == HAL_UART_STATE_READY) || (huart->State == HAL_UART_STATE_BUSY_RX))
{
if((pData == NULL ) || (Size == 0))
{
return HAL_ERROR;
}
/* Process Locked */
__HAL_LOCK(huart);
huart->pTxBuffPtr = pData;
huart->TxXferSize = Size;
huart->TxXferCount = Size;
huart->ErrorCode = HAL_UART_ERROR_NONE;
/* Check if a receive process is ongoing or not */
//if(huart->State == HAL_UART_STATE_BUSY_RX)
{
// huart->State = HAL_UART_STATE_BUSY_TX_RX;
}
// else
{
huart->State = HAL_UART_STATE_BUSY_TX;
}
/* Set the UART DMA transfert 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;
/* Enable the UART transmit DMA Stream */
tmp = (uint32_t*)&pData;
HAL_DMA_Start_IT(huart->hdmatx, *(uint32_t*)tmp, (uint32_t)&huart->Instance->TDR, 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 */
huart->Instance->CR3 |= USART_CR3_DMAT;
/* Process Unlocked */
__HAL_UNLOCK(huart);
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
/**
* @brief Receive an amount of data in DMA mode
* @param huart: uart handle
* @param pData: pointer to data buffer
* @param Size: amount of data to be received
* @NOTE When the UART parity is enabled (PCE = 1) the data received contain the parity bit.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
uint32_t *tmp;
if((huart->State == HAL_UART_STATE_READY) || (huart->State == HAL_UART_STATE_BUSY_TX))
{
if((pData == NULL ) || (Size == 0))
{
return HAL_ERROR;
}
/* Process Locked */
__HAL_LOCK(huart);
huart->pRxBuffPtr = pData;
huart->RxXferSize = Size;
huart->ErrorCode = HAL_UART_ERROR_NONE;
/* Check if a transmit process is ongoing or not */
if(huart->State == HAL_UART_STATE_BUSY_TX)
{
huart->State = HAL_UART_STATE_BUSY_TX_RX;
}
else
{
huart->State = HAL_UART_STATE_BUSY_RX;
}
/* Set the UART DMA transfert complete callback */
huart->hdmarx->XferCpltCallback = UART_DMAReceiveCplt;
/* Set the UART DMA Half transfer complete callback */
huart->hdmarx->XferHalfCpltCallback = UART_DMARxHalfCplt;
/* Set the DMA error callback */
huart->hdmarx->XferErrorCallback = UART_DMAError;
/* Enable the DMA Stream */
tmp = (uint32_t*)&pData;
HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->RDR, *(uint32_t*)tmp, Size);
/* Enable the DMA transfer for the receiver request by setting the DMAR bit
in the UART CR3 register */
huart->Instance->CR3 |= USART_CR3_DMAR;
/* Process Unlocked */
__HAL_UNLOCK(huart);
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
/**
* @brief Pauses the DMA Transfer.
* @param huart: UART handle
* @retval None
*/
HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart)
{
/* Process Locked */
__HAL_LOCK(huart);
if(huart->State == HAL_UART_STATE_BUSY_TX)
{
/* Disable the UART DMA Tx request */
huart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAT);
}
else if(huart->State == HAL_UART_STATE_BUSY_RX)
{
/* Disable the UART DMA Rx request */
huart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAR);
}
else if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
{
/* Disable the UART DMA Tx request */
huart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAT);
/* Disable the UART DMA Rx request */
huart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAR);
}
/* Process Unlocked */
__HAL_UNLOCK(huart);
return HAL_OK;
}
/**
* @brief Send an amount of data in DMA mode
* @param huart: uart handle
* @param pData: pointer to data buffer
* @param Size: amount of data to be sent
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
uint32_t *tmp;
if((huart->State == HAL_UART_STATE_READY) || (huart->State == HAL_UART_STATE_BUSY_RX))
{
if((pData == NULL ) || (Size == 0))
{
return HAL_ERROR;
}
/* Process Locked */
__HAL_LOCK(huart);
huart->pTxBuffPtr = pData;
huart->TxXferSize = Size;
huart->TxXferCount = Size;
huart->ErrorCode = HAL_UART_ERROR_NONE;
/* Check if a receive process is ongoing or not */
//if(huart->State == HAL_UART_STATE_BUSY_RX)
{
// huart->State = HAL_UART_STATE_BUSY_TX_RX;
}
// else
{
huart->State = HAL_UART_STATE_BUSY_TX;
}
/* Set the UART DMA transfert 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;
/* Enable the UART transmit DMA Stream */
tmp = (uint32_t*)&pData;
HAL_DMA_Start_IT(huart->hdmatx, *(uint32_t*)tmp, (uint32_t)&huart->Instance->TDR, 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 */
huart->Instance->CR3 |= USART_CR3_DMAT;
/* Process Unlocked */
__HAL_UNLOCK(huart);
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
/**
* @brief Receive an amount of data in DMA mode
* @param huart: uart handle
* @param pData: pointer to data buffer
* @param Size: amount of data to be received
* @note When the UART parity is enabled (PCE = 1) the data received contain the parity bit.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
uint32_t *tmp;
if((huart->State == HAL_UART_STATE_READY) || (huart->State == HAL_UART_STATE_BUSY_TX))
{
if((pData == NULL ) || (Size == 0))
{
return HAL_ERROR;
}
/* Process Locked */
__HAL_LOCK(huart);
huart->pRxBuffPtr = pData;
huart->RxXferSize = Size;
huart->ErrorCode = HAL_UART_ERROR_NONE;
/* Check if a transmit process is ongoing or not */
if(huart->State == HAL_UART_STATE_BUSY_TX)
{
huart->State = HAL_UART_STATE_BUSY_TX_RX;
}
else
{
huart->State = HAL_UART_STATE_BUSY_RX;
}
/* Set the UART DMA transfert complete callback */
huart->hdmarx->XferCpltCallback = UART_DMAReceiveCplt;
/* Set the UART DMA Half transfer complete callback */
huart->hdmarx->XferHalfCpltCallback = UART_DMARxHalfCplt;
/* Set the DMA error callback */
huart->hdmarx->XferErrorCallback = UART_DMAError;
/* Enable the DMA Stream */
tmp = (uint32_t*)&pData;
HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->RDR, *(uint32_t*)tmp, Size);
/* Enable the DMA transfer for the receiver request by setting the DMAR bit
in the UART CR3 register */
huart->Instance->CR3 |= USART_CR3_DMAR;
/* Process Unlocked */
__HAL_UNLOCK(huart);
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
/**
* @brief Pauses the DMA Transfer.
* @param huart: UART handle
* @retval None
*/
HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart)
{
/* Process Locked */
__HAL_LOCK(huart);
if(huart->State == HAL_UART_STATE_BUSY_TX)
{
/* Disable the UART DMA Tx request */
huart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAT);
}
else if(huart->State == HAL_UART_STATE_BUSY_RX)
{
/* Disable the UART DMA Rx request */
huart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAR);
}
else if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
{
/* Disable the UART DMA Tx request */
huart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAT);
/* Disable the UART DMA Rx request */
huart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAR);
}
/* Process Unlocked */
__HAL_UNLOCK(huart);
return HAL_OK;
}
|