#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