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的應答資料,如下圖:
完結,問題圓滿解決!