基於STM32之UART串口通訊協議(二)發送

1、前言

一、簡介

  在上一篇UART詳解中,已經有了關於UART的詳細介紹了,也有關於如何使用STM32CubeMX來配置UART的操做了,而在該篇博客,主要會講解一下如何實現UART串口的發送功能。html

二、UART簡介

  嵌入式開發中,UART串口通訊協議是咱們經常使用的通訊協議之一,全稱叫作通用異步收發傳輸器(Universal Asynchronous Receiver/Transmitter)。數組

三、準備工做

  在UART詳解中已經有了詳細的說明,在這裏就不說明了。異步

注:

  建議每次編寫好一個相關功能且測試功能成功使用後,保存並壓縮成一份Demo例程,方便往後有須要的時候能夠直接使用。ide

  例如:函數

 

2、CubeMx配置及函數說明

說明:

  這篇用到的配置跟UART詳解裏的配置都相同,能夠按照UART詳解來配置好時鐘、UART便可。oop

  因此在進行下一步以前,先確保已經按照UART詳解的配置步驟配置好了,而後再進行後面的操做。測試

一、CubeMx配置

  按照上一篇UART詳解來配置ui

二、函數說明

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

  
 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 /* USER CODE BEGIN USART1_MspInit 1 */ 48 49 /* USER CODE END USART1_MspInit 1 */ 50 } 51 } 52 53 void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle) 54 { 55 56 if(uartHandle->Instance==USART1) 57 { 58 /* USER CODE BEGIN USART1_MspDeInit 0 */ 59 60 /* USER CODE END USART1_MspDeInit 0 */ 61 /* Peripheral clock disable */ 62 __HAL_RCC_USART1_CLK_DISABLE(); 63 64 /**USART1 GPIO Configuration 65 PA9 ------> USART1_TX 66 PA10 ------> USART1_RX 67 */ 68 HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10); 69 70 /* USER CODE BEGIN USART1_MspDeInit 1 */ 71 72 /* USER CODE END USART1_MspDeInit 1 */ 73 } 74 } 
USART init

2)HAL庫函數HAL_UART_Transmit(在stm32f4xx_hal_uart.c中)

說明:

  該函數可以經過huart串口發送Size位pData數據。spa

參數說明:

  • 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

 

3、代碼部分:實現UART發送

一、直接發送

1)在main主函數中定義一個數組

1   /* USER CODE BEGIN 1 */
2     unsigned char uTx_Data[5] = {0x41, 0x42, 0x43, 0x44, 0x45};    //數組內十六進制表明「ABCDE」
3   /* USER CODE END 1 */

2)在main主函數中的while循環中調用HAL庫UART發送函數

/* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1) { /* UART發送 */ HAL_UART_Transmit(&huart1, uTx_Data, sizeof(uTx_Data), 0xffff); /* 延遲1s */ HAL_Delay(1000); /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */

整個main函數以下:

 1 int main(void)  2 {  3   /* USER CODE BEGIN 1 */
 4     unsigned char uTx_Data[5] = {0x41, 0x42, 0x43, 0x44, 0x45};    //數組內十六進制表明「ABCDE」
 5   /* USER CODE END 1 */
 6   
 7 
 8   /* MCU Configuration--------------------------------------------------------*/
 9 
10   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
11  HAL_Init(); 12 
13   /* USER CODE BEGIN Init */
14 
15   /* USER CODE END Init */
16 
17   /* Configure the system clock */
18  SystemClock_Config(); 19 
20   /* USER CODE BEGIN SysInit */
21 
22   /* USER CODE END SysInit */
23 
24   /* Initialize all configured peripherals */
25  MX_GPIO_Init(); 26  MX_USART1_UART_Init(); 27   /* USER CODE BEGIN 2 */
28 
29   /* USER CODE END 2 */
30 
31   /* Infinite loop */
32   /* USER CODE BEGIN WHILE */
33   while (1) 34  { 35         /* UART發送 */
36       HAL_UART_Transmit(&huart1, uTx_Data, sizeof(uTx_Data), 0xffff); 37         /* 延遲1s */
38         HAL_Delay(1000); 39     /* USER CODE END WHILE */
40 
41     /* USER CODE BEGIN 3 */
42  } 43   /* USER CODE END 3 */
44 }

3)編譯、下載燒寫

4)實現效果(在PC端串口助手中顯示發送成功)

二、字符串發送

說明:

  前面的發送方式,不只要傳入句柄參數,還有數組、長度、超時時間參數。

  爲了簡便發送,咱們能夠專門寫一個字符串發送函數,能夠直接傳入一個數組便可發送,能夠更簡便地實現字符串發送。

  優勢是,發送數據更簡便,可以一次性發送很長的數據數組。

  但缺點就是不能控制發送的長度,會將整個數據數組發出。

1)在Uart.c中添加vUser_UART_SendString函數

 1 /* USER CODE BEGIN 1 */
 2 void vUser_UART_SendString(UART_HandleTypeDef* uartHandle, unsigned char * uData)  3 {  4     /* -1- 判斷數據是否發送完畢 */
 5     while(*uData)        //若爲空即發送完畢,若不爲空則還有數據
 6  {  7         /* -2- 發送1Byte */
 8         HAL_UART_Transmit(uartHandle, uData, 1, 0xffff);  9         /* -3- 移至下1Byte */
10         uData++; 11  } 12 } 13 /* USER CODE END 1 */

2)在Uart.h中聲明一下vUser_UART_SendString函數(聲明後就能夠在別的地方調用該函數)

1 /* USER CODE BEGIN Prototypes */
2 extern void vUser_UART_SendString(UART_HandleTypeDef* uartHandle, unsigned char * uData); 3 /* USER CODE END Prototypes */

3)在main主函數中定義一個數組

1   /* USER CODE BEGIN 1 */
2     unsigned char uTx_Data[] = "\r\n Hallo World! 你好,世界!"; 3   /* USER CODE END 1 */

4)在main主函數的while循環中調用字符串發送函數

 1   /* Infinite loop */
 2   /* USER CODE BEGIN WHILE */
 3   while (1)  4  {  5         /* 字符串發送 */
 6       vUser_UART_SendString(&huart1, uTx_Data);  7         /* 延遲1s */
 8         HAL_Delay(1000);  9     /* USER CODE END WHILE */
10 
11     /* USER CODE BEGIN 3 */
12  } 13   /* USER CODE END 3 */

整個main函數以下:

 1 int main(void)  2 {  3   /* USER CODE BEGIN 1 */
 4     unsigned char uTx_Data[] = "\r\n Hallo World! 你好,世界!";  5   /* USER CODE END 1 */
 6   
 7 
 8   /* MCU Configuration--------------------------------------------------------*/
 9 
10   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
11  HAL_Init(); 12 
13   /* USER CODE BEGIN Init */
14 
15   /* USER CODE END Init */
16 
17   /* Configure the system clock */
18  SystemClock_Config(); 19 
20   /* USER CODE BEGIN SysInit */
21 
22   /* USER CODE END SysInit */
23 
24   /* Initialize all configured peripherals */
25  MX_GPIO_Init(); 26  MX_USART1_UART_Init(); 27   /* USER CODE BEGIN 2 */
28 
29   /* USER CODE END 2 */
30 
31   /* Infinite loop */
32   /* USER CODE BEGIN WHILE */
33   while (1) 34  { 35         /* UART發送 */
36       vUser_UART_SendString(&huart1, uTx_Data); 37         /* 延遲1s */
38         HAL_Delay(1000); 39     /* USER CODE END WHILE */
40 
41     /* USER CODE BEGIN 3 */
42  } 43   /* USER CODE END 3 */
44 }

5)編譯、下載燒寫

6)實現效果(在PC端串口助手顯示發送成功)

三、printf發送

說明:

  這種發送方式就是至關於編寫c語言的時候,在小黑框中打印本身想要打印的東西,咱們也能夠在串口助手上實現同樣的功能。

  因爲篇幅長度有限,可能須要後續有空再補上這一發送方式,在這裏先不講解了。

 

4、結尾

一、總結

  這篇博客主要是以上一篇UART詳解爲基礎,來實現使用UART來實現發送功能,在這裏簡單講解了兩種發送方式,而在後續若是有機會還會補上第三種printf發送方式的。

  若是你們還不清楚UART串口通訊協議的,能夠閱讀一下上一篇UART詳解。若還有對於此篇博客不懂之處,可在下方留言評論,我會盡快回復。

二、回顧

1)UART詳解

三、後續

1)UART接收

2)待補充

~

~

~

~

感謝閱讀~

 歡迎你們關注個人博客,一塊兒分享嵌入式知識~

原文出處:https://www.cnblogs.com/ChurF-Lin/p/10798193.html

相關文章
相關標籤/搜索