打印
[应用相关]

HAL_UART_Receive_IT()详解

[复制链接]
199|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tpgf|  楼主 | 2023-8-30 17:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
函数源代码
/**
  * @brief Receive an amount of data in interrupt mode.
  * @NOTE   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
  *         the received data is handled as a set of u16. In this case, Size must indicate the number
  *         of u16 available through pData.
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
  *         address of user data buffer for storing data to be received, should be aligned on a half word frontier
  *         (16 bits) (as received data will be handled using u16 pointer cast). Depending on compilation chain,
  *         use of specific alignment compilation directives or pragmas might be required
  *         to ensure proper alignment for pData.
  * @param huart UART handle.
  * @param pData Pointer to data buffer (u8 or u16 data elements).
  * @param Size  Amount of data elements (u8 or u16) to be received.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
  /* Check that a Rx process is not already ongoing */
  if (huart->RxState == 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 received from RDR 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;
      }
    }

    /* Set Reception type to Standard reception */
    huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;

    if (!(IS_LPUART_INSTANCE(huart->Instance)))
    {
      /* Check that USART RTOEN bit is set */
      if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U)
      {
        /* Enable the UART Receiver Timeout Interrupt */
        ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RTOIE);
      }
    }

    return (UART_Start_Receive_IT(huart, pData, Size));
  }
  else
  {
    return HAL_BUSY;
  }
}



函数用法详解
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
1
huart:UART句柄,指向要使用的UART外设。
pData:指向数据缓冲区的指针,用于存储接收到的数据。
Size:要接收的数据元素(u8或u16)的数量。
返回值类型为HAL_StatusTypeDef,表示函数执行的状态。可能的返回值有:

HAL_OK:函数执行成功。
HAL_ERROR:函数执行过程中发生错误。
HAL_BUSY:接收过程已经在进行中,函数无法执行。
使用该函数时,需要按照以下步骤进行操作:

创建一个UART_HandleTypeDef类型的结构体变量,并对其进行初始化,包括配置UART外设的参数(如波特率、字长、奇偶校验等)。
创建一个数据缓冲区,用于存储接收到的数据。
调用HAL_UART_Receive_IT函数,传入UART句柄、数据缓冲区指针和要接收的数据数量作为参数。
根据函数的返回值判断操作是否成功。
在函数执行期间,会进行一系列的检查,包括检查接收过程是否已经在进行中、检查数据缓冲区指针和数据大小是否合法等。如果检查失败,函数会返回相应的错误状态。

需要注意的是,该函数是在中断模式下进行接收操作的,因此在接收到数据时会触发中断,并通过中断服务函数进行数据处理。

函数逐行解释
HAL_UART_Receive_IT函数用于在中断模式下接收一定量的数据。
首先,函数检查接收过程是否已经在进行中,如果是,则返回忙碌状态。
接下来,函数检查传入的数据缓冲区指针和数据大小是否合法,如果不合法,则返回错误状态。
如果使用9位/无奇偶校验传输,并且接收数据的字长配置为9位(M1-M0 = 01),则要求pData缓冲区指针按照u16边界对齐,因为从RDR寄存器接收的数据将通过u16类型进行处理。如果对齐不正确,则返回错误状态。
将接收类型设置为标准接收。
对于非LPUART实例,检查USART的RTOEN位是否设置。如果设置了RTOEN位,则使能UART接收超时中断。
最后,调用UART_Start_Receive_IT函数启动接收操作,并返回相应的状态值。
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
  /* Check that a Rx process is not already ongoing */
  if (huart->RxState == 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 received from RDR will be
       handled through a u16 cast. */
    if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) // 检查是否使用9位/无奇偶校验传输
    {
      if ((((uint32_t)pData) & 1U) != 0U) // 检查pData缓冲区指针是否按照u16边界对齐
      {
        return  HAL_ERROR; // 返回错误状态
      }
    }

    /* Set Reception type to Standard reception */
    huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; // 设置接收类型为标准接收

    if (!(IS_LPUART_INSTANCE(huart->Instance))) // 检查是否为LPUART实例
    {
      /* Check that USART RTOEN bit is set */
      if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U) // 检查USART的RTOEN位是否设置
      {
        /* Enable the UART Receiver Timeout Interrupt */
        ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RTOIE); // 使能UART接收超时中断
      }
    }

    return (UART_Start_Receive_IT(huart, pData, Size)); // 调用UART_Start_Receive_IT函数启动接收操作,并返回相应的状态值
  }
  else
  {
    return HAL_BUSY; // 返回忙碌状态
  }
}
————————————————
版权声明:本文为CSDN博主「乘凉~」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/AnChenliang_1002/article/details/131783668

使用特权

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

本版积分规则

1931

主题

15650

帖子

12

粉丝