1. 程式人生 > >STM32 HAL庫 串列埠DMA(收發)和STM32串列埠中斷接收(接收時間管理機制)+ESP8266 wifi模組通訊問題

STM32 HAL庫 串列埠DMA(收發)和STM32串列埠中斷接收(接收時間管理機制)+ESP8266 wifi模組通訊問題

一、HAL庫 串列埠 DMA+ESP8266模組通訊問題

STM32 HAL庫串列埠的DMA傳送和空閒中斷接收處理資料,單片機發送AT指令給ESP8266 wifi模組問題:微控制器連續幾次給wifi模組傳送AT指令,wifi模組總是少一次的應答,在無線通訊過程中是不方便和不允許的,因為在通訊過程會通訊不暢或中斷,如果要遠端升級程式,這不能達到遠端升級需求。部分程式如下:

int mian(void)
{
    for(n = 1; n <= 5;n++){
          printf("微控制器給WIFI模組傳送第%d次AT指令!\r\n",n);
          DMA_usart3_send((uint8_t*)"AT+RST\r\n",sizeof("AT+RST\r\n")-1);    //微控制器串列埠給wifi模組傳送AT指令
          if(usart3_recv_end_flag == 1){                                                              //微控制器是否接收到資料

                delay_ms(10);                                                                               //串列埠空閒中斷接收資料處理,稍微延時10ms
                usart3_recv_end_flag = 0;                                                              //把接收完成標誌清零
                if(strstr((const char *)usart3_rx_buf,"OK")){                                    //判斷wifi模組是否應答
                      rs485_send(usart3_rx_buf,usart3_rx_len);                               //把wifi模組應答資訊打印出來
                      usart3_rx_len = 0;                                                                     //把接收資料長度清零
                      memset(usart3_rx_buf,0,DATA_BUFFER_SIZE);                    //把接收快取器清零
                 }
          }                 
        delay_ms(500);                                                                                       //延時100ms
    }
}

微控制器連續5次給wifi模組傳送AT指令,但wifi模組只應答4次,打印出來的資料如下:

問題分析:

剛開始分析時,以為是微控制器串列埠程式處理有問題,查找了兩天時間一直沒有找到問題,後把延時函式放在了前面,微控制器給wifi模組傳送一次AT指令,wifi模組就應答一次。

分析:微控制器給wifi模組傳送AT指令後,需要稍微延時等待wifi模組應答,讀的太快會讀不到wifi應答的AT指令,會達不到研發要求。程式更改後,可以滿足開發需求。程式如下:

int mian(void)
{
    for(n = 1; n <= 5;n++){
         printf("微控制器給WIFI模組傳送第%d次AT指令!\r\n",n);
         DMA_usart3_send((uint8_t*)"AT+RST\r\n",sizeof("AT+RST\r\n")-1);    //微控制器串列埠給wifi模組傳送AT指令
         delay_ms(10);                                                                                      //串列埠空閒中斷接收資料處理,稍微延時10ms


         if(usart3_recv_end_flag == 1){                                                              //微控制器是否接收到資料
                usart3_recv_end_flag = 0;                                                             //把接收完成標誌清零
                if(strstr((const char *)usart3_rx_buf,"OK")){                                   //判斷wifi模組是否應答
                     rs485_send(usart3_rx_buf,usart3_rx_len);                               //把wifi模組應答資訊打印出來
                     usart3_rx_len = 0;                                                                     //把接收資料長度清零
                     memset(usart3_rx_buf,0,DATA_BUFFER_SIZE);                    //把接收快取器清零
                 }
          }             
        delay_ms(500);                                                                                      //延時100ms
    }
}

微控制器連續5次給wifi模組傳送AT指令,wifi模組應答5次,打印出來的資料如下:

二、HAL庫 串列埠中斷(不用DMA,用串列埠接收中斷時間管理機制處理接收資料)

在用串列埠中斷(接收資料幀用時間管理機制來實現)時,調了好半天沒調出來,微控制器給ESP8266模組傳送AT指令,然後微控制器接收ESP8266模組的應答,第一次總是接收不到,後面把下面用紅色標出的延時時間加長,才準確的接收ESP8266模組的應答。才發現是讀的太快,還沒等ESP8266模組應答,就去讀,所以讀不到ESP8266模組的應答。如果是微控制器給ESP8266模組傳送“AT+RST\r\n”指令,需要等待500-1000ms的時間,才能準確讀到ESP8266模組的應答。

bool sendWifiCmd(uint8_t *cmd,uint16_t len,uint8_t *ack,uint16_t waittime)   //微控制器給wifi模組傳送AT指令
{
        uint8_t xlen,buf[512];
        wifiSend(cmd,len);
        delay_ms(waittime);
//     if(wifiAtAckCmp(ack)){
//        return TRUE;      //返回TRUE說明wifi模組已有應答
//     }
        xlen = wifiRead(buf,sizeof(buf));                                                         //串列埠中斷接收資料處理,延時50-100ms
        if(strstr((const char *)buf,(const char*)ack)){
            rs485Send(buf,xlen);
            xlen = 0;
            memset(buf,0,DATALEN(buf));
            return true;    //返回TRUE說明wifi模組已有應答
        }

     return false;        //返回FALSE說明wifi模組沒有應答
 }

延時時間不夠長:下圖是微控制器給ESP8266模組傳送5次"AT+RST\r\n"指令,微控制器讀的太快,所以有時能讀到,有時讀不到,故需要把什麼的延時時間加長。

把延時時間稍微加長,確保能正確讀到ESP8266的應答資料,如下圖:

完結,問題圓滿解決!