STM32 HAL库函数——HAL_UART_Transmit_IT()详解

函数源代码

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

    /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
       should be aligned on a u16 frontier, as data to be filled into TDR will be
       handled through a u16 cast. */
    if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
    {
    
    
      if ((((uint32_t)pData) & 1U) != 0U)
      {
    
    
        return  HAL_ERROR;
      }
    }

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

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

    /* Configure Tx interrupt processing */
    if (huart->FifoMode == UART_FIFOMODE_ENABLE)
    {
    
    
      /* Set the Tx ISR function pointer according to the data word length */
      if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
      {
    
    
        huart->TxISR = UART_TxISR_16BIT_FIFOEN;
      }
      else
      {
    
    
        huart->TxISR = UART_TxISR_8BIT_FIFOEN;
      }

      /* Enable the TX FIFO threshold interrupt */
      ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
    }
    else
    {
    
    
      /* Set the Tx ISR function pointer according to the data word length */
      if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
      {
    
    
        huart->TxISR = UART_TxISR_16BIT;
      }
      else
      {
    
    
        huart->TxISR = UART_TxISR_8BIT;
      }

      /* Enable the Transmit Data Register Empty interrupt */
      ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
    }

    return HAL_OK;
  }
  else
  {
    
    
    return HAL_BUSY;
  }
}

函数用法详解

HAL_UART_Transmit_IT函数的用法如下:

输入参数:

  • huart:指向UART句柄结构体的指针,用于指定要使用的UART外设。
  • pData:指向要发送数据缓冲区的指针,可以是uint8_t类型或uint16_t类型的数据。
  • Size:要发送的数据大小,以数据元素(uint8_tuint16_t)的数量表示。

返回值:

  • HAL_StatusTypeDef类型的返回值,表示函数的执行状态。可能的返回值包括:
    • HAL_OK:发送操作已成功启动。
    • HAL_BUSY:当前有正在进行的发送操作。
    • HAL_ERROR:传入的参数不合法。

函数的作用:

  • 以中断模式发送数据。函数会检查UART的状态,如果当前有正在进行的发送操作,则返回忙碌状态。然后,它会检查传入的数据缓冲区指针和数据大小是否合法,如果不合法,则返回错误状态。
  • 如果参数合法,函数会设置UART句柄结构体中的成员变量,并根据UART的FIFO模式和数据长度选择相应的中断服务程序的函数指针,并使能相应的中断。
  • 最后,函数返回状态值表示发送操作的启动状态。

使用该函数时,你需要先创建一个有效的UART句柄结构体,并将其作为第一个参数传递给函数。另外,你需要提供一个有效的数据缓冲区指针和数据大小。

在使用该函数之前,你需要先进行UART的初始化配置,包括波特率、数据位、停止位、奇偶校验等参数的设置。你还需要确保UART的中断已经正确配置,并实现相应的中断服务程序来处理发送完成和错误等事件。

函数功能

以上代码是HAL库中的HAL_UART_Transmit_IT函数,用于以中断模式发送数据。

HAL_UART_Transmit_IT函数的功能是以中断模式发送数据。它接受一个指向UART句柄结构体的指针 huart,一个指向要发送数据缓冲区的指针 pData,以及要发送的数据大小 Size

函数首先检查UART的状态,如果当前有正在进行的发送操作,则返回HAL_BUSY表示忙碌。然后,它检查传入的数据缓冲区指针和数据大小,如果它们不合法(为NULL或大小为0),则返回HAL_ERROR

接下来,函数设置UART句柄结构体中的一些成员变量,包括发送缓冲区指针、发送的数据大小、剩余待发送的数据大小、发送中断服务程序的函数指针,以及错误码和UART状态。

根据UART的FIFO模式和数据长度,函数选择相应的中断服务程序的函数指针,并使能相应的中断。如果FIFO模式使能,函数将使能TX FIFO阈值中断;如果FIFO模式未使能,函数将使能发送数据寄存器空中断。

最后,函数返回HAL_OK表示发送操作已成功启动。

总而言之,HAL_UART_Transmit_IT函数允许以中断模式发送数据,通过配置中断服务程序和使能相应的中断来实现数据的异步发送。这样可以避免阻塞主线程,提高系统的响应性能。

函数逐行解释

下面是对每一行代码的详细解释:

HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size)

这是函数的定义,它接受一个指向UART_HandleTypeDef结构体的指针 huart,一个指向要发送数据缓冲区的指针 pData,以及要发送的数据大小 Size。它返回一个HAL_StatusTypeDef类型的状态。

if (huart->gState == HAL_UART_STATE_READY)

这行代码检查UART的状态是否为HAL_UART_STATE_READY,即没有正在进行的发送过程。如果UART状态不是READY,表示当前有发送操作正在进行,函数将返回HAL_BUSY

if ((pData == NULL) || (Size == 0U))
{
    
    
  return HAL_ERROR;
}

这行代码检查要发送的数据缓冲区指针 pData 是否为NULL,以及发送的数据大小 Size 是否为0。如果是,则返回HAL_ERROR

if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
{
    
    
  if ((((uint32_t)pData) & 1U) != 0U)
  {
    
    
    return  HAL_ERROR;
  }
}

这段代码在使用9位数据长度和无奇偶校验的情况下,检查数据缓冲区指针 pData 是否按照u16的边界对齐。如果没有按照边界对齐,则返回HAL_ERROR

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

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

这些代码设置了UART句柄结构体中的一些成员变量,包括发送缓冲区指针 pTxBuffPtr、发送的数据大小 TxXferSize、剩余待发送的数据大小 TxXferCount、发送中断服务程序的函数指针 TxISR,以及错误码和UART状态。

if (huart->FifoMode == UART_FIFOMODE_ENABLE)
{
    
    
  if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
  {
    
    
    huart->TxISR = UART_TxISR_16BIT_FIFOEN;
  }
  else
  {
    
    
    huart->TxISR = UART_TxISR_8BIT_FIFOEN;
  }

  ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
}
else
{
    
    
  if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
  {
    
    
    huart->TxISR = UART_TxISR_16BIT;
  }
  else
  {
    
    
    huart->TxISR = UART_TxISR_8BIT;
  }

  ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
}

这部分代码根据UART的FIFO模式和数据长度设置中断服务程序的函数指针 TxISR,并使能相应的中断。如果FIFO模式使能,根据数据长度选择16位或8位的中断服务程序,并使能TX FIFO阈值中断。如果FIFO模式未使能,同样根据数据长度选择16位或8位的中断服务程序,并使能发送数据寄存器空中断。

最后,函数返回HAL_OK表示发送操作已成功启动。

猜你喜欢

转载自blog.csdn.net/AnChenliang_1002/article/details/131780092