STM32 HAL library function - HAL_UART_Receive_IT() detailed explanation

function source code

/**
  * @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;
  }
}

Detailed explanation of function usage

HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
  • huart: UART handle, pointing to the UART peripheral to be used.
  • pData: Pointer to the data buffer, used to store the received data.
  • Size: Number of data elements (u8 or u16) to receive.

The return value type is HAL_StatusTypeDef, indicating the status of the function execution. Possible return values ​​are:

  • HAL_OK: The function executes successfully.
  • HAL_ERROR: An error occurred during function execution.
  • HAL_BUSY: The receiving process is already in progress and the function cannot be executed.

When using this function, you need to follow the steps below:

  1. Create a UART_HandleTypeDeftype of structure variable and initialize it, including configuring the parameters of the UART peripheral (such as baud rate, word length, parity, etc.).
  2. Create a data buffer for storing received data.
  3. Call HAL_UART_Receive_ITthe function, passing in the UART handle, data buffer pointer and the amount of data to receive as parameters.
  4. Determine whether the operation was successful based on the return value of the function.

During the execution of the function, a series of checks will be carried out, including checking whether the receiving process is already in progress, checking whether the data buffer pointer and data size are legal, etc. If the check fails, the function returns an appropriate error status.

It should be noted that this function performs receiving operation in interrupt mode, so when data is received, an interrupt will be triggered, and data processing will be performed through the interrupt service function.

function line by line

  • HAL_UART_Receive_ITThe function is used to receive a certain amount of data in interrupt mode.
  • First, the function checks whether the receiving process is already in progress, and if so, returns a busy status.
  • Next, the function checks whether the data buffer pointer and data size passed in are legal, and if not, returns an error status.
  • pDataIf 9-bit/no-parity transfer is used, and the word length of the received data is configured as 9 bits (M1-M0 = 01), the buffer pointer is required to be aligned on u16 boundaries, because the data received from the RDR register will be passed through the u16 type to process. Returns an error status if the alignment is incorrect.
  • Set Receive Type to Standard Receive.
  • For non-LPUART instances, check if the RTOEN bit of the USART is set. If the RTOEN bit is set, the UART receive timeout interrupt is enabled.
  • Finally, the calling UART_Start_Receive_ITfunction initiates the receive operation and returns the appropriate status value.
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; // 返回忙碌状态
  }
}

Guess you like

Origin blog.csdn.net/AnChenliang_1002/article/details/131783668