打印
[应用相关]

HAL_UART_Transmit_IT()详解

[复制链接]
659|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tpgf|  楼主 | 2023-8-30 16:28 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
函数源代码
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_t或uint16_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表示发送操作已成功启动。
————————————————
版权声明:本文为CSDN博主「乘凉~」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/AnChenliang_1002/article/details/131780092

使用特权

评论回复
沙发
zhuotuzi| | 2023-8-31 11:00 | 只看该作者
麻烦代码用代码框贴啊,这看着太累。

使用特权

评论回复
板凳
langgq| | 2023-8-31 19:44 | 只看该作者
函数返回HAL_OK表示发送操作已成功启动

使用特权

评论回复
地板
yangjiaxu| | 2023-8-31 21:17 | 只看该作者
串口中断算是基本操作了,这个用好了,比操作系统好用

使用特权

评论回复
5
Stahan| | 2023-9-2 22:41 | 只看该作者
不复杂的逻辑用中断完全够了

使用特权

评论回复
6
MessageRing| | 2023-9-3 21:52 | 只看该作者
边界对齐怎么判断的啊

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1931

主题

15650

帖子

12

粉丝