今天要來介紹一下HAL庫的串口中斷使用方法
首先打開CUBEMX,新建一個STM32工程,博主建立的是F429工程,然后在圖形界面中打開一個USART,這里我們使用USART1。
然后進入配置configguration
基本的參數都不用修改,在NVIC中,大概中斷使能
然后生成工程即可,打開工程文件。這里要解釋一下串口中斷接收:
關於串口接收中斷
用CUBEMX生成的工程文件中,先開啟接收中斷使能
__HAL_UART_ENABLE_IT(uartHandle, UART_IT_RXNE);
並且利用HAL_UART_Receive_IT(uartHandle, &TempChar, 1);
這個函數中,第二個和第三個參數可以修改,分別代表預處字符串和字符串大小。
我們可以定義個初始化函數,在進入while(1)之前執行,比如我自定義了一個ITEnable(void);我們再來看一下這個函數的定義和使用位置:
void ITEnable(void) {
HAL_TIM_Base_Start_IT(&htim6);
HAL_TIM_Base_Start_IT(&htim7);
__HAL_UART_ENABLE_IT(&huart3, UART_IT_RXNE);
HAL_UART_Receive_IT(&huart3, &TempChar, 1);
__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);
HAL_UART_Receive_IT(&huart1, &TempChar, 1);
}
可以看到,在這里我們開啟了中斷使能以及說明了接收到的信息存放位置&TempChar, TempChar是我們聲明的一個全局變量,存放臨時字符。
/* USER CODE BEGIN 2 */ delay_init(180); LED_Init(); SDRAM_Init(); LCD_Init(); ESP8266_Init(); ITEnable(); PeriphInit(); LCD_ShowString(30,0,200,24,24,"ShowTimeWalker"); /* USER CODE END 2 */
(上面是我從自己的工程里面挑選的代碼,大家只需要關注部分代碼)
設置完后,每次接受完一個字符,都會進入中斷服務函數,官方申明的服務函數為
void USART1_IRQHandler(void)
該函數中只有一個目的,即進入
HAL_UART_IRQHandler(&huart1);
在這個函數中,函數會清除中斷標志位,禁止使能中斷!!!
並且進入函數UART_Receive_IT(huart);
在這里,把接收到的那個字符存放在之前HAL_UART_Receive_IT()設定的位置&TempChar,並計數
當計數達到設定值1后,轉入回調函數
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
最終的操作就可以在回調函數中完成了,博主的處理代碼如下:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance == USART1) { if(!END_STA) { if (TempChar!=0x0d) { Usart_ReceiveBuffer[USART_COUNTER++] = TempChar; } else { Usart_ReceiveBuffer[USART_COUNTER++] = TempChar; if (Usart_ReceiveBuffer[USART_COUNTER + 1] == 0) END_STA = 1; } } else { Usart_ReceiveBuffer[USART_COUNTER++] = TempChar; END_STA = 0; USART_COUNTER = 0; LCD_Fill(0, 120, 479, 149, WHITE); memcpy(USART1MESSAGE, Usart_ReceiveBuffer, RX_Length); for (int i = 0; i < RX_Length; i++) Usart_ReceiveBuffer[i] = 0; POINT_COLOR = BLACK; LCD_ShowString(30,120,800,24,24,(char*)USART1MESSAGE); } } }
在這之前還要聲明一些全局變量
u8 Usart_ReceiveBuffer[RX_Length] = {0}; u8 USART1MESSAGE[RX_Length] = {0}; u8 USART3MESSAGE[RX_Length] = {0}; u16 USART_COUNTER = 0; u8 END_STA = 0; uint8_t TempChar = 0;
由於已經禁能中斷,所以還要開啟中斷,每完成一次中斷處理后,我們還要再USART1_IRQHandler中補充一行
HAL_UART_Receive_IT(uartHandle, &TempChar, 1);
在stm32f4xx_it.c里面找到這個函數,修改為:
void USART1_IRQHandler(void) { HAL_UART_IRQHandler(&huart1); HAL_UART_Receive_IT(&huart1, &TempChar, 1); }
博主把接收到的信息存放在USART1MESSAGE的字符數組中,並且打印到了RGB顯示屏上,
紅字不用理他,博主是把發送的信息作為執行命令,比如發送了一個清屏函數LCD_Clear(),STM32會調用USMART組件完成相應的功能,如果不是正確格式,就會提示紅字。
以上便是我對HAL庫串口中斷接收的理解,歡迎大家討論。