以前用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_Delay(100); //加延時,保證接收到數據過長的時候,等待數據存入緩存區發送 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 */ }
運行結果如下,效果正確
談談串口RS232跟RS485:這兩個串口除了邏輯電平不同外,還有傳輸距離也不同,如果對速度要求不高,傳輸距離要比較遠的就用RS485比較好,雖然RS485是個半雙工,但是抑制共模干擾能力比較強,不過這些只是對於硬件層面的,對於軟件層面來說他們的本質都是串口,在STM32Cubemx中,都是只是配置為串口,按照串口的編程來處理即可。