串口中斷的實現(函數名參考MX生成代碼)
初始化:
1、void MX_USART1_UART_Init()
基於UART_HandleTypeDef huart,對huart的成員進行配置,並將數據傳入HAL_UART_Init(UART_HandleTypeDef *huart),完成對串口功能特性的配置
接下來需要分情況了:是將接受處理寫在中斷服務函數里還是寫在中斷Callback里面,若寫在Callback里面,我們還需要對HAL_UART_Receive_IT()進行配置,傳入參數有&huart,buffer的首指針與buffersize;若寫在中斷服務函數里則不需要對Receive IT進行配置,相對來說寫在中斷服務函數里效率會相對高效
UART_HandleTypeDef huart1; void MX_USART1_UART_Init(void) { huart1.Instance = USART1; huart1.Init.BaudRate = 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; huart1.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart1) != HAL_OK) { Error_Handler(); } }
2、void HAL_UART_MspInit(UART_HandleTypeDef *huart)
又是一個weak函數,這個函數寫在HAL_UART_Init(UART_HandleTypeDef *huart)里面,HAL庫通過引出這個API,使得用戶可以自行在外部配置硬件資源,此處主要是對GPIO的配置以及中斷優先級配置和允許
以上兩個函數需要用戶自行編寫,或使用CubeMX生成
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(); GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF7_USART1; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); HAL_NVIC_SetPriority(USART1_IRQn, 0, 0); HAL_NVIC_EnableIRQ(USART1_IRQn); } }
中斷時:
1、void USART1_IRQHandler(void)
這是中斷服務函數,假設用戶采用直接寫在中斷服務函數里的方式,那么到此為止了,這時只需要在此函數里寫用戶對於接收數據的處理(接收值在寄存器里,限於篇幅不贅述),設置標志清零即可,如果用CubeMX,這個服務函數會生成再stm32xxx_it.c里,用戶需要自己編寫回調
假設用戶采用回調的方式,那么需要在此函數里調用總的Handler:HAL_UART_IRQHandler(),這里面會調用UART_Receive_IT(),在里面會調用HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
回調:
HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
叕是一個weak函數,用戶在外部定義這個Callback,寫法和另一種方式的寫在中斷服務函數的內容一樣,不過由於是公用的Callback,需要在這里面判斷是串口幾,done
續:由於是簡述,目前理解還不太深,潦潦草草先寫這么多后再補充。。。