目錄
概述
1?CubeMX配置串口參數
1.1 STM32CUB配置參數
1.2 生成代碼
2 核心代碼介紹
2.1 初始化函數?
2.2 中斷函數
2.3? 重要的用戶函數
2.4 實現用戶接口函數
3 接收數據函數的優化
3.1 HAL庫接收函數的缺陷
3.2 改進接收函數
概述
在STM32開發中使用HAL庫操作串口(UART)主要分為以下幾個步驟,下面以中斷接收和輪詢發送為例進行詳細說明:
1?CubeMX配置串口參數
1.1 STM32CUB配置參數
使用STM32 Cube工具配置UART參數,具體配置如下:
1)選擇端口
STM32F103RCTX有5個串口可供使用,其中USART(1~3)為增強型串口, UART(4-5)為普通串口。
2) baud rate 和其他參數
筆者選擇默認參數,其具體參數如下
注意: 關于選擇Baud的注意點
使用STM32串口應該注意,系統的工作頻率會影響串口數據的誤差率,官方已經給了測試數據,具體如下:
3) 配置中斷
4) 給IO添加User Label (可選擇)
1.2 生成代碼
通過以上配置,完成串口功能的參數配置 。接下來可已使用STM32CUBE工具生成代碼。在生成代碼前,應該選擇相應的開發工具,堆棧參數等
完成以上配置后,可點擊GENERATE CODE生成代碼,具體架構如下:
2 核心代碼介紹
2.1 初始化函數?
在usart.c文件中生成串口的初始代碼,其包括2個部分
1) 對串口的參數進行初始化
2)IO 參數初始化
包括開啟串口和IO的時鐘,配置IO的工作模式,配置中斷參數
2.2 中斷函數
在stm32fxx_it.c文件中實現了所有已經使能中斷的中斷函數,這里至關注和USART相關的中斷函數。
2.3? 重要的用戶函數
功能 | 函數 | 說明 |
---|---|---|
中斷發送 | HAL_UART_Transmit_IT() | 非阻塞發送(需等待發送完成中斷) |
DMA發送 | HAL_UART_Transmit_DMA() | DMA傳輸(高效不占用CPU) |
DMA接收 | HAL_UART_Receive_DMA() | DMA接收 |
發送函數 | HAL_UART_Transmit() | 查詢方式發送數據 |
查詢接收狀態 | HAL_UART_GetState(&huart1) == HAL_OK | 檢查串口狀態 |
接收數據回調函數 | HAL_UART_RxCpltCallback | 用于處理接收的數據 |
2.4 實現用戶接口函數
串口的重要作用是發送和接收數據,STM32Hal庫已經給了相應的函數接口,程序員需要了解這些函數,并合理的使用它們。
1) 發送數據函數
要使用該函數需要對其進行改造,具體寫法如下:
static void user_send(const uint8_t *buff, uint16_t len )
{HAL_UART_Transmit(&UartHandle, buff, len, 1000);
}
2) 接收數據?
STM32 HAL庫已經提供了接收數據的函數 ,這里使用中斷的方式接收數據,其函數原型如下:
通過在主函數中調用該函數就能接收數據。
3 接收數據函數的優化
3.1 HAL庫接收函數的缺陷
如下是HAl庫提供的接收函數,其包含3個參數
1)?huart: 串口對象
2)?pData: 接收數據的buff
3)?Size:? ?接收數據的大小
/*** @brief Receives an amount of data in non blocking mode.* @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),* the received data is handled as a set of u16. In this case, Size must indicate the number* of u16 available through pData.* @param huart Pointer to a UART_HandleTypeDef structure that contains* the configuration information for the specified UART module.* @param pData Pointer to data buffer (u8 or u16 data elements).* @param Size Amount of data elements (u8 or u16) to be received.* @retval HAL status*/
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;}/* Set Reception type to Standard reception */huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;return (UART_Start_Receive_IT(huart, pData, Size));}else{return HAL_BUSY;}
}
使用該函數接收數據,其timeout的時間取決于Size, 當Size越大,其timeout的時間會越長。
3.2 改進接收函數
通過操作STM32的寄存器實現單個字節的接收,這樣可以根據接收數據的需要,隨時調整Timerout的時間。具體方法如下:
1) 在回調函數中實現接收代碼
uint32_t isrflags = READ_REG(huart->Instance->SR);uint32_t cr1its = READ_REG(huart->Instance->CR1);if( huart->Instance == USART1 ){/* UART in mode Receiver */if(( isrflags & USART_SR_RXNE) != RESET ){data = huart->Instance->DR;// protocol_data_recvByte(data);}SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE);CLEAR_BIT(huart->Instance->SR, USART_SR_ORE);}
2) 初始化函數中添加觸發中斷語句
/* USER CODE BEGIN USART1_Init 2 */SET_BIT(huart1.Instance->CR1, USART_CR1_RXNEIE);/* USER CODE END USART1_Init 2 *
3) 在中斷函數中直接調用回調函數
/* USER CODE BEGIN USART1_IRQn 0 */HAL_UART_RxCpltCallback(&huart1);/* USER CODE END USART1_IRQn 0 *