• 基于STM32之UART串口通信协议(三)接收


    一、前言

    1、简介

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

    2、UART简介

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

    3、准备工作

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

    注:

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

      例如:

    二、CubeMx配置及函数说明

    说明:

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

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

    1、CubeMx配置

    1)按照UART详解配置UART(若配置过,可以继续使用)

    2)使能串口中断

    3)设置中断优先级(如果没开启其他中断,那就默认即可,直接跳过)

     4)代码生成(点击前最好把原本的工程关掉,不然有可能会有问题)

    2、函数说明

    1)CubeMx生成的UART初始化(在usart.c中)

    说明:

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

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

    2)CubeMx生成的UART中断处理函数(在stm32f4xx_it.c中)

    说明:

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

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

    3)HAL库函数HAL_UART_Transmit(在stm32f4xx_hal_uart.c中)

    说明:

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

    参数说明:

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

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

    • Size      :发送数据的大小

    • Timeout:超时时间

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

    4)HAL库函数HAL_UART_Receive(在stm32f4xx_hal_uart.c中)

    说明:

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

    参数说明:

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

    三、代码编写:实现UART接收

    1、直接接收(不建议)

    1)在main主函数中定义一个变量,负责接收数据

    1   /* USER CODE BEGIN 1 */
    2     unsigned char uRx_Data = 0;
    3   /* USER CODE END 1 */

    2)在main主函数while循环中调用HAL库UART接收函数

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

     整个main函数如下:

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

    3)编译、下载烧写

    4)实现效果(接收到数据后,调用UART发送函数将数据发送到电脑)

    说明:

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

     2、中断接收(接收并发送)(不推荐)

    1)在HAL_UART_MspInit(在usart.c中)使能接收中断

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

    整个HAL_UART_MspInit函数如下:

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

    2)在USART1_IRQHandler(在stm32f4xx_it.c中)定义一个变量,负责接收数据

     1 unsigned char uRx_Data = 0; 

    3)在USART1_IRQHandler(在stm32f4xx_it.c中)调用HAL库的UART接收函数以及发送函数

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

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

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

    4)编译、下载烧写

     

     5)实现效果(接收到数据后,调用UART发送函数将数据发送到电脑)

    说明:

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

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

    3、中断接收(先接收完,后处理)(推荐)

    说明:

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

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

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

     1)在HAL_UART_MspInit(在usart.c中)使能接收中断(与方式2相同)

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

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

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

    2)在USART1_IRQHandler(在stm32f4xx_it.c中)定义三个静态变量

    1     static unsigned char     uRx_Data[1024] = {0}     ;    //存储数组
    2     static unsigned char  *  pRx_Data       = uRx_Data;    //指向存储数组将要存储数据的位
    3     static unsigned char     uLength        =  0      ;    //接收数据长度

    3)在USART1_IRQHandler(在stm32f4xx_it.c中)调用HAL库的UART接收函数以及发送函数

    注:

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

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

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

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

    4)编译、下载烧写

     

     5)实现效果(接收到数据后,调用UART发送函数将数据发送到电脑)

     四、结尾

     1、总结

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

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

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

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

    2、回顾

    1)UART详解

    2)UART发送

    3、后续

    待补充

    ~

    ~

    ~

    ~

    感谢阅读~

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

  • 相关阅读:
    ssh.sh_for_ubuntu1604
    ssh.sh_for_ubuntu1404
    ssh.sh_for_ubuntu1204
    ssh.sh_for_centos
    raw,cow,qcow,qcow2镜像的比较
    Oz 创建Windows2008R2镜像
    Oz 创建Ubuntu镜像
    Oz 创建Debian8镜像
    Oz 创建CentOS7镜像
    Oz 创建CentOS6镜像
  • 原文地址:https://www.cnblogs.com/ChurF-Lin/p/10809000.html
Copyright © 2020-2023  润新知