回顾上一篇UART发送当中,已经讲解了如何实现UART的发送操作了,接下来这一篇将会继续讲解如何实现UART的接收操作。

  嵌入式开发中,UART串口通信协议是我们常用的通信协议之一,全称叫做通用异步收发传输器(Universal Asynchronous Receiver/Transmitter)。

  在UART详解中已经有了详细的说明,按照里面的说明即可。

  建议每次编写好一个相关功能且测试功能成功使用后,保存备份并压缩成一份Demo例程,方便日后有需要的时候可以直接使用。

  例如:

 

说明:

  如果有看过我写的UART发送的兄弟姐妹们应该会知道,在UART发送UART详解中的CubeMx配置都是一样的。

  但这一次不同,会在原本配置CubeMx的基础上,添加一些UART的中断配置来实现中断接收操作。

  会与上一篇UART发送的UART初始化有所不同,因为在这一篇我们开启了中断处理,简单了解一下即可。

  

  1. 1 UART_HandleTypeDef huart1;
  2. 2
  3. 3 /* USART1 init function */
  4. 4
  5. 5 void MX_USART1_UART_Init(void)
  6. 6 {
  7. 7
  8. 8 huart1.Instance = USART1;
  9. 9 huart1.Init.BaudRate = 115200;
  10. 10 huart1.Init.WordLength = UART_WORDLENGTH_8B;
  11. 11 huart1.Init.StopBits = UART_STOPBITS_1;
  12. 12 huart1.Init.Parity = UART_PARITY_NONE;
  13. 13 huart1.Init.Mode = UART_MODE_TX_RX;
  14. 14 huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  15. 15 huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  16. 16 if (HAL_UART_Init(&huart1) != HAL_OK)
  17. 17 {
  18. 18 Error_Handler();
  19. 19 }
  20. 20
  21. 21 }
  22. 22
  23. 23 void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
  24. 24 {
  25. 25
  26. 26 GPIO_InitTypeDef GPIO_InitStruct = {0};
  27. 27 if(uartHandle->Instance==USART1)
  28. 28 {
  29. 29 /* USER CODE BEGIN USART1_MspInit 0 */
  30. 30
  31. 31 /* USER CODE END USART1_MspInit 0 */
  32. 32 /* USART1 clock enable */
  33. 33 __HAL_RCC_USART1_CLK_ENABLE();
  34. 34
  35. 35 __HAL_RCC_GPIOA_CLK_ENABLE();
  36. 36 /**USART1 GPIO Configuration
  37. 37 PA9 ------> USART1_TX
  38. 38 PA10 ------> USART1_RX
  39. 39 */
  40. 40 GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
  41. 41 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  42. 42 GPIO_InitStruct.Pull = GPIO_PULLUP;
  43. 43 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  44. 44 GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
  45. 45 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  46. 46
  47. 47 /* USART1 interrupt Init */
  48. 48 HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
  49. 49 HAL_NVIC_EnableIRQ(USART1_IRQn);
  50. 50 /* USER CODE BEGIN USART1_MspInit 1 */
  51. 51
  52. 52 /* USER CODE END USART1_MspInit 1 */
  53. 53 }
  54. 54 }
  55. 55
  56. 56 void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
  57. 57 {
  58. 58
  59. 59 if(uartHandle->Instance==USART1)
  60. 60 {
  61. 61 /* USER CODE BEGIN USART1_MspDeInit 0 */
  62. 62
  63. 63 /* USER CODE END USART1_MspDeInit 0 */
  64. 64 /* Peripheral clock disable */
  65. 65 __HAL_RCC_USART1_CLK_DISABLE();
  66. 66
  67. 67 /**USART1 GPIO Configuration
  68. 68 PA9 ------> USART1_TX
  69. 69 PA10 ------> USART1_RX
  70. 70 */
  71. 71 HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
  72. 72
  73. 73 /* USART1 interrupt Deinit */
  74. 74 HAL_NVIC_DisableIRQ(USART1_IRQn);
  75. 75 /* USER CODE BEGIN USART1_MspDeInit 1 */
  76. 76
  77. 77 /* USER CODE END USART1_MspDeInit 1 */
  78. 78 }
  79. 79 }

UART init

  当USART1发生中断事件时,程序会进行该函数,所以我们会在这个函数编写好程序,来处理我们的中断事件。

  1. 1 /**
  2. 2 * @brief This function handles USART1 global interrupt.
  3. 3 */
  4. 4 void USART1_IRQHandler(void)
  5. 5 {
  6. 6 /* USER CODE BEGIN USART1_IRQn 0 */
  7. 7
  8. 8 /* USER CODE END USART1_IRQn 0 */
  9. 9 HAL_UART_IRQHandler(&huart1);
  10. 10 /* USER CODE BEGIN USART1_IRQn 1 */
  11. 11
  12. 12 /* USER CODE END USART1_IRQn 1 */
  13. 13 }

  该函数能够通过huart串口发送Size位pData数据。

  • huart    :选择用来发送的UART串口

  • pData   :指向将要发送的数据的指针

  • Size      :发送数据的大小

  • Timeout:超时时间

  

  1. 1 /**
  2. 2 * @brief Sends an amount of data in blocking mode.
  3. 3 * @param huart Pointer to a UART_HandleTypeDef structure that contains
  4. 4 * the configuration information for the specified UART module.
  5. 5 * @param pData Pointer to data buffer
  6. 6 * @param Size Amount of data to be sent
  7. 7 * @param Timeout Timeout duration
  8. 8 * @retval HAL status
  9. 9 */
  10. 10 HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
  11. 11 {
  12. 12 uint16_t *tmp;
  13. 13 uint32_t tickstart = 0U;
  14. 14
  15. 15 /* Check that a Tx process is not already ongoing */
  16. 16 if (huart->gState == HAL_UART_STATE_READY)
  17. 17 {
  18. 18 if ((pData == NULL) || (Size == 0U))
  19. 19 {
  20. 20 return HAL_ERROR;
  21. 21 }
  22. 22
  23. 23 /* Process Locked */
  24. 24 __HAL_LOCK(huart);
  25. 25
  26. 26 huart->ErrorCode = HAL_UART_ERROR_NONE;
  27. 27 huart->gState = HAL_UART_STATE_BUSY_TX;
  28. 28
  29. 29 /* Init tickstart for timeout managment */
  30. 30 tickstart = HAL_GetTick();
  31. 31
  32. 32 huart->TxXferSize = Size;
  33. 33 huart->TxXferCount = Size;
  34. 34 while (huart->TxXferCount > 0U)
  35. 35 {
  36. 36 huart->TxXferCount--;
  37. 37 if (huart->Init.WordLength == UART_WORDLENGTH_9B)
  38. 38 {
  39. 39 if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
  40. 40 {
  41. 41 return HAL_TIMEOUT;
  42. 42 }
  43. 43 tmp = (uint16_t *) pData;
  44. 44 huart->Instance->DR = (*tmp & (uint16_t)0x01FF);
  45. 45 if (huart->Init.Parity == UART_PARITY_NONE)
  46. 46 {
  47. 47 pData += 2U;
  48. 48 }
  49. 49 else
  50. 50 {
  51. 51 pData += 1U;
  52. 52 }
  53. 53 }
  54. 54 else
  55. 55 {
  56. 56 if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
  57. 57 {
  58. 58 return HAL_TIMEOUT;
  59. 59 }
  60. 60 huart->Instance->DR = (*pData++ & (uint8_t)0xFF);
  61. 61 }
  62. 62 }
  63. 63
  64. 64 if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
  65. 65 {
  66. 66 return HAL_TIMEOUT;
  67. 67 }
  68. 68
  69. 69 /* At end of Tx process, restore huart->gState to Ready */
  70. 70 huart->gState = HAL_UART_STATE_READY;
  71. 71
  72. 72 /* Process Unlocked */
  73. 73 __HAL_UNLOCK(huart);
  74. 74
  75. 75 return HAL_OK;
  76. 76 }
  77. 77 else
  78. 78 {
  79. 79 return HAL_BUSY;
  80. 80 }
  81. 81 }

HAL_UART_Transmit

  该函数能够通过huart串口接收Size位pData数据。

  • huart    :选择用来接收的UART串口
  • pData   :指向将要存放数据的指针
  • Size      :接收数据的大小
  • Timeout:超时时间
  

  1. 1 /**
  2. 2 * @brief Receives an amount of data in blocking mode.
  3. 3 * @param huart Pointer to a UART_HandleTypeDef structure that contains
  4. 4 * the configuration information for the specified UART module.
  5. 5 * @param pData Pointer to data buffer
  6. 6 * @param Size Amount of data to be received
  7. 7 * @param Timeout Timeout duration
  8. 8 * @retval HAL status
  9. 9 */
  10. 10 HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
  11. 11 {
  12. 12 uint16_t *tmp;
  13. 13 uint32_t tickstart = 0U;
  14. 14
  15. 15 /* Check that a Rx process is not already ongoing */
  16. 16 if (huart->RxState == HAL_UART_STATE_READY)
  17. 17 {
  18. 18 if ((pData == NULL) || (Size == 0U))
  19. 19 {
  20. 20 return HAL_ERROR;
  21. 21 }
  22. 22
  23. 23 /* Process Locked */
  24. 24 __HAL_LOCK(huart);
  25. 25
  26. 26 huart->ErrorCode = HAL_UART_ERROR_NONE;
  27. 27 huart->RxState = HAL_UART_STATE_BUSY_RX;
  28. 28
  29. 29 /* Init tickstart for timeout managment */
  30. 30 tickstart = HAL_GetTick();
  31. 31
  32. 32 huart->RxXferSize = Size;
  33. 33 huart->RxXferCount = Size;
  34. 34
  35. 35 /* Check the remain data to be received */
  36. 36 while (huart->RxXferCount > 0U)
  37. 37 {
  38. 38 huart->RxXferCount--;
  39. 39 if (huart->Init.WordLength == UART_WORDLENGTH_9B)
  40. 40 {
  41. 41 if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
  42. 42 {
  43. 43 return HAL_TIMEOUT;
  44. 44 }
  45. 45 tmp = (uint16_t *) pData;
  46. 46 if (huart->Init.Parity == UART_PARITY_NONE)
  47. 47 {
  48. 48 *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);
  49. 49 pData += 2U;
  50. 50 }
  51. 51 else
  52. 52 {
  53. 53 *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x00FF);
  54. 54 pData += 1U;
  55. 55 }
  56. 56
  57. 57 }
  58. 58 else
  59. 59 {
  60. 60 if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
  61. 61 {
  62. 62 return HAL_TIMEOUT;
  63. 63 }
  64. 64 if (huart->Init.Parity == UART_PARITY_NONE)
  65. 65 {
  66. 66 *pData++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
  67. 67 }
  68. 68 else
  69. 69 {
  70. 70 *pData++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
  71. 71 }
  72. 72
  73. 73 }
  74. 74 }
  75. 75
  76. 76 /* At end of Rx process, restore huart->RxState to Ready */
  77. 77 huart->RxState = HAL_UART_STATE_READY;
  78. 78
  79. 79 /* Process Unlocked */
  80. 80 __HAL_UNLOCK(huart);
  81. 81
  82. 82 return HAL_OK;
  83. 83 }
  84. 84 else
  85. 85 {
  86. 86 return HAL_BUSY;
  87. 87 }
  88. 88 }

HAL_UART_Receive

 

  1. 1 /* USER CODE BEGIN 1 */
  2. 2 unsigned char uRx_Data = 0;
  3. 3 /* USER CODE END 1 */
  1. 1 /* Infinite loop */
  2. 2 /* USER CODE BEGIN WHILE */
  3. 3 while (1)
  4. 4 {
  5. 5 /* 判断是否接收成功 */
  6. 6 if(HAL_UART_Receive(&huart1, &uRx_Data, 1, 1000) == HAL_OK)
  7. 7 {
  8. 8 /* 将接收成功的数据通过串口发出来 */
  9. 9 HAL_UART_Transmit(&huart1, &uRx_Data, 1, 0xffff);
  10. 10 }
  11. 11
  12. 12 /* USER CODE END WHILE */
  13. 13
  14. 14 /* USER CODE BEGIN 3 */
  15. 15 }
  16. 16 /* USER CODE END 3 */

 整个main函数如下:

  1. 1 /**
  2. 2 * @brief The application entry point.
  3. 3 * @retval int
  4. 4 */
  5. 5 int main(void)
  6. 6 {
  7. 7 /* USER CODE BEGIN 1 */
  8. 8 unsigned char uRx_Data = 0;
  9. 9 /* USER CODE END 1 */
  10. 10
  11. 11
  12. 12 /* MCU Configuration--------------------------------------------------------*/
  13. 13
  14. 14 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  15. 15 HAL_Init();
  16. 16
  17. 17 /* USER CODE BEGIN Init */
  18. 18
  19. 19 /* USER CODE END Init */
  20. 20
  21. 21 /* Configure the system clock */
  22. 22 SystemClock_Config();
  23. 23
  24. 24 /* USER CODE BEGIN SysInit */
  25. 25
  26. 26 /* USER CODE END SysInit */
  27. 27
  28. 28 /* Initialize all configured peripherals */
  29. 29 MX_GPIO_Init();
  30. 30 MX_USART1_UART_Init();
  31. 31 /* USER CODE BEGIN 2 */
  32. 32
  33. 33 /* USER CODE END 2 */
  34. 34
  35. 35 /* Infinite loop */
  36. 36 /* USER CODE BEGIN WHILE */
  37. 37 while (1)
  38. 38 {
  39. 39 /* 判断是否接收成功 */
  40. 40 if(HAL_UART_Receive(&huart1, &uRx_Data, 1, 1000) == HAL_OK)
  41. 41 {
  42. 42 /* 将接收成功的数据通过串口发出来 */
  43. 43 HAL_UART_Transmit(&huart1, &uRx_Data, 1, 0xffff);
  44. 44 }
  45. 45
  46. 46 /* USER CODE END WHILE */
  47. 47
  48. 48 /* USER CODE BEGIN 3 */
  49. 49 }
  50. 50 /* USER CODE END 3 */
  51. 51 }

  这种接收方式是直接在main函数里的while循环里不断接收,会严重占用程序的进程,且接收较长的数据时,会发生接收错误,如下:

  1. 1 /* USER CODE BEGIN USART1_MspInit 1 */
  2. 2 __HAL_UART_ENABLE_IT(uartHandle, UART_IT_RXNE);
  3. 3 /* USER CODE END USART1_MspInit 1 */

整个HAL_UART_MspInit函数如下:

  1. 1 void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
  2. 2 {
  3. 3
  4. 4 GPIO_InitTypeDef GPIO_InitStruct = {0};
  5. 5 if(uartHandle->Instance==USART1)
  6. 6 {
  7. 7 /* USER CODE BEGIN USART1_MspInit 0 */
  8. 8
  9. 9 /* USER CODE END USART1_MspInit 0 */
  10. 10 /* USART1 clock enable */
  11. 11 __HAL_RCC_USART1_CLK_ENABLE();
  12. 12
  13. 13 __HAL_RCC_GPIOA_CLK_ENABLE();
  14. 14 /**USART1 GPIO Configuration
  15. 15 PA9 ------> USART1_TX
  16. 16 PA10 ------> USART1_RX
  17. 17 */
  18. 18 GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
  19. 19 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  20. 20 GPIO_InitStruct.Pull = GPIO_PULLUP;
  21. 21 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  22. 22 GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
  23. 23 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  24. 24
  25. 25 /* USART1 interrupt Init */
  26. 26 HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
  27. 27 HAL_NVIC_EnableIRQ(USART1_IRQn);
  28. 28 /* USER CODE BEGIN USART1_MspInit 1 */
  29. 29 __HAL_UART_ENABLE_IT(uartHandle, UART_IT_RXNE);
  30. 30 /* USER CODE END USART1_MspInit 1 */
  31. 31 }
  32. 32 }

 1 unsigned char uRx_Data = 0; 

  1. 1 /* -1- 接收 */
  2. 2 HAL_UART_Receive(&huart1, &uRx_Data, 1, 1000);
  3. 3 /* -2- 将接收成功的数据通过串口发出去 */
  4. 4 HAL_UART_Transmit(&huart1, &uRx_Data, 1, 0xffff);

 整个USART1_IRQHandler(在stm32f4xx_it.c中)函数如下:

  1. 1 /**
  2. 2 * @brief This function handles USART1 global interrupt.
  3. 3 */
  4. 4 void USART1_IRQHandler(void)
  5. 5 {
  6. 6 /* USER CODE BEGIN USART1_IRQn 0 */
  7. 7 unsigned char uRx_Data;
  8. 8
  9. 9 /* -1- 接收 */
  10. 10 HAL_UART_Receive(&huart1, &uRx_Data, 1, 1000);
  11. 11 /* -2- 将接收成功的数据通过串口发出去 */
  12. 12 HAL_UART_Transmit(&huart1, &uRx_Data, 1, 0xffff);
  13. 13
  14. 14 /* USER CODE END USART1_IRQn 0 */
  15. 15 HAL_UART_IRQHandler(&huart1);
  16. 16 /* USER CODE BEGIN USART1_IRQn 1 */
  17. 17
  18. 18 /* USER CODE END USART1_IRQn 1 */
  19. 19 }

 

  相对于前面的直接接收方式,该中断接收方式就显得特别人性化了,在没有什么特别事件的时候,单片机会按照原本的程序运行着,等到有数据从UART串口发送过来时,会马上进入UART串口的中断处理函数中,完成相应的中断处理操作,完成后会退出中断函数,并继续原本在进行的程序,这样就不会占用单片机程序太多的进程了。

  但仍会发生前面直接接收方式的接收异常状况,主要原因是,在中断处理函数中,我们在接收了数据后并紧接着作出发送的操作,这会出现一个状况,还没来得及将上一次接收到的数据发送出去,就进入下一次接收的中断,然而导致失去了一些数据了。

  这种接收方式,是在方式2的基础上稍作改进的,较于前两种接收方式,是更好的一种接收方式,不会给原本的程序进程造成太大影响。还可以先接收全部数据(提示:通过定义一个较大的数组来存储),再将数据进行处理,这样能确保接收数据的完整性,并能将数据进行有效的处理、分析。

  既然这种方式明显会好一点,那为什么一开始不用这个方式呢?因为通过前面两种方法,可以更容易明白UART接收的操作。

  而这次就只要在方式2的基础上作出一些简单的修改就可以了。

  1. 1 /* USER CODE BEGIN USART1_MspInit 1 */
  2. 2 __HAL_UART_ENABLE_IT(uartHandle, UART_IT_RXNE);
  3. 3 /* USER CODE END USART1_MspInit 1 */

整个HAL_UART_MspInit(在usart.c中)函数如下:

  1. 1 void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
  2. 2 {
  3. 3
  4. 4 GPIO_InitTypeDef GPIO_InitStruct = {0};
  5. 5 if(uartHandle->Instance==USART1)
  6. 6 {
  7. 7 /* USER CODE BEGIN USART1_MspInit 0 */
  8. 8
  9. 9 /* USER CODE END USART1_MspInit 0 */
  10. 10 /* USART1 clock enable */
  11. 11 __HAL_RCC_USART1_CLK_ENABLE();
  12. 12
  13. 13 __HAL_RCC_GPIOA_CLK_ENABLE();
  14. 14 /**USART1 GPIO Configuration
  15. 15 PA9 ------> USART1_TX
  16. 16 PA10 ------> USART1_RX
  17. 17 */
  18. 18 GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
  19. 19 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  20. 20 GPIO_InitStruct.Pull = GPIO_PULLUP;
  21. 21 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  22. 22 GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
  23. 23 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  24. 24
  25. 25 /* USART1 interrupt Init */
  26. 26 HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
  27. 27 HAL_NVIC_EnableIRQ(USART1_IRQn);
  28. 28 /* USER CODE BEGIN USART1_MspInit 1 */
  29. 29 __HAL_UART_ENABLE_IT(uartHandle, UART_IT_RXNE);
  30. 30 /* USER CODE END USART1_MspInit 1 */
  31. 31 }
  32. 32 }
  1. 1 static unsigned char uRx_Data[1024] = {0} ; //存储数组
  2. 2 static unsigned char * pRx_Data = uRx_Data; //指向存储数组将要存储数据的位
  3. 3 static unsigned char uLength = 0 ; //接收数据长度

  如下的第2、3步都可以根据自身要求进行改进。

  • 第2步:判断接收结束条件,这个可以根据自己想要接收何种类型的数据而定。
  • 第3步:数据处理,大家可以在这一步执行自己想要对数据做的一些操作,我这里只是将接收到的数据重新发送出去而已。
  1. 1 /* -1- 接收数据 */
  2. 2 HAL_UART_Receive(&huart1, pRx_Data, 1, 1000);
  3. 3
  4. 4 /* -2- 判断数据结尾 */
  5. 5 if(*pRx_Data == \'\n\')
  6. 6 {
  7. 7 /* -3- 将接收成功的数据通过串口发出去 */
  8. 8 HAL_UART_Transmit(&huart1, uRx_Data, uLength, 0xffff);
  9. 9
  10. 10 /* -4- 初始化指针和数据长度 */
  11. 11 pRx_Data = uRx_Data; //重新指向数组起始位置
  12. 12 uLength = 0; //长度清零
  13. 13 }
  14. 14 /* -5- 若未结束,指针往下一位移动,长度自增一 */
  15. 15 else
  16. 16 {
  17. 17 pRx_Data++;
  18. 18 uLength++;
  19. 19 }

整个USART1_IRQHandler(在stm32f4xx_it.c中)函数如下:

  1. 1 /**
  2. 2 * @brief This function handles USART1 global interrupt.
  3. 3 */
  4. 4 void USART1_IRQHandler(void)
  5. 5 {
  6. 6 /* USER CODE BEGIN USART1_IRQn 0 */
  7. 7 static unsigned char uRx_Data[1024] = {0} ; //存储数组
  8. 8 static unsigned char * pRx_Data = uRx_Data; //指向存储数组将要存储数据的位
  9. 9 static unsigned char uLength = 0 ; //接收数据长度
  10. 10
  11. 11 /* -1- 接收数据 */
  12. 12 HAL_UART_Receive(&huart1, pRx_Data, 1, 1000);
  13. 13
  14. 14 /* -2- 判断数据结尾 */
  15. 15 if(*pRx_Data == \'\n\')
  16. 16 {
  17. 17 /* -3- 将接收成功的数据通过串口发出去 */
  18. 18 HAL_UART_Transmit(&huart1, uRx_Data, uLength, 0xffff);
  19. 19
  20. 20 /* -4- 初始化指针和数据长度 */
  21. 21 pRx_Data = uRx_Data; //重新指向数组起始位置
  22. 22 uLength = 0; //长度清零
  23. 23 }
  24. 24 /* -5- 若未结束,指针往下一位移动,长度自增一 */
  25. 25 else
  26. 26 {
  27. 27 pRx_Data++;
  28. 28 uLength++;
  29. 29 }
  30. 30
  31. 31
  32. 32 /* USER CODE END USART1_IRQn 0 */
  33. 33 HAL_UART_IRQHandler(&huart1);
  34. 34 /* USER CODE BEGIN USART1_IRQn 1 */
  35. 35
  36. 36 /* USER CODE END USART1_IRQn 1 */
  37. 37 }

 

 

  这一篇博客带来的是两种简单的接收方式(方式1:直接接收、方式2:中断接收1),还有一种接收方式(方式3:中断接收2),并实现了接收的操作。

  但前面两种方式是不推荐的,因为在接收数据的时候,建议程序只在负责接收程序,直至接收完毕为止,数据接收完毕再进入自己处理数据的函数内。

  除了上面的方法,还有DMA接收方法没介绍,这里先不说了。

  整体来说,自我感觉还是讲解得比较清楚得,如果还有对于此篇博客不懂之处,可以在下方评论留言提问,我会尽快回复的。

~

~

~

~

感谢阅读~

 欢迎大家关注我的博客,一起分享嵌入式知识~

版权声明:本文为ChurF-Lin原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/ChurF-Lin/p/10809000.html