STM32 HAL库 串口DMA(收发)和STM32串口中断接收(接收时间管理机制)+ESP8266 wifi模组通信问题
一、HAL庫(kù) 串口 DMA+ESP8266模組通信問題
用STM32 HAL庫(kù)串口的DMA發(fā)送和空閑中斷接收處理數(shù)據(jù),單片機(jī)發(fā)送AT指令給ESP8266 wifi模組問題:單片機(jī)連續(xù)幾次給wifi模組發(fā)送AT指令,wifi模塊總是少一次的應(yīng)答,在無線通信過程中是不方便和不允許的,因?yàn)樵谕ㄐ胚^程會(huì)通信不暢或中斷,如果要遠(yuǎn)程升級(jí)程序,這不能達(dá)到遠(yuǎn)程升級(jí)需求。部分程序如下:
int mian(void)
{
? ??for(n = 1; n <= 5;n++){
?? ??? ???printf("單片機(jī)給WIFI模塊發(fā)送第%d次AT指令!\r\n",n);
?? ??? ???DMA_usart3_send((uint8_t*)"AT+RST\r\n",sizeof("AT+RST\r\n")-1);? ? //單片機(jī)串口給wifi模組發(fā)送AT指令
?? ??? ???if(usart3_recv_end_flag == 1){? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //單片機(jī)是否接收到數(shù)據(jù)
? ? ? ? ? ? ? ??delay_ms(10);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//串口空閑中斷接收數(shù)據(jù)處理,稍微延時(shí)10ms
?? ??? ??? ??? ?usart3_recv_end_flag = 0;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //把接收完成標(biāo)志清零
?? ??? ??? ??? ?if(strstr((const char *)usart3_rx_buf,"OK")){? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //判斷wifi模組是否應(yīng)答
?? ??? ??? ??? ??? ???rs485_send(usart3_rx_buf,usart3_rx_len);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//把wifi模組應(yīng)答信息打印出來
? ? ? ? ? ? ? ? ? ? ? usart3_rx_len = 0;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//把接收數(shù)據(jù)長(zhǎng)度清零
?? ??? ??? ??? ??? ???memset(usart3_rx_buf,0,DATA_BUFFER_SIZE);? ? ? ? ? ? ? ? ? ? //把接收緩存器清零
?? ??? ??? ??? ??}
?? ??? ???}?? ?? ? ? ? ? ? ?
? ? ? ? delay_ms(500);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//延時(shí)100ms
?? ?}
}
?
單片機(jī)連續(xù)5次給wifi模組發(fā)送AT指令,但wifi模組只應(yīng)答4次,打印出來的數(shù)據(jù)如下:
問題分析:
剛開始分析時(shí),以為是單片機(jī)串口程序處理有問題,查找了兩天時(shí)間一直沒有找到問題,后把延時(shí)函數(shù)放在了前面,單片機(jī)給wifi模組發(fā)送一次AT指令,wifi模組就應(yīng)答一次。
分析:單片機(jī)給wifi模組發(fā)送AT指令后,需要稍微延時(shí)等待wifi模組應(yīng)答,讀的太快會(huì)讀不到wifi應(yīng)答的AT指令,會(huì)達(dá)不到研發(fā)要求。程序更改后,可以滿足開發(fā)需求。程序如下:
int mian(void)
{
? ? for(n = 1; n <= 5;n++){
?? ??? ??printf("單片機(jī)給WIFI模塊發(fā)送第%d次AT指令!\r\n",n);
?? ??? ??DMA_usart3_send((uint8_t*)"AT+RST\r\n",sizeof("AT+RST\r\n")-1);? ? //單片機(jī)串口給wifi模組發(fā)送AT指令
? ? ? ? ?delay_ms(10);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //串口空閑中斷接收數(shù)據(jù)處理,稍微延時(shí)10ms
?? ??? ??if(usart3_recv_end_flag == 1){? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //單片機(jī)是否接收到數(shù)據(jù)
?? ??? ??? ??? ?usart3_recv_end_flag = 0;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//把接收完成標(biāo)志清零
? ? ? ? ? ? ? ??if(strstr((const char *)usart3_rx_buf,"OK")){? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? //判斷wifi模組是否應(yīng)答
? ? ? ? ? ? ? ? ? ???rs485_send(usart3_rx_buf,usart3_rx_len);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//把wifi模組應(yīng)答信息打印出來
?? ??? ??? ??? ??? ??usart3_rx_len = 0;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//把接收數(shù)據(jù)長(zhǎng)度清零
?? ??? ??? ??? ??? ??memset(usart3_rx_buf,0,DATA_BUFFER_SIZE);? ? ? ? ? ? ? ? ? ??//把接收緩存器清零
?? ??? ??? ??? ??}
?? ??? ???}?? ? ? ? ? ??
? ? ? ? delay_ms(500);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //延時(shí)100ms
??? }
}
單片機(jī)連續(xù)5次給wifi模組發(fā)送AT指令,wifi模組應(yīng)答5次,打印出來的數(shù)據(jù)如下:
二、HAL庫(kù)?串口中斷(不用DMA,用串口接收中斷時(shí)間管理機(jī)制處理接收數(shù)據(jù))
在用串口中斷(接收數(shù)據(jù)幀用時(shí)間管理機(jī)制來實(shí)現(xiàn))時(shí),調(diào)了好半天沒調(diào)出來,單片機(jī)給ESP8266模組發(fā)送AT指令,然后單片機(jī)接收ESP8266模組的應(yīng)答,第一次總是接收不到,后面把下面用紅色標(biāo)出的延時(shí)時(shí)間加長(zhǎng),才準(zhǔn)確的接收ESP8266模組的應(yīng)答。才發(fā)現(xiàn)是讀的太快,還沒等ESP8266模組應(yīng)答,就去讀,所以讀不到ESP8266模組的應(yīng)答。如果是單片機(jī)給ESP8266模組發(fā)送“AT+RST\r\n”指令,需要等待500-1000ms的時(shí)間,才能準(zhǔn)確讀到ESP8266模組的應(yīng)答。
bool sendWifiCmd(uint8_t *cmd,uint16_t len,uint8_t *ack,uint16_t waittime) ? //單片機(jī)給wifi模組發(fā)送AT指令
{
?? ??? ?uint8_t xlen,buf[512];
?? ??? ?wifiSend(cmd,len);
?? ??? ?delay_ms(waittime);
//?? ? if(wifiAtAckCmp(ack)){
//?? ? ? ?return TRUE; ? ? ?//返回TRUE說明wifi模組已有應(yīng)答
//?? ? }
?? ??? ?xlen = wifiRead(buf,sizeof(buf));? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//串口中斷接收數(shù)據(jù)處理,延時(shí)50-100ms
?? ??? ?if(strstr((const char *)buf,(const char*)ack)){
?? ??? ??? ?rs485Send(buf,xlen);
?? ??? ??? ?xlen = 0;
?? ??? ??? ?memset(buf,0,DATALEN(buf));
?? ??? ??? ?return true; ? ?//返回TRUE說明wifi模組已有應(yīng)答
?? ??? ?}
?? ? return false; ? ? ? ?//返回FALSE說明wifi模組沒有應(yīng)答
?}
延時(shí)時(shí)間不夠長(zhǎng):下圖是單片機(jī)給ESP8266模組發(fā)送5次"AT+RST\r\n"指令,單片機(jī)讀的太快,所以有時(shí)能讀到,有時(shí)讀不到,故需要把什么的延時(shí)時(shí)間加長(zhǎng)。
?
把延時(shí)時(shí)間稍微加長(zhǎng),確保能正確讀到ESP8266的應(yīng)答數(shù)據(jù),如下圖:
完結(jié),問題圓滿解決!
?
總結(jié)
以上是生活随笔為你收集整理的STM32 HAL库 串口DMA(收发)和STM32串口中断接收(接收时间管理机制)+ESP8266 wifi模组通信问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 学习《FreeRTOS源码详解与应用开发
- 下一篇: STM32 HAL库--串口的DMA(发