【STM32】HAL库学习 2—hal_uart

目录

1 串口查询模式

        HAL_UART_Transmit

        HAL_UART_Receive 

 2 串口中断模式

        HAL_UART_Transmit_IT 

        HAL_UART_Receive_IT

        HAL_UART_RxCpltCallback

3 串口DMA模式

        HAL_UART_Transmit_DMA

        HAL_UART_Receive_DMA


1 串口查询模式

        HAL_UART_Transmit

/**
  * @brief 以阻塞模式发送一定量的数据。
  * @注 当UART奇偶校验未启用(PCE = 0),且字长被配置为9位(M1 - M0 = 01)时,发送的数据被处理为一组u16。在这种情况下,Size必须表示通过pData提供的u16的数量
  * @param huart 指向UART_HandleTypeDef结构的指针,该结构包含指定UART模块的配置信息。
  * @param pData 指向数据缓冲区指针(u8或u16数据元素)。
  * @param Size发送的数据元素的数量(u8或u16)。
  * @param Timeout 超时时间,单位是ms
  * @retval HAL状态
  */

        Definition at line 1135 of file stm32f4xx_hal_uart.c.

HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
  const uint8_t  *pdata8bits;
  const uint16_t *pdata16bits;
  uint32_t tickstart = 0U;
 
  /* Check that a Tx process is not already ongoing */
  if (huart->gState == HAL_UART_STATE_READY)
  {
    if ((pData == NULL) || (Size == 0U))
    {
      return  HAL_ERROR;
    }
 
    /* Process Locked */
    __HAL_LOCK(huart);
 
    huart->ErrorCode = HAL_UART_ERROR_NONE;
    huart->gState = HAL_UART_STATE_BUSY_TX;
 
    /* Init tickstart for timeout management */
    tickstart = HAL_GetTick();
 
    huart->TxXferSize = Size;
    huart->TxXferCount = Size;
 
    /* In case of 9bits/No Parity transfer, pData needs to be handled as a uint16_t pointer */
    if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
    {
      pdata8bits  = NULL;
      pdata16bits = (const uint16_t *) pData;
    }
    else
    {
      pdata8bits  = pData;
      pdata16bits = NULL;
    }
 
    /* Process Unlocked */
    __HAL_UNLOCK(huart);
 
    while (huart->TxXferCount > 0U)
    {
      if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
      {
        return HAL_TIMEOUT;
      }
      if (pdata8bits == NULL)
      {
        huart->Instance->DR = (uint16_t)(*pdata16bits & 0x01FFU);
        pdata16bits++;
      }
      else
      {
        huart->Instance->DR = (uint8_t)(*pdata8bits & 0xFFU);
        pdata8bits++;
      }
      huart->TxXferCount--;
    }
 
    if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
    {
      return HAL_TIMEOUT;
    }
 
    /* At end of Tx process, restore huart->gState to Ready */
    huart->gState = HAL_UART_STATE_READY;
 
    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}

        HAL_UART_Receive 

/**
  * @brief 在阻塞模式下接收一定量的数据。
  * @注 当UART奇偶校验未启用(PCE = 0),且字长被配置为9位(M1 - M0 = 01)时,接收的数据被处理为一组u16。在这种情况下,Size必须通过pData表示可用的u16的数量。
  * @param huart 指向 UART_HandleTypeDef 结构的指针,该结构包含指定 UART 模块的配置信息。
  * @param pData 指向数据缓冲区的指针(u8或u16数据元素)。
  * @param Size接收的数据元素的数量(u8或u16)。
  * @param Timeout 超时时间
  * @retval HAL 状态
  */
 

        Definition at line 1223 of file stm32f4xx_hal_uart.c.

HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
  uint8_t  *pdata8bits;
  uint16_t *pdata16bits;
  uint32_t tickstart = 0U;

  /* Check that a Rx process is not already ongoing */
  if (huart->RxState == HAL_UART_STATE_READY)
  {
    if ((pData == NULL) || (Size == 0U))
    {
      return  HAL_ERROR;
    }

    /* Process Locked */
    __HAL_LOCK(huart);

    huart->ErrorCode = HAL_UART_ERROR_NONE;
    huart->RxState = HAL_UART_STATE_BUSY_RX;
    huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;

    /* Init tickstart for timeout management */
    tickstart = HAL_GetTick();

    huart->RxXferSize = Size;
    huart->RxXferCount = Size;

    /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
    if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
    {
      pdata8bits  = NULL;
      pdata16bits = (uint16_t *) pData;
    }
    else
    {
      pdata8bits  = pData;
      pdata16bits = NULL;
    }

    /* Process Unlocked */
    __HAL_UNLOCK(huart);

    /* Check the remain data to be received */
    while (huart->RxXferCount > 0U)
    {
      if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
      {
        return HAL_TIMEOUT;
      }
      if (pdata8bits == NULL)
      {
        *pdata16bits = (uint16_t)(huart->Instance->DR & 0x01FF);
        pdata16bits++;
      }
      else
      {
        if ((huart->Init.WordLength == UART_WORDLENGTH_9B) || ((huart->Init.WordLength == UART_WORDLENGTH_8B) && (huart->Init.Parity == UART_PARITY_NONE)))
        {
          *pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
        }
        else
        {
          *pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
        }
        pdata8bits++;
      }
      huart->RxXferCount--;
    }

    /* At end of Rx process, restore huart->RxState to Ready */
    huart->RxState = HAL_UART_STATE_READY;

    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}

eg:

char str[12] = "Hello World\n";
char recv_buf[12] = {0};
HAL_UART_Transmit(&huart1, (uint8_t*)str, 12, 0xFFFF);
    //接收12个字节的数据,不超时
    if(HAL_OK == HAL_UART_Receive(&huart1, (uint8_t*)recv_buf, 12, 0xFFFF))
    {
      //将接收到的数据发送
      HAL_UART_Transmit(&huart1, (uint8_t*)recv_buf, 12, 0xFFFF);
    }

&huart1:串口句柄地址;

(uint8_t*):

        1字节     uint8_t
        2字节     uint16_t
        4字节     uint32_t
        8字节     uint64_t

0xFFFF:不超时。

 2 串口中断模式

        HAL_UART_Transmit_IT 

/**
  * @brief 以非阻塞模式发送一定量的数据。
  * @注 当UART奇偶校验未启用(PCE = 0),且字长被配置为9位(M1 - M0 = 01)时,发送的数据被处理为一组u16。在这种情况下,Size必须表示通过pData提供的u16的数量。
  * @param huart 指向UART_HandleTypeDef结构的指针,该结构包含
  * 指定UART模块的配置信息。
  * @param pData 指向数据缓冲区的指针(u8或u16数据元素)。
  * @param Size 要发送的数据元素的数量(u8或u16)。
  * @retval HAL状态
  */

         Definition at line 1314 of file stm32f4xx_hal_uart.c.

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;
    }
 
    /* Process Locked */
    __HAL_LOCK(huart);
 
    huart->pTxBuffPtr = pData;
    huart->TxXferSize = Size;
    huart->TxXferCount = Size;
 
    huart->ErrorCode = HAL_UART_ERROR_NONE;
    huart->gState = HAL_UART_STATE_BUSY_TX;
 
    /* Process Unlocked */
    __HAL_UNLOCK(huart);
 
    /* Enable the UART Transmit data register empty Interrupt */
    __HAL_UART_ENABLE_IT(huart, UART_IT_TXE);
 
    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}

        HAL_UART_Receive_IT

 /**
  * @brief 在非阻塞模式下接收一定量的数据。
  * @注 当UART奇偶校验未启用(PCE = 0),且字长被配置为9位(M1 - M0 = 01)时,接收的数据被处理为一组u16。在这种情况下,Size必须通过pData表示可用的u16的数量。
  * @param huart 指向UART_HandleTypeDef结构的指针,该结构包含
  * 指定UART模块的配置信息。
  * @param pData 指向数据缓冲区的指针(u8或u16数据元素)。
  * @param Size 要接收的数据元素的数量(u8或u16)。
  * @retval HAL状态
  */

        Definition at line 1359 of file stm32f4xx_hal_uart.c.

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;
    }
 
    /* Process Locked */
    __HAL_LOCK(huart);
 
    /* Set Reception type to Standard reception */
    huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
 
    return (UART_Start_Receive_IT(huart, pData, Size));
  }
  else
  {
    return HAL_BUSY;
  }
}

        HAL_UART_RxCpltCallback

/**
  * @brief Rx 转移完成的回调。
  * @param huart 指向UART_HandleTypeDef结构的指针,其中包含指定UART模块的配置信息。
  * @retval 无
  */

        Definition at line 2618 of file stm32f4xx_hal_uart.c.

__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(huart);
  /* NOTE: This function should not be modified, when the callback is needed,
           the HAL_UART_RxCpltCallback could be implemented in the user file
   */
}

eg:

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint8_t hello[] = "USART1 is ready...\n";
uint8_t recv_buf[13] = {0};
/* USER CODE END 0 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	/* 判断是哪个串口触发的中断 */
	if(huart ->Instance == USART1)
	{
		//将接收到的数据发送
		HAL_UART_Transmit_IT(huart, (uint8_t*)recv_buf, 13);
		//重新使能串口接收中断
		HAL_UART_Receive_IT(huart, (uint8_t*)recv_buf, 13);
	}
}
int main(void)
{
  HAL_Init();
 
  SystemClock_Config();
 
  MX_GPIO_Init();
  MX_USART1_UART_Init();
 
  /* USER CODE BEGIN 2 */
  //使能串口中断接收
  HAL_UART_Receive_IT(&huart1, (uint8_t*)recv_buf, 13);
  //发送提示信息
  HAL_UART_Transmit_IT(&huart1, (uint8_t*)hello, sizeof(hello));
  /* USER CODE END 2 */
 
  while (1)
  {
  }
}

3 串口DMA模式

        HAL_UART_Transmit_DMA

 /**
  * @brief 以DMA模式发送一定量的数据。
  * @注 当UART奇偶校验未启用(PCE = 0),且字长被配置为9位(M1-M0 = 01)时,发送的数据被处理为一组u16。在这种情况下,Size必须表示通过pData提供的u16的数量。
  * @param huart 指向UART_HandleTypeDef结构的指针,该结构包含指定UART模块的配置信息。
  * @param pData 指向数据缓冲区的指针(u8或u16数据元素)。
  * @param Size 要发送的数据元素的数量(u8或u16)。
  * @retval HAL状态
  */

        Definition at line 1394 of file stm32f4xx_hal_uart.c.

HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size)
{
  const uint32_t *tmp;

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

    /* Process Locked */
    __HAL_LOCK(huart);

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

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

    /* Set the UART DMA transfer 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;

    /* Set the DMA abort callback */
    huart->hdmatx->XferAbortCallback = NULL;

    /* Enable the UART transmit DMA stream */
    tmp = (const uint32_t *)&pData;
    HAL_DMA_Start_IT(huart->hdmatx, *(const uint32_t *)tmp, (uint32_t)&huart->Instance->DR, Size);

    /* Clear the TC flag in the SR register by writing 0 to it */
    __HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);

    /* Process Unlocked */
    __HAL_UNLOCK(huart);

    /* Enable the DMA transfer for transmit request by setting the DMAT bit
       in the UART CR3 register */
    ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);

    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}

 eg:

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint8_t dat[] = "Hello, I am koko.\n";
/* USER CODE END 0 */
int main(void)
{
  HAL_Init();

  SystemClock_Config();

  MX_GPIO_Init();
  MX_USART1_UART_Init();

  /* USER CODE BEGIN 2 */
  HAL_UART_Transmit_DMA(&huart1, (uint8_t*)dat, sizeof(dat));
  /* USER CODE END 2 */

  while (1)
  {
  }
}

        HAL_UART_Receive_DMA

/**
  * @brief 在DMA模式下接收一定量的数据。
  * @注 当UART奇偶校验未启用(PCE = 0),且字长被配置为9位(M1-M0 = 01)时,接收的数据被处理为一组u16。在这种情况下,Size必须通过pData表示可用的u16的数量。
  * @param huart 指向 UART_HandleTypeDef 结构的指针,该结构包含指定 UART 模块的配置信息。
  * @param pData 指向数据缓冲区的指针(u8或u16数据元素)。
  * @param Size 要接收的数据元素的数量(u8或u16)。
  * @注意 当UART奇偶校验被启用时(PCE = 1),接收的数据包含奇偶校验位。
  * @retval HAL 状态
  */

        Definition at line 1462 of file stm32f4xx_hal_uart.c.

HAL_StatusTypeDef HAL_UART_Receive_DMA(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;
    }

    /* Process Locked */
    __HAL_LOCK(huart);

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

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

eg:

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint8_t dat[] = "Hello, I am koko.\n";
uint8_t recv_buf[13] = {0};		//串口接收缓冲区
/* USER CODE END 0 */
int main(void)
{
  HAL_Init();

  SystemClock_Config();

  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART1_UART_Init();

  /* USER CODE BEGIN 2 */
  HAL_UART_Transmit(&huart1, (uint8_t*)dat, sizeof(dat), 0xFFFF);
  HAL_UART_Receive_DMA(&huart1, recv_buf, 13);  //使能DMA接收
  /* USER CODE END 2 */

  while (1)
  {
  }
}
/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) 
{ 
	//将接收到的数据再发送
	HAL_UART_Transmit(&huart1,recv_buf,13, 0xFFFF);
}
/* USER CODE END 4 */
  • 6
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值