目錄
STM32F103RC使用HAL庫配置USART進行數據收發(代碼模塊)
一、USART初始化
二、USART使用的GPIO初始化
三、USART的接收中斷配置
四、USART的數據發送
五、補充
STM32F103RC使用HAL庫配置USART進行數據收發(代碼模塊)
一、USART初始化
UART_HandleTypeDef huart1; uint8_t Rdata; ? void MX_USART1_UART_Init(void) {huart1.Instance = USART1;huart1.Init.BandRate = 115200;huart1.Init.WordLength = UART_WORDLENGTH_8B;huart1.Init.StopBits = UART_STOPBITS_1;huart1.Init.Parity = UART_PARITY_NONE;huart1.Init.Mode = UART_MODE_TX_RX;huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;if(HAL_UART_Init(&huart1) != HAL_OK){Error_Handler();}#if 1HAL_UART_Receive_IT(&huart1,&Rdata,1); //使能接收中斷,會進入回調函數#else__HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE); //直接使能串口接收中斷,不會進入回調函數#endif }
二、USART使用的GPIO初始化
UART使用的GPIO初始化函數是在void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)函數中: void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle) ? ? {GPIO_InitTypeDef GPIO_InitStruct = {0};if(uartHandle->Instance == USART1){__HAL_RCC_USART1_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_AFIO_CLK_ENABLE();//PA9(USART1_TX) GPIO_InitStruct.Pin = USART1_TX_Pin;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; ?GPIO_InitStruct.Pull = GPIO_NOPULL; ? ? ?HAL_GPIO_Init(USART1_TX_GPIO_Port,&GPIO_InitStruct); //PA10(USART1_RX)GPIO_InitStruct.Pin = USART1_RX_Pin;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_NOPULL; ? ?HAL_GPIO_Init(USART1_RX_GPIO_Port,&GPIO_InitStruct); ? ?HAL_NVIC_SetPriority(USART1_IRQn,0,0);HAL_NVIC_EnableIRQ(USART1_IRQn);} }
三、USART的接收中斷配置
USART的接收中斷的配置有兩種方式,以下簡要介紹下兩種配置方式的不同。1、使用串口接收中斷回調函數 2、不使用串口接收中斷的回調函數
######使用串口接收中斷回調函數時的配置如下: 1、函數MX_USART1_UART_Init的配置 void MX_USART1_UART_Init(void) {/*//這里是串口的初始化配置*/HAL_UART_Receive_IT(&huart1,&Rdata,1); //使能接收中斷,會進入回調函數 } 在函數void MX_USART1_UART_Init(void)中的最后使用HAL_UART_Receive_IT(&huart1,&Rdata,1)進行配置。該函數會使能接收中斷,每當串口接收到1個字節后就會進入回調函數void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)中。 2、串口接收中斷回調函數HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)配置 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {if(huart->Instance == USART1){QueueWrite((void *)buf_pc_to_uart,Rdata); //將串口接收到的數據寫入到隊列中HAL_UART_Receive_IT(&huart1,&Rdata,1); //接收完1字節后要重新使能接收中斷} } 在串口接收回調函數中,需要先對接收的數據進行處理,需要注意的是在處理完接收數據后要重新調用HAL_UART_Receive_IT函數使能接收中斷,使得下次接收完數據后能繼續進入回調函數。
######不使用串口接收中斷回調函數時的配置如下: 1、函數MX_USART1_UART_Init的配置 void MX_USART1_UART_Init(void) {/*//這里是串口的初始化配置*/__HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE); //直接使能串口接收中斷,不會進入回調函數 } 在函數void MX_USART1_UART_Init(void)中的最后使用__HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE)進行配置。該函數會使能接收中斷,但是不會進入回調函數void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)中,而是進入 void USART1_IRQHandler(void)中。 2、串口接收中斷函數void USART1_IRQHandler(void)配置 void USART1_IRQHandler(void) {if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_RXNE) != RESET){HAL_UART_Receive(&huart1,&Rdata,1,100);QueueWrite((void *)buf_pc_to_uart,Rdata); //將串口接收到的數據寫入到隊列中__HAL_UART_CLEAR_FLAG(&huart1,UART_FLAG_RXNE);}HAL_UART_IRQHandler(&huart1); } 在串口中斷函數中,和標準庫的處理流程相同,先通過接收中斷標志位是否置1判斷接收中斷是否觸發,觸發后接收數據,對接收到的數據進行處理后,清除接收中斷標志位即可。
四、USART的數據發送
直接調用HAL庫接口函數 HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart,uint8_t *pData,uint16_t Size,uint32_t Timeout) 或者 HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart,uint8_t *pData,uint16_t Size)即可。 ? ?
五、補充
1、這里介紹的串口配置及串口的收發數據是沒有使用DMA進行傳輸數據的,如果需要進行大數據包傳輸,就需要使用DMA進行數據傳輸了。這時就需要進一步配置DMA的發送或者接收功能了。這里不再介紹,可以自己去網上查找相關資料。 2、以上的配置我們使用的串口接收中斷每次接收1個字節的數據,當需要進行不定長數據或者大數據包的接收時,就不適合采用這種接收方式了,這時可以采用串口空閑中斷+DMA的方式來進行不定長數據或者大數據包的接收。一般配置流程如下: 首先、配置串口,串口GPIO及DMA完成初始化 然后、在串口初始化函數最后調用: HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart,uint8_t *pData,uint16_t Size)函數,該函數會使能串口的DMA接收并且使能串口的空閑中斷。當接收到一包數據后就會進入回調函數: void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart,uint16_t Size)。