STM32基於HAL庫串列埠空閒中斷接收不定長資料
阿新 • • 發佈:2020-08-19
一、前言
- 最近在使用STM32的HAL庫的時候,發現竟然沒有整合IDLE中斷處理,本身寫的HAL庫處理邏輯就挺繁瑣,效率又不高,還缺胳膊少腿的。平時專案中的串列埠接收資料都是不定長的,而IDLE中斷在這一塊作用是非常大的,可以大大簡化資料接收過程的判斷。本文將介紹基於HAL庫IDLE中斷接收不定長資料。
二、程式碼實現
- 首先串列埠的初始化工作,在初始化過程中,我們需要開啟兩個中斷,一個是UART_IT_RXNE接收中斷,此中斷是沒接收到一個位元組的資料接收產生一次中斷,另一個是UART_IT_IDLE空閒中斷,也就是我們今天的主角。每幀資料傳送完成就會有空閒時期,一幀資料接收完成就會產生空閒中斷。這裡我們不使用 HAL_UART_Receive_IT()函式來初始化了,因為我們不用HAL庫的那一套,直接進行中斷開啟。
void USART1_Init(uint32_t Bound) { UART1_HandleStructure.Instance = USART1; UART1_HandleStructure.Init.BaudRate = Bound; UART1_HandleStructure.Init.WordLength = UART_WORDLENGTH_8B; UART1_HandleStructure.Init.StopBits = UART_STOPBITS_1; UART1_HandleStructure.Init.Parity = UART_PARITY_NONE; UART1_HandleStructure.Init.Mode = UART_MODE_TX_RX; UART1_HandleStructure.Init.HwFlowCtl = UART_HWCONTROL_NONE; HAL_UART_Init(&UART1_HandleStructure); HAL_NVIC_EnableIRQ(USART1_IRQn); HAL_NVIC_SetPriority(USART1_IRQn,3,3); __HAL_UART_ENABLE_IT(&UART1_HandleStructure,UART_IT_RXNE);//接收中斷 __HAL_UART_ENABLE_IT(&UART1_HandleStructure,UART_IT_IDLE);//空閒中斷 }
- 下來是寫我們的中斷服務函式,我們直接在USART1_IRQHandler()裡寫我們的處理邏輯,不需要再呼叫HAL_UART_IRQHandler()函式。如果進入的是接收中斷,我們把接收到的位元組放入到緩衝區,如果接收長度超過了緩衝區位元組就不再處理直接丟棄。如果進入的是空閒中斷,則表示一幀資料接收完成,這時候呼叫我們的回撥函式進行資料處理即可,一般是放到中斷外進行處理,我這裡為了簡化所以直接寫到中斷裡面了。注意清除IDLE的中斷標誌要使用__HAL_UART_CLEAR_IDLEFLAG()進行,不然會一直進入中斷。
void USART1_IRQHandler(void) { uint8_t res = 0; //接收中斷 if(__HAL_UART_GET_FLAG(&UART1_HandleStructure,UART_FLAG_RXNE) != RESET) { HAL_UART_Receive(&UART1_HandleStructure,&res,1,1000); //將資料放入緩衝區 if(rxConut < RX_BUFFER_SIZE) { aRxBuffer[rxConut] = res; rxConut++; } __HAL_UART_CLEAR_FLAG(&UART1_HandleStructure,UART_FLAG_RXNE); } //空閒中斷 if(__HAL_UART_GET_FLAG(&UART1_HandleStructure,UART_FLAG_IDLE) != RESET) { //一幀資料接收完成 USART1_IdleCallback(aRxBuffer,rxConut); rxConut = 0; __HAL_UART_CLEAR_IDLEFLAG(&UART1_HandleStructure); } } //回撥函式 void USART1_IdleCallback(uint8_t *pData,uint16_t len) { while(__HAL_UART_GET_FLAG(&UART1_HandleStructure,UART_FLAG_TC) != SET); HAL_UART_Transmit(&UART1_HandleStructure,pData,len,1000); }
三、測試結果
- 我設定的波特率為115200,資料傳送間隔10ms,附上測試圖。