基於STM32之UART串口通信協議(三)接收

来源:https://www.cnblogs.com/ChurF-Lin/archive/2019/05/06/10809000.html
-Advertisement-
Play Games

一、前言 1、簡介 回顧上一篇UART發送當中,已經講解瞭如何實現UART的發送操作了,接下來這一篇將會繼續講解如何實現UART的接收操作。 2、UART簡介 嵌入式開發中,UART串口通信協議是我們常用的通信協議之一,全稱叫做通用非同步收發傳輸器(Universal Asynchronous Rec ...


一、前言

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 == '\n')
 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 == '\n')
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、後續

  待補充……

~

~

~

~

感謝閱讀~

 歡迎大家關註我的博客,一起分享嵌入式知識~


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、簡介 linux alias 是命令的一種別稱,輸入 alias 可以看到像下麵這樣的結果: alias vi="vim" 也即,輸入vi後,被自動定向到vim這個命令了。alias的作用就是,可以簡寫命令。 二、修改alias 若要添加自己的alias,格式如下 alias la="ls -a ...
  • centos7 python3.6.2環境下virtualenv和virtualenvwrapper的簡單介紹。 ...
  • DHCP伺服器的架設 一、DHCP伺服器的安裝要求: 搭建DHCP伺服器需要一些必備條件支持,主要有以下方面: 二、安裝DHCP伺服器 以管理員身份登陸伺服器 右擊【電腦】 選擇【管理】 打開【伺服器管理器】 單擊【角色】 單擊【添加角色】 單擊【添加角色嚮導】 勾選【DHCP伺服器】 單擊【確定 ...
  • [TOC] 找到.ini路徑 Centos中重啟PHP 修改etc/php.ini後,必須重啟PHP才能生效 方式一 如果在安裝PHP時,設置了許可權並啟動php fpm: 方式二 也可以服務的方式啟動、停止和重啟: 一些經驗 ...
  • 本文將把Linux 系統管理遇到的問題進行彙總 一、用戶修改密碼 問題現象 用戶登錄後,修改自己的密碼,出現 passwd:Authentication token manipulation error(身份驗證令牌操作錯誤),一般是密碼文件的許可權的問題,不過也有可能是根目錄空間滿。 問題定位 ls ...
  • 我的內容來自於《馬哥Linux2016最新高薪運維視頻課程-Nginx應用基礎及配置詳解》 httpd:MPM prefork,worker,event prefork:主進程,生成多個子進程,每個子進程處理一個請求; worker:主進程,生成多個子進程,每個子進程再生成多個線程,每個線程響應一個 ...
  • python django uwsgi nginx安裝 已安裝完成python/django的情況下安裝 pip install uwsgi cd /usr/share/nginx/html/ vim uwsgi.ini輸入以下內容 #uwsgi.ini file [uwsgi] # Django- ...
  • 1.去官網下載適用於linux的jdk包,如jdk-8u162-linux-x64.tar.gz 2.創建目錄,將jdk包拷貝到該目錄下,如home/haha/user/java 3.在控制臺中進入該目錄,執行tar zxvf jdk-8u162-linux-x64.tar.gz 進行解壓 4.配置 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...