STM32
直播中

李秀兰

7年用户 1399经验值
私信 关注
[问答]

STM32F103如何驱动ESP8266连接贝壳物联?

STM32F103如何驱动ESP8266连接贝壳物联?

回帖(1)

周必镜

2021-12-14 11:10:03

#include "ESP8266.h"


uint8_t TXBuffer[TXBUFFER_LEN] = {0};  //网络通信数据发送缓冲
uint8_t RXBuffer[RXBUFFER_LEN] = {0};  //网络通信数据接收缓冲
uint8_t HandCMD[10]="ATrn";
uint8_t HandACK[2]="OK";
uint8_t QuitUnvarnishedTransCMD[5]="+++";
uint8_t ResetCMD[10]="AT+RSTrn";
/**
* 功能:指定某个UART发送一个字节
* 参数:USARTx:使用的目标串口x为1-3
*       byte:待发送字节
* 返回值:None
*/
void USART_SendByte(USART_TypeDef *USARTx, uint8_t byte)
{
        while(!LL_USART_IsActiveFlag_TXE(USARTx));
        LL_USART_TransmitData8(USARTx,byte);
}
/**
* 功能:指定某个串口发送字符串
* 参数:USARTx:使用的目标串口x为1-3
*       str:字符串指针
* 返回值:None
*/
void USART_SendString(USART_TypeDef *USARTx, uint8_t *str)
{
    while (*str)
    {
        USART_SendByte(USARTx,*str++);
    }
}


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


   if(OverTime==0)                            //如果超时则有问题,此时返回0
   {
       return 0;
   }
   return 1;                        //执行到这里说明一切正常, 表示查找成功
}
/**
* 功能:检查ESP8266是否正常
* 参数:None
* 返回值:ESP8266返回状态
*        非0 ESP8266正常
*        0 ESP8266有问题  
*/
uint8_t CheckESP8266(void)
{
    memset(RXBuffer,0,RXBUFFER_LEN);                                         //清空接收缓冲
    USART_SendString(Wifi_USART,HandCMD);     //发送AT握手指令
    if(CompareStr(RXBuffer,HandACK,200)!=0)                //ESP8266正常
    {
        return 1;  
    }else                                                                    //ESP8266不正常
    {
        return 0;
    }
}
/**
* 功能:初始化ESP8266
* 参数:None
* 返回值:初始化结果,非0为初始化成功,0为失败
*/
uint8_t ESP8266Init(void)
{
        USART_SendString(Wifi_USART,QuitUnvarnishedTransCMD);   //退出透传
  LL_mDelay(500);
        USART_SendString(Wifi_USART,ResetCMD);   //重启ESP8266
        LL_mDelay(500);
        if(CheckESP8266()==0)                                      //使用AT指令检查ESP8266是否存在
        {
                        return 0;
        }
        memset(RXBuffer,0,RXBUFFER_LEN);                           //清空接收缓冲
        USART_SendString(Wifi_USART,(uint8_t*)"ATE0rn");             //关闭回显  
        if(CompareStr(RXBuffer,(uint8_t*)"OK",200)==0)                                  //设置不成功
        {
                        return 0;      
        }
        return 1;                                                                                                                 //设置成功
}




//void ProcessDevice(DeviceStruct *DS)
//{
//    uint8_t i = 0;
//    /*对应状态控制*/
//    if((uint8_t)strstr(RXBuffer,"RELAY1_ON"))
//    {
//        i = 1;
//        DS->Relay1 = 1;
//        setRelay(RELAY1,RELAY_CLOSE);
//        
//    }else if((uint8_t)strstr(RXBuffer,"RELAY1_OFF"))
//    {
//        i = 1;
//        DS->Relay1 = 0;
//        setRelay(RELAY1,RELAY_OPEN);
//    }
//   
//    if((uint8_t)strstr(RXBuffer,"RELAY2_ON"))
//    {
//        i = 1;
//        DS->Relay2 = 1;
//        setRelay(RELAY2,RELAY_CLOSE);
//    }else if((uint8_t)strstr(RXBuffer,"RELAY2_OFF"))
//    {
//        i = 1;
//        DS->Relay2 = 0;
//        setRelay(RELAY2,RELAY_OPEN);
//    }
//   
//    /*清除接收缓冲并更新继电器状态到服务器*/
//    if(i!=0)
//    {
//    memset(RXBuffer,0,RXBUFFER_LEN);
//                sendDevice(&device);
//    }   
//}


/**
* 功能:恢复出厂设置
* 参数:None
* 返回值:None
* 说明:此时ESP8266中的用户设置将全部丢失回复成出厂状态
*/
void ESP8266Restart(void)
{
        USART_SendString(Wifi_USART,(uint8_t*)"+++");           //退出透传
  LL_mDelay(500);
        USART_SendString(Wifi_USART,(uint8_t*)"AT+RESTORErn");//恢复出厂
  NVIC_SystemReset();                 //同时重启单片机   
}
/**
* 功能:连接热点
* 参数:
*         ssid:热点名
*         pwd:热点密码
* 返回值:
*         连接结果,非0连接成功,0连接失败
* 说明:
*         失败的原因有以下几种(UART通信和ESP8266正常情况下)
*         1. WIFI名和密码不正确
*         2. 路由器连接设备太多,未能给ESP8266分配IP
*/
uint8_t ConnectAP(uint8_t* ssid,uint8_t* pwd)
{
    memset(RXBuffer,0,RXBUFFER_LEN);                       
    USART_SendString(Wifi_USART,(uint8_t*)"AT+CWMODE?rn");                       //查询此时WIFI工作模式
    if(CompareStr(RXBuffer,(uint8_t*)"CWMODE:1",200)==0)                    //如果此时不是MODE1模式,即不是STATION模式
    {
        memset(RXBuffer,0,RXBUFFER_LEN);     
        USART_SendString(Wifi_USART,(uint8_t*)"AT+CWMODE_CUR=1rn");              //设置为STATION模式
        if(CompareStr(RXBuffer,(uint8_t*)"OK",200)==0)
        {
            return 0;
        }            
    }
    memset(RXBuffer,0,RXBUFFER_LEN);                            //清空接收缓冲
    sprintf((char*)TXBuffer,(const char*)"AT+CWJAP_CUR="%s","%s"rn",ssid,pwd);//连接目标AP
    USART_SendString(Wifi_USART,TXBuffer);
    if(CompareStr(RXBuffer,(uint8_t*)"OK",800)!=0)                           //连接成功且分配到IP
    {
        return 1;
    }
                return 0;
}


/**
* 功能:使用指定协议(TCP/UDP)连接到服务器
* 参数:
*         mode:协议类型 "TCP","UDP"
*         ip:目标服务器IP
*         port:目标是服务器端口号
* 返回值:
*         连接结果,非0连接成功,0连接失败
* 说明:
*         失败的原因有以下几种(UART通信和ESP8266正常情况下)
*         1. 远程服务器IP和端口号有误
*         2. 未连接AP
*         3. 服务器端禁止添加(一般不会发生)
*/
uint8_t ConnectServer(uint8_t* mode,uint8_t* ip,uint16_t port)
{     
    memset(TXBuffer,0,RXBUFFER_LEN);   
   
    USART_SendString(Wifi_USART,QuitUnvarnishedTransCMD);                   //多次连接需退出透传
    LL_mDelay(500);
    /*格式化待发送AT指令*/   
    sprintf((char*)TXBuffer,"AT+CIPSTART="%s","%s",%drn",mode,ip,port);
    USART_SendString(Wifi_USART,TXBuffer);
    if(CompareStr(RXBuffer,(uint8_t*)"CONNECT",800)!=0)
    {
        memset(RXBuffer,0,RXBUFFER_LEN);   
        USART_SendString(Wifi_USART,(uint8_t*)"AT+CIPMODE=1rn");  //设置为透传模式
        if(CompareStr(RXBuffer,(uint8_t*)"OK",200)!=0)
        {
            memset(RXBuffer,0,RXBUFFER_LEN);
            USART_SendString(Wifi_USART,(uint8_t*)"AT+CIPSENDrn");//开始处于透传发送状态
            if(CompareStr(RXBuffer,(uint8_t*)">",200)!=0)
            {
                return 1;
            }else
            {
                return 0;
            }   
        }else
        {
            return 0;
        }
        
    }else
    {
        return 0;
    }
}


/**
* 功能:主动和服务器断开连接
* 参数:None
* 返回值:
*         连接结果,非0断开成功,0断开失败
*/
uint8_t DisconnectServer(void)
{
    USART_SendString(Wifi_USART,QuitUnvarnishedTransCMD);            //退出透传
    LL_mDelay(500);
    memset(RXBuffer,0,RXBUFFER_LEN);  
    USART_SendString(Wifi_USART,(uint8_t*)"AT+CIPCLOSErn");//关闭链接


    if(CompareStr(RXBuffer,(uint8_t*)"CLOSED",200)!=0)//操作成功,和服务器成功断开
    {
        return 1;
    }else
    {
        return 0;
    }
}


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


/**
* 功能:处理服务器发回来的控制指令
* 参数:None
* 返回值:None
*/
void ProcessServerBuffer(void)
{
    uint8_t i = 0;


    /*LED状态控制*/
    if(strstr((const char*)RXBuffer,(const char*)"LED_ON"))
    {
        ++i;
       // openLED();
    }else if(strstr((const char*)RXBuffer,(const char*)"LED_OFF"))
    {
        ++i;
       // closeLED();
    }else
    {


    }
   
    /*继电器1状态控制*/
    if(strstr((const char*)RXBuffer,(const char*)"RELAY1_CLOSE"))
    {
        ++i;
//        setRelay(RELAY1,RELAY_CLOSE);
    }else if(strstr((const char*)RXBuffer,(const char*)"RELAY1_OPEN"))
    {
        ++i;
//        setRelay(RELAY1,RELAY_OPEN);
    }else
    {


    }


    /*继电器2状态控制*/
    if(strstr((const char*)RXBuffer,(const char*)"RELAY2_CLOSE"))
    {
        ++i;
//        setRelay(RELAY2,RELAY_CLOSE);
    }else if(strstr((const char*)RXBuffer,(const char*)"RELAY2_OPEN"))
    {
        ++i;
//        setRelay(RELAY2,RELAY_OPEN);
    }else
    {
        
    }  


    /*只在接收控制指令时才清空,这样可避免接收AT指令时导致失败*/
    if(i!=0)
    {
        memset(RXBuffer,0,RXBUFFER_LEN);
    }         
}
#ifndef _ESP8266_H_
#define _ESP8266_H_


#include "main.h"


#define RXBUFFER_LEN        200
#define TXBUFFER_LEN        200


#define Wifi_USART                USART2






void ESP8266Restart(void);
uint8_t ConnectAP(uint8_t* ssid,uint8_t* pwd);
uint8_t ConnectServer(uint8_t* mode,uint8_t* ip,uint16_t port);
uint8_t DisconnectServer(void);
void SendStrToServer(uint8_t* buffer);
void ProcessServerBuffer(void);
void USART_SendByte(USART_TypeDef *USARTx, uint8_t byte);
void USART_SendString(USART_TypeDef *USARTx, uint8_t *str);
uint8_t CompareStr(uint8_t* dest,uint8_t* src,uint16_t OverTime);


#endif
举报

更多回帖

发帖
×
20
完善资料,
赚取积分