C_Planet 2022-09-17 16:41 采纳率: 100%
浏览 107
已结题

关于#STM32wifi模块,WiFi模块初始化卡在循环里#的问题,如何解决?

问题遇到的现象和发生背景

STM32中用ESP8266模块连接TLINK平台,实现想要的效果。但是在测试wifi时,发现会卡在一个循环里面

用代码块功能插入代码,请勿粘贴截图
//main.c文件中的代码

#include "stm32f10x.h"
#include "Systick.h"
#include "usart.h"        
#include "pwm.h"
#include "NetWork.h"
#include "TLink.h"
#include "stdio.h"
#include "string.h"
#include "Delay.h"
#include "hx.h"
#include "step_motor.h"
#include "led.h"


DeviceSta_Strcture device = {0,120,0};

int main()
{
    Systick_init(72);
    initUART();
  initUART2();
  initNVIC(NVIC_PriorityGroup_2);//开启UART2的接收和空闲中断
//    TIM3_CH1_PWM_Init(20000-1,72-1);
    //舵机角度参数:19500-17500(前者为0°,后者为360°)
//    STEP_MOTOR_Init();
 initESP8266();
    LED_1(ON);
//  connectAP(SSID,PWD);
//  connectTlink();
//    sendDeviceStatus(&device);
//    TIM_SetCompare1(TIM3,19000);
//    Get_Maopi();                //称毛皮重量
//    Delay_ms(1000);
//    Delay_ms(1000);
//    Get_Maopi();                //重新获取毛皮重量
//    STEP_MOTOR_LOOP (1,1,1);//电机按圈数运行//LOOP是旋转多少圈

    while(1)
    { 
//        device.Shengyu = Get_Weight();
//        Delay_ms(1000);
//        sendDeviceStatus(&device);
    }


}


//
#include "string.h"
#include "NetWork.h"
#include "stm32f10x.h"  
#include "Delay.h"
#include "usart.h"
#include "led.h"



u8 TXBuffer[TXBUFFER_LEN] = {0};  //网络通信数据发送缓冲
u8 RXBuffer[RXBUFFER_LEN] = {0};  //网络通信数据接收缓懆ҍ

/**
 * 功能:查找字符串中是否包含另一个字符串
 * 参数:
 *       dest:待查找目标字符串
 *       src:待查找内容
 *       retry_cn:查询超时时间
 * 返回值:查找结果,非0为查找成功,0为失败
 * 说明:
 *       当发出一个AT指令后,需要一段时间等待ESP8266回复,因此就需要等待一段时间,
 *       这个时间通常是几百ms(除了连接服务器和AP指令),本程序一般指令通常等待
 *       2S,耗时的连接AP和服务器的设置等待为8S,其实花不了那么多时间,但如果发生超时
 *       就一定可以判断是通信问题
 */
u8 findStr(u8* dest,u8* src,u16 retry_cn)
{
    u16 retry = retry_cn;                   //超时时间
    u8 result_flag = 0;                     //查找结果

    while(strstr(dest,src)==0 && --retry!=0)//等待串口接收完毕或超时退出
    {
        Delay_ms(10);
    }

   if(retry==0)                            //如果超时则有问题,此时返回0
   {
       return 0;
   }
   result_flag = 1;                        //执行到这里说明一切正常, 表示查找成功

    if(result_flag)
    {

        return 1;
    }else 
    {
        return 0;
    }
}


/**
 * 功能:初始化ESP8266
 * 参数:None
 * 返回值:初始化结果,非0为初始化成功,0为失败
 */
void initESP8266(void)
{
    sendString(USART2,"+++");          //退出透传 
    Delay_ms(500);
    sendString(USART2,"AT+RST\r\n");   //重启ESP8266 
    Delay_ms(3000);
  checkESP8266();            //使用AT指令检查ESP8266是否孍

    memset(RXBuffer,0,RXBUFFER_LEN);   //清空接收缓冲
    sendString(USART2,"ATE0\r\n");     //关闭回显  
    while(findStr(RXBuffer,"OK",300)==0)  //设置不成功
    {
        sendString(USART2,"ATE0\r\n");
                Delay_ms(3000);
    }
    

//    if(findStr(RXBuffer,"OK",300)==0)  //设置不成势
//    {
////        sendString(USART2,"ATE0\r\n");
////                Delay_ms(3000);
////            LED_1(ON);
//    }

//}


 * 功能:检查ESP8266是否正常
 * 参数:None
 * 返回值:ESP8266返回状态
 *        0 ESP8266正常
 *        0 ESP8266有问题  
 */
void checkESP8266(void)
{
    memset(RXBuffer,0,RXBUFFER_LEN); //清空接收缓冲

    sendString(USART2,"AT\r\n");     //发送AT握手指令

    while(findStr(RXBuffer,"OK",500)==0)//ESP8266正常
    {
        sendString(USART2,"AT\r\n"); 
        Delay_ms(500);            
    }                            //ESP8266不正常 
}
//    if(findStr(RXBuffer,"OK",500)==1)//ESP8266正常
//    {
////        sendString(USART2,"AT\r\n"); 
////        Delay_ms(500);            
//            LED_1(ON);

//    }                            //ESP8266不正常 
//}


/**
 * 功能:连接热点
 * 参数:
 *         ssid:热点名
 *         pwd:热点密码
 * 返回值:
 *         连接结果,非0连接成功,0连接失败
 * 说明: 
 *         失败的原因有以下几种(UART通信和ESP8266正常情况下)
 *         1. WIFI名和密码不正确
 *         2. 路由器连接设备太多,未能给ESP8266分配IP
 */
void connectAP(u8* ssid,u8* pwd)
{
    memset(RXBuffer,0,RXBUFFER_LEN);                       
    sendString(USART2,"AT+CWMODE?\r\n");                       //查询此时WIFI工作模式
    if(findStr(RXBuffer,"CWMODE:1",200)==0)                    //如果此时不是MODE1模式,即不是STATION模式
    {
        memset(RXBuffer,0,RXBUFFER_LEN);     
        sendString(USART2,"AT+CWMODE_CUR=1\r\n");              //设置为STATION模式
        if(findStr(RXBuffer,"OK",200)==0)
        {
                    sendString(USART2,"AT+CWMODE_CUR=1\r\n");                         //设置为STATION模式
                    Delay_ms(800);

        }       
                sendString(USART2,"AT+RST\r\n");   //重启ESP8266 
                
    }

    memset(TXBuffer,0,RXBUFFER_LEN);                            //清空发送缓冲
    memset(RXBuffer,0,RXBUFFER_LEN);                            //清空接收缓冲
    sprintf(TXBuffer,"AT+CWJAP_CUR=\"%s\",\"%s\"\r\n",ssid,pwd);//连接目标AP
    sendString(USART2,TXBuffer);
    while(findStr(RXBuffer,"OK",800)==0)                           //连接成功且分配到IP
    {
        sendString(USART2,TXBuffer);
              Delay_ms(800);
    }
}

/**
 * 功能:使用指定协议(TCP/UDP)连接到服务器
 * 参数:
 *         mode:协议类型 "TCP","UDP"
 *         ip:目标服务器IP
 *         port:目标是服务器端口号
 * 返回值:
 *         连接结果,非0连接成功,0连接失败
 * 说明: 
 *         失败的原因有以下几种(UART通信和ESP8266正常情况下)
 *         1. 远程服务器IP和端口号有误
 *         2. 未连接AP
 *         3. 服务器端禁止添加(一般不会发生)
 */
void connectServer(u8* mode,u8* ip,u16 port)
{
    memset(RXBuffer,0,RXBUFFER_LEN);      
    memset(TXBuffer,0,RXBUFFER_LEN);   

    sendString(USART2,"+++");                   //多次连接需退出透传
    Delay_ms(500);
    /*格式化待发送AT指令*/    
    sprintf(TXBuffer,"AT+CIPSTART=\"%s\",\"%s\",%d\r\n",mode,ip,port);
    sendString(USART2,TXBuffer);
    while(findStr(RXBuffer,"CONNECT",800)==0)
    {
        sendString(USART2,TXBuffer);
              Delay_ms(800);
                
    }
        memset(RXBuffer,0,RXBUFFER_LEN);    
    sendString(USART2,"AT+CIPMODE=1\r\n");  //设置为透传模式
        while(findStr(RXBuffer,"OK",300)==0)
        {
                sendString(USART2,"AT+CIPMODE=1\r\n");
                Delay_ms(300);
            
         }
    
        memset(RXBuffer,0,RXBUFFER_LEN); 
        sendString(USART2,"AT+CIPSEND\r\n");//开始处于透传发送状怿
//            while(findStr(RXBuffer,">",200)==0)
//            {        
//                            
//        } 
}


/**
 * 功能:透传模式下的数据发送函数
 * 参数:
 *      buffer:待发送数据
 * 返回值:None
 */
void sendBuffertoServer(u8* buffer)
{
    memset(RXBuffer,0,RXBUFFER_LEN);
    sendString(USART2,buffer); 
}




//串口中断函数

void USART2_IRQHandler(void)
{
    static u8 i = 0;

    if(USART_GetITStatus(USART2, USART_IT_RXNE)) //判断接收数据寄存器是否有数据
    {
        RXBuffer[i++] = USART_ReceiveData(USART2);
        if(i==RXBUFFER_LEN)                     //超出接收缓冲范围,可能的情形是ESP8266复位,为防止溢出必须设置索引                  
        {
            i = RXBUFFER_LEN-1;
        }
    }

    if(USART_GetITStatus(USART2, USART_IT_IDLE))
    {
        USART_ReceiveData(USART2);              //读一次UART可以清除空闲标志位
        i = 0;
        processDeviceStatus(&device);
    } 
}


运行结果及报错内容

发现灯在initESP8266();后不能点亮

我的解答思路和尝试过的方法

以为是模块损坏,用wifi模块直接连接电脑,用串口助手手动发送可以实现目的。但是用串口2在内部发送的时候却不能达到目的。检查了硬件连接,没有错误。
我将wifi初始化中的循环去掉,wifi还是没有连接上TLINK

后面重新写了初始化ESP8266的程序

void initESP8266()
{
    Usart_SendStr(USART2, "+++");//退出透传
    Delay_ms(500);
    Usart_SendStr(USART2,"AT\r\n");     //发送AT握手指令
    Delay_ms(500);    
  Usart_SendStr(USART2,"AT+CWMODE_CUR=1\r\n");              //设置为STATION模式
    Delay_ms(800);
    Usart_SendStr(USART2,"AT+RST\r\n");   //重启ESP8266 
    Delay_ms(3000);
    Usart_SendStr(USART2,"AT+CWJAP_CUR=\"1234\",\"12345678\"\r\n");//连接目标AP
    Delay_ms(800);
    Usart_SendStr(USART2,"AT+CIPSTART=\"TCP\",\"tcp.tlink.io\",8647\r\n");//连接平台
    Delay_ms(800);
    Usart_SendStr(USART2,"AT+CIPMODE=1\r\n"); 
  Delay_ms(200);
    Usart_SendStr(USART2,"AT+CIPSEND\r\n");  
    Delay_ms(200);
  Usart_SendStr(USART2,"HQ6XWWY8N1EJ4H5G\r\n");//连接平台
    Delay_ms(800);

}




```c
//发送字符串

void Usart_SendByte(USART_TypeDef* pUSARTx, uint8_t data)
{
    USART_SendData(pUSARTx, data);
    while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET );
}

/* 发送两个字节的数据 */
void Usart_SendHalfWord(USART_TypeDef* pUSARTx, uint16_t data)
{
    uint8_t temp_h,temp_l;
    
    temp_h = (data&0xff00) >> 8 ;
    temp_l = data&0xff;
    
    USART_SendData(pUSARTx, temp_h);
    while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET );
    
    USART_SendData(pUSARTx, temp_l);
    while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET );
}

/* 发送8位数据的数组 */
void Usart_SendArray(USART_TypeDef* pUSARTx, uint8_t *array,uint8_t num)
{
    uint8_t i;
    for( i=0; i<num; i++ )
  {
        Usart_SendByte(pUSARTx, array[i]);
    }
    while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TC) == RESET );
}

/* 发送字符串 */
void Usart_SendStr(USART_TypeDef* pUSARTx, uint8_t *str)
{
    uint8_t i=0;
    do
  {
        Usart_SendByte(pUSARTx, *(str+i));
        i++;
    }while(*(str+i) != '\0');
    while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TC) == RESET );
}

我想要达到的结果

wifi初始化成功

  • 写回答

3条回答 默认 最新

  • Flyshine~ 2022-09-18 11:14
    关注

    仿真停下来看看在哪个死循环里面,
    那个查找字符串的函数能确保正确吗? 可以尝试用标准库函数去查找字符串。
    串口接收需要对回车换行归零操作,建议把串口中断代码也贴上来。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 10月3日
  • 已采纳回答 9月25日
  • 修改了问题 9月18日
  • 修改了问题 9月18日
  • 展开全部

悬赏问题

  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名
  • ¥65 汇编语言除法溢出问题
  • ¥15 Visual Studio问题