STM32 HAL庫使用中斷實現串列埠接收不定長資料
阿新 • • 發佈:2018-12-21
以前用DMA實現接收不定長資料,DMA的方法接收串列埠助手的資料,全部沒問題,不過如果接收模組返回的資料,而這些資料如果包含回車換行的話就會停止接收,例如接收:AT\r\nOK\r\n,就只能接收到AT\r,導致沒有接收完成,具體原因還沒搞懂,有了解的,希望可以告知一下,DMA不定長接收方法傳輸門:https://www.cnblogs.com/xingboy/p/9714907.html。
好了,不多說了,現在進入正文。首先建立一個STM32Cumebx的工程,開啟串列埠中斷,完成配置,具體的配置流程就不細說了,沒什麼難度就只是開啟串列埠跟中斷而已。
生成工程程式碼後,先定義好一些變數:
//串列埠4中斷接收定義 #define MAX_RECV_LEN 1024 //設定可以接收的最大位元組 uint8_t msg_buff[MAX_RECV_LEN] = {0}; //接收快取區 uint8_t * msg = msg_buff; //定義一個指標指向接收快取區 int flag = 0; //接收完成標誌 int len_u4=0; //資料長度記錄
接著重寫串列埠接收回調函式
/*重寫串列埠接收回調函式*/ void HAL_UART_RxCpltCallback(UART_HandleTypeDef*UartHandle) { uint8_t ret= HAL_OK; msg++; len_u4++;//資料長度計數 if( msg == msg_buff + MAX_RECV_LEN) { msg = msg_buff; } do { ret = HAL_UART_Receive_IT(UartHandle,(uint8_t *)msg,1); }while(ret != HAL_OK); if(*(msg-1) == '\n') //接收以\n為結尾字元,則表示接收完成 { flag= 1; } }
最後在main函式裡面編寫接收後的邏輯,注意要在while(1){ }前開啟串列埠接收中斷
int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration----------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init();
MX_DMA_Init();
MX_USART3_UART_Init();
MX_UART4_Init(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ //自己新增程式碼部分:while前開啟串列埠中斷接收 HAL_UART_Receive_IT(&huart4, (uint8_t *)msg, 1); //開啟第一次中斷 while (1) { /* USER CODE END WHILE *//* USER CODE BEGIN 3 */ //======自己新增程式碼部分========= if (flag == 1) { printf("msg_buff = %s ;len = %d\r\n",msg_buff,len_u4); HAL_UART_Transmit(&huart3,msg_buff, len_u4,100); //將串列埠4接收到的資料通過串列埠3傳出 memset(msg_buff, 0, sizeof(msg_buff)); //清空快取區 // 指向接收快取的頭部 msg = msg_buff; (&huart4)->pRxBuffPtr = msg; flag = 0; len_u4=0;//每次資料長度清0 } HAL_Delay(10); } //============================== /* USER CODE END 3 */ }
執行結果如下,效果正確