作者:xyy840948307 | 更新时间:2016-08-02 | 浏览量:5317
#include "common.h"
#include "HC74HC.h"
#include "24cxx.h"
///////////////////////////////////////////////////////////////////////////////////////////////////////////
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32开发板
//ATK-ESP8266 WIFI模块 公用驱动代码
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//修改日期:2014/4/3
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2009-2019
//All rights reserved
///////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////
//用户配置区
const u8* reply0="无法识别的指令";
const u8* reply1="屏幕已开";
const u8* reply2="屏幕已关";
const u8* reply3="灯已打开";
const u8* reply4="灯已关闭";
const u8* reply9="灯已打开10s";
const u8* reply10="蜂鸣器开启1s";
//用户配置区
//const u8* esp8266_="{\"M\":\"say\",\"ID\":\"U397\",\"C\":\"LED OK\\u6536\\u5230\\u6570\\u636e\",\"SIGN\":\"123\"}";//路由器SSID号
const u8* esp8266_="{\"M\":\"say\",\"ID\":\"U397\",\"C\":\"LED OK收到数据\",\"SIGN\":\"123\"}";//路由器SSID号
//连接端口号:8086,可自行修改为其他端口.apiKey
_ESP8266 ESP8266;
//连接端口号:8086,可自行修改为其他端口.apiKey
const u8* portnum="8086";
//bigiod_ip和端口
const u8* bigiod_ip="www.bigiot.net";//路由器SSID号device
const u8* bigiod_portnum="8181";//wpa/wpa2 aes加密方式
//bigiod登录指令
const u8* bigiod_ID="398";//wpa/wpa2 aes加密方式
const u8* bigiod_apiKey="d12a86c9d";//wpa/wpa2 aes加密方式
//WIFI STA模式,设置要去连接的路由器无线参数,请根据你自己的路由器设置,自行修改.
const u8* wifista_ssid="cengnimabi";//路由器SSID号
const u8* wifista_encryption="wpawpa2_aes";//wpa/wpa2 aes加密方式
const u8* wifista_password="Jang@Luo?515@Zhou"; //连接密码
//WIFI AP模式,模块对外的无线参数,可自行修改.
const u8* wifiap_ssid="XYY-ESP8266";//对外SSID号
const u8* wifiap_encryption="wpawpa2_aes";//wpa/wpa2 aes加密方式
const u8* wifiap_password="12345678"; //连接密码
///////////////////////////////////////////////////////////////////////////////////////////////////////////
//4个网络模式
const u8 *ATK_ESP8266_CWMODE_TBL[3]={"STA模式 ","AP模式 ","AP&STA模式 "};//ATK-ESP8266,3种网络模式,默认为路由器(ROUTER)模式
//4种工作模式
const u8 *ATK_ESP8266_WORKMODE_TBL[3]={"TCP服务器","TCP客户端"," UDP 模式"};//ATK-ESP8266,4种工作模式
//5种加密方式
const u8 *ATK_ESP8266_ECN_TBL[5]={"OPEN","WEP","WPA_PSK","WPA2_PSK","WPA_WAP2_PSK"};
///////////////////////////////////////////////////////////////////////////////////////////////////////////
//usmart支持部分
//将收到的AT指令应答数据返回给电脑串口
//mode:0,不清零USART2_RX_STA;
// 1,清零USART2_RX_STA;
void atk_8266_at_response(u8 mode)
{
if(USART2_RX_STA&0X8000)//接收到一次数据了
{
USART2_RX_BUF[USART2_RX_STA&0X7FFF]=0;//添加结束符
printf("%s\r\n\r\n",USART2_RX_BUF);//发送到串口
if(mode)USART2_RX_STA=0;
}
}
//ATK-ESP8266??????
//???:0,????;
// 1,????
u8 atk_8266_quit_trans(void)
{
while((USART2->SR&0X40)==0);//?????
USART2->DR='+';
delay_ms(15);//????????(10ms)
while((USART2->SR&0X40)==0);//?????
USART2->DR='+';
delay_ms(15);//????????(10ms)
while((USART2->SR&0X40)==0);//?????
USART2->DR='+';
delay_ms(500);//??500ms
return atk_8266_send_cmd("AT","OK",20);//??????.
}
//ATK-ESP8266发送命令后,检测接收到的应答
//str:期待的应答结果
//返回值:0,没有得到期待的应答结果
// 其他,期待应答结果的位置(str的位置)
u8* atk_8266_check_cmd(u8 *str)
{
char *strx=0;
if(USART2_RX_STA&0X8000)//接收到一次数据了
{
USART2_RX_BUF[USART2_RX_STA&0X7FFF]=0;//添加结束符
strx=strstr((const char*)USART2_RX_BUF,(const char*)str);
}
return (u8*)strx;
}
//向ATK-ESP8266发送命令
//cmd:发送的命令字符串
//ack:期待的应答结果,如果为空,则表示不需要等待应答
//waittime:等待时间(单位:10ms)
//返回值:0,发送成功(得到了期待的应答结果)
// 1,发送失败
u8 atk_8266_send_cmd(u8 *cmd,u8 *ack,u16 waittime)
{
u8 res=0;
USART2_RX_STA=0;
u2_printf("%s\r\n",cmd);//发送命令
if(ack&&waittime)//需要等待应答
{
while(--waittime)//等待倒计时
{
delay_ms(10);
if(USART2_RX_STA&0X8000)//接收到期待的应答结果
{
if(atk_8266_check_cmd(ack))
{
//printf("ack:%s\r\n",(u8*)ack);
break;//得到有效数据
}
USART2_RX_STA=0;
}
}
if(waittime==0)res=1;
}
return res;
}
//向ATK-ESP8266发送指定数据
//data:发送的数据(不需要添加回车了)
//ack:期待的应答结果,如果为空,则表示不需要等待应答
//waittime:等待时间(单位:10ms)
//返回值:0,发送成功(得到了期待的应答结果)luojian
u8 atk_8266_send_data(u8 *data,u8 *ack,u16 waittime)
{
u8 res=0;
USART2_RX_STA=0;
u2_printf("%s",data);//发送命令
if(ack&&waittime)//需要等待应答
{
while(--waittime)//等待倒计时
{
delay_ms(10);
if(USART2_RX_STA&0X8000)//接收到期待的应答结果
{
if(atk_8266_check_cmd(ack))break;//得到有效数据
USART2_RX_STA=0;
}
}
if(waittime==0)res=1;
}
return res;
}
////wifi帐号密码设置
u8 ESP8266_init(void)
{
u8 *p,*wifi_ssid,*wifi_password;
u8 k=0;
wifi_ssid=mymalloc(SRAMIN,50);//申请32字节内存
wifi_password=mymalloc(SRAMIN,50);//申请32字节内存
AT24CXX_Read(400,wifi_ssid,50);
AT24CXX_Read(450,wifi_password,50);
LCD_ShowString(5,285,240,16,16,wifi_ssid,0);
LCD_ShowString(5,305,240,16,16,wifi_password,0);
//ESP8266.wifista_ssid=(u8* )wifista_ssid, ESP8266.wifista_password=(u8* )wifista_password;
ESP8266.wifista_ssid=(u8* )wifi_ssid;
ESP8266.wifista_password=(u8* )wifi_password;
while(atk_8266_send_cmd("AT","OK",20))//检查WIFI模块是否在线
{
atk_8266_quit_trans();//退出透传
atk_8266_send_cmd("AT+CIPMODE=0","OK",200); //关闭透传模式
delay_ms(10);
}
while(atk_8266_send_cmd("ATE0","OK",20));//关闭回显
p=mymalloc(SRAMIN,64);//申请32字节内存
atk_8266_send_cmd("AT+CWMODE=1","OK",50);//设置WIFI STA模式
atk_8266_send_cmd("AT+RST","OK",20);//DHCP服务器关闭(仅AP模式有效)
delay_ms(3000); //延时3S等待重启成功
printf("正在获取IP\r\n");
sprintf((char*)p,"AT+CWJAP=\"%s\",\"%s\"",ESP8266.wifista_ssid,ESP8266.wifista_password);//设置无线参数:ssid,密码
if(atk_8266_send_cmd(p,"WIFI CONNECTED",500)==0)goto AA25;//连接目标路由器,并且获得IP//
if(atk_8266_send_cmd(p,"WIFI GOT IP",500)==0) goto AA25;//连接目标路由器,并且获得IP//
k=1, printf("获取IP失败\r\n");
goto AA24;
AA25://WIFI获得IP
printf("获取IP成功\r\n");
delay_ms(1000);
atk_8266_send_cmd("AT+CIPMUX=0","OK",200); //0:单连接,1:多连接
printf("正在连接!\r\n");
sprintf((char*)p,"AT+CIPSTART=\"TCP\",\"%s\",%s",(u8*)bigiod_ip,(u8*)bigiod_portnum); //配置目标TCP服务器
if(atk_8266_send_cmd(p,"WELCOME TO BIGIOT",200)==0) goto AA26; //得到有效数据
if(atk_8266_send_cmd(p,"ALREADY CONNECTED",200)==0) goto AA26; //得到有效数据
k=1; printf("连接失败!\r\n");
goto AA24;//连接失败跳转到末尾
AA26:
printf("连接成功!\r\n");
atk_8266_send_cmd("AT+CIPMODE=1","OK",20); //传输模式为:透传
atk_8266_send_cmd("AT+CIPSEND",">",20); //开始透传
delay_ms(500);
k=ESP8266_login();
AA24:
myfree(SRAMIN,wifi_password); //释放32字节内存
myfree(SRAMIN,wifi_ssid); //释放32字节内存
myfree(SRAMIN,p); //释放32字节内存
if(k==0) ESP8266.DISCONNECT_T=0;
return k ;
}
//ATK-ESP8266初始化函数
u8 ESP8266_connect(void)
{
u8 *ser;
u8 k;
while(atk_8266_send_cmd("AT","OK",20))//检查WIFI模块是否在线
{
atk_8266_quit_trans();//退出透传
delay_ms(10);
}
ser=mymalloc(SRAMIN,64); //申请32字节内存
atk_8266_send_cmd("AT+CWMODE=1","OK",50);//设置WIFI STA模式
atk_8266_send_cmd("AT+RST","OK",20); //DHCP服务器关闭(仅AP模式有效)
delay_ms(5000); //延时3S等待重启成功
k=1,printf("正在连接!!!\r\n");
sprintf((char*)ser,"AT+CIPSTART=\"TCP\",\"%s\",%s",(u8*)bigiod_ip,(u8*)bigiod_portnum); //配置目标TCP服务器
if(atk_8266_send_cmd(ser,"CONNECT",200)==0) goto AA22; //得到有效数据
if(atk_8266_send_cmd(ser,"ALREADY CONNECTED",200)==0) goto AA22; //得到有效数据
if(atk_8266_send_cmd(ser,"WELCOME TO BIGIOT",200)==0) goto AA22; //得到有效数据
if(atk_8266_send_cmd(ser,"no ip",100)==0) ESP8266.enforce=5,k=2; //无IP需要立即进行初始化操作,强制初始化
printf("连接失败!!!\r\n");
goto AA21;//连接失败跳转到末尾
AA22:
k=0,printf("连接成功!!!\r\n");
atk_8266_send_cmd("AT+CIPMODE=1","OK",20); //传输模式为:透传
atk_8266_send_cmd("AT+CIPSEND",">",20); //开始透传
delay_ms(500);
k=ESP8266_login(); //登录
AA21:
myfree(SRAMIN,ser); //释放32字节内存connected
if(k==0) ESP8266.DISCONNECT_T=0;
return k ;
}
//登录贝壳服务器函数
u8 ESP8266_login(void)
{
u8 *p,*str;
u8 k=0,n;
p=mymalloc(SRAMIN,64); //申请32字节内存
str=mymalloc(SRAMIN,32); //申请32字节内存
sprintf((char*)p,"{\"M\":\"checkin\",\"ID\":\"%s\",\"K\":\"%s\"}",bigiod_ID,(u8*)bigiod_apiKey);//登录指令
sprintf((char*)str,"\"ID\":\"D%s\"",bigiod_ID);//登录指令
AA27:
n=12;
printf("登录\r\n");
while(n)
{
if(atk_8266_send_cmd(p,str,200)==0) break;
n--;
}
if(n==0)
{
k=1,printf("登录失败???\r\n");
if(ESP8266_check("connected")==0) goto AA27;
}
else k=0,printf("登录成功!!!\r\n");
myfree(SRAMIN,str); //释放32字节内存connected
myfree(SRAMIN,p); //释放32字节内存connected
if(k==0) ESP8266.DISCONNECT_T=0;
return k ;
}
//ATK-ESP8266初始化函数
void SetWifi_IdPass(u8 *wifiId,u8 *Pass)
{
u8 *wifitemp;
u8 n=0;
wifitemp=wifiId;
while(*wifitemp)
{
n++;
wifitemp++;
if(n>=49)
{
*wifitemp=0; //超过最大计数强制添加结束符号
break;
}
}
AT24CXX_Write(400,wifiId,n+1); //结束符号同时存入AT24,方便读取结束符号
n=0;
wifitemp=Pass;
while(*wifitemp)
{
n++;
wifitemp++;
if(n>=49)
{
*wifitemp=0; //超过最大计数强制添加结束符号
break;
}
}
AT24CXX_Write(450,Pass,n+1); //结束符号同时存入AT24,方便读取结束符号
ESP8266.enforce=5; //强制ESP8266进行初始化
}
//ATK-ESP8266初始化函数
u8 ESP8266_check(u8* str)
{
u8 k;
k=atk_8266_send_cmd("{\"M\":\"status\"}",(u8*)str,200);//检测心跳
return k ;
}
//ESP8266检查保持在线函数,单位S,内部已经延时45s,未登录内部循环10s。
void ESP8266_hold(void)
{
u8 k;
AA18:
ESP8266.status=8;//默认有心跳
k=ESP8266_check("checked");//检测心跳
if(k==0) ESP8266.DISCONNECT_T=0; //有心跳
if((k!=0)&&(ESP8266.DISCONNECT_T==0))
{
ESP8266.DISCONNECT_T++; //无心跳计时
ESP8266.DISCONNECT_C++; //掉线次数+1
}
if(ESP8266.DISCONNECT_T>60) ESP8266.status=7;//无心跳需要重新登录
if(ESP8266.DISCONNECT_T>300) ESP8266.status=6;//无心跳需要重新连接
if(ESP8266.DISCONNECT_T>600) ESP8266.status=5;//无心跳需要重新初始化
if(ESP8266.enforce) ESP8266.status=ESP8266.enforce;//强制选项条件
if(ESP8266.enforce) ESP8266.DISCONNECT_T++; //无心跳计时
if(ESP8266.enforce) ESP8266.enforce=0;//强制选项条件清空
//选择操作内容
switch(ESP8266.status)
{
case 5:
while(ESP8266_init())
{
delay_ms(30000);
if(ESP8266_check("checked")==0) goto AA18 ;//检测心跳
delay_ms(30000);
}
goto AA18 ;
case 6:
ESP8266_connect();// 超过300s重新连接服务器
delay_ms(10000);
goto AA18 ;
case 7:
if(ESP8266_login()==0) ESP8266.status=8;//检查不在线,重新登录deng
delay_ms(5000);
break;
case 8:
delay_ms(45000);
break;
default:
break;
}
if(ESP8266.status!=8)
{
delay_ms(3000);
goto AA18 ;
}
}
//ESP8266接收数据后,
//str:期待的应答结果
//返回值:0,返回相应的结果
// 其他,期待应答结果的位置(str的位置)
u16 ESP8266_search(void)
{
u8 res=0,strN;
u8 *p,*p2,*strA,*strB,*reply;
p=mymalloc(SRAMIN,100); //申请100字节内存
p2=mymalloc(SRAMIN,100); //申请100字节内存
if(USART2_RX_STA&0X8000)//接收到期待的应答结果
{
//判断指令类型
if(atk_8266_check_cmd("\"M\":\"login\"")) res=login; //检查上线
if(atk_8266_check_cmd("\"M\":\"logout\"")) res=logout; //检查下线
if(atk_8266_check_cmd("\"M\":\"say\"")) res=say; //检查对话
//跳转类型操作
switch(res)
{
case login:
res=0;
if(atk_8266_check_cmd("\"xyy840948307(web)\"")) ESP8266.xyy_web_login=1; //检查上线
if(atk_8266_check_cmd("\"xyy840948307(wx)\"")) ESP8266.xyy_wx_login=1; //检查上线
if(atk_8266_check_cmd("\"guest\"")) ESP8266.guest_login=1; //检查上线
break;
case logout:
res=0;
if(atk_8266_check_cmd("\"xyy840948307(web)\"")) ESP8266.xyy_web_logout=1; //检查下线
if(atk_8266_check_cmd("\"xyy840948307(wx)\"")) ESP8266.xyy_wx_logout=1; //检查下线
if(atk_8266_check_cmd("\"guest\"")) ESP8266.guest_logout=1; //检查下线
break;
case say:
res=0;
if(atk_8266_check_cmd("\"xyy840948307(wx)\"")) res=xyy840948307wx;//检查下线
if(atk_8266_check_cmd("\"xyy840948307(web)\"")) res=xyy840948307web; //检查下线
if(atk_8266_check_cmd("\"guest\"")) res=guest; //检查下线
res=1; //强制
goto AA10;
default:
res=0;
break;
}
goto AA20; //无命令,跳转到文末
AA10://say对话操作
reply=(u8*)reply0;
switch(res)
{
case xyy840948307wx://微信对话,命令字符在“C” 和“T” 之间
res=0;
strA=atk_8266_check_cmd("\"C\"")+5 ; //检查命令字符第一个字符位置, 向右偏移5个字节
strB=atk_8266_check_cmd("\"T\"")-3 ; //检查命令字符最后一个个字符位置, 向左偏移3个字节
strN=strB-strA+1; //加1是防止最后一个字符丢失
memcpy(p,strA,strN); //复制字符串
p[strN]=0; //添加结束符
order2str(p);
printf("%s\r\n",(u8*) p);//发送到串口 "\u52a0\u6cb9"
strN=0;
if(strstr((const char*)p,(const char*)"开灯")) strN=1;
if(strstr((const char*)p,(const char*)"开灯1")) strN=1;
if(strstr((const char*)p,(const char*)"继电器开")) strN=1;
if(strN) K0.DO=1,reply=(u8*)reply3;
strN=0;
if(strstr((const char*)p,(const char*)"关灯")) strN=1;
if(strstr((const char*)p,(const char*)"关灯1")) strN=1;
if(strstr((const char*)p,(const char*)"继电器关")) strN=1;
if(strN) K0.DO=0,reply=(u8*)reply4;
strN=0;
if(strstr((const char*)p,(const char*)"屏幕开")) strN=1;
if(strstr((const char*)p,(const char*)"up")) strN=1;
if(strN) LCD_ON,LCD_ONT=30000,reply=(u8*)reply1;
strN=0;
if(strstr((const char*)p,(const char*)"屏幕关")) strN=1;
if(strstr((const char*)p,(const char*)"down")) strN=1;
if(strN) LCD_OFF,reply=(u8*)reply2;
strN=0;
if(strstr((const char*)p,(const char*)"喇叭")) strN=1;
if(strstr((const char*)p,(const char*)"蜂鸣器")) strN=1;
if(strstr((const char*)p,(const char*)"报警")) strN=1;
if(strN) Beep_T=2000 ,reply=(u8*)reply10;
if(strstr((const char*)p,(const char*)"offOn")) K0.DO=!K0.DO, K0.TN=10000 ,reply=(u8*)reply9;
if(strstr((const char*)p,(const char*)"play")) Beep_T=1000 ,reply=(u8*)reply10;
sprintf((char*)p2,"{\"M\":\"say\",\"ID\":\"U397\",\"C\":\"%s\",\"SIGN\":\"123\"}",(char*)reply);
str2order(p2);
atk_8266_send_cmd((u8*)p2,0,0);
break;
case xyy840948307web://web对话
res=0;
break;
case guest://guest对话 R??
res=0;
break;
default:
res=0;
break;
}
AA20:
USART2_RX_STA=0;
}
myfree(SRAMIN,p); //释放100字节内存
myfree(SRAMIN,p2); //释放100字节内存
return 0;
}
void order2str(u8* str)
{
u16 j=0,n=0,res;
while(str[j]) //判断索检到末尾
{
if((str[j]=='\\')&&(str[j+1]=='u'))
{
if(str[j+2]<58) str[j+2]-=48;
else str[j+2]-=87;
if(str[j+3]<58) str[j+3]-=48;
else str[j+3]-=87;
if(str[j+4]<58) str[j+4]-=48;
else str[j+4]-=87;
if(str[j+5]<58) str[j+5]-=48;
else str[j+5]-=87;
str[n]=str[j+2]*16+str[j+3];
str[n+1]=str[j+4]*16+str[j+5];
res=(str[n]*256)+str[n+1]; //编码求和
res=ff_convert(res,0); /* Converted code, 0 means conversion error */
if(res<0x0100) res=0x3f3f; //汉字编码不能小于这个数
str[n]=res>>8,str[n+1]=res; //编码分解
n+=2,j+=6;
}else
{
str[n]=str[j];
n++,j++;
}
}
str[n]=0; //索检到末尾,添加结束符
}
//p; j{"M":"say","ID":"U397","C":"LED OK收到数据","SIGN":"123"}
//str;n{"M":"say","ID":"U397","C":"LED OK\u6536\u5230\u6570\u636e","SIGN":"123"}
void str2order(u8* str)
{
u16 j=0,n=0,res;
u8 *p;
p=mymalloc(SRAMIN,100); //申请100字节内存
strcpy((char*)p,(char*)str);
while(p[j]) //判断索检到末尾
{
if((p[j]&0x80)>0)
{
str[n]='\\';
str[n+1]='u';
n+=2;
res=(p[j]*256)+p[j+1];
res=ff_convert(res,1); /* Converted code, 0 means conversion error */
p[j]=res>>8,p[j+1]=res;
str[n]=p[j]>>4,str[n+1]=p[j]&0x0f;
str[n+2]=p[j+1]>>4,str[n+3]=p[j+1]&0x0f;
if(str[n]<10) str[n]+=48;
else str[n]+=87;
if(str[n+1]<10) str[n+1]+=48;
else str[n+1]+=87;
if(str[n+2]<10) str[n+2]+=48;
else str[n+2]+=87;
if(str[n+3]<10) str[n+3]+=48;
else str[n+3]+=87;
n+=4,j+=2;
}else
{
str[n]=p[j];
n++,j++;
}
}
str[n]=0; //索检到末尾,添加结束符
myfree(SRAMIN,p); //释放100字节内存
}
//UCOS2主程序调用任务//ESP8266
void ESP8266_hold_task(void *pdata)
{
u8 *p;
u8 n=0;
ESP8266.DISCONNECT_T=1; //开机认为已经失联,设置超时状态强制重连,需要让其连接但不需要初始化。
if(ESP8266_check("checked")==0)
{
ESP8266.DISCONNECT_T=0;
goto AA16;
}
while(ESP8266_connect()) //开机连接一次
{
n++; //延时
if(n>=3) break;
}
AA16:
delay_ms(12000); //查询不得小于10秒
while(1)
{
ESP8266_hold(); //内部集成延时45s,保持在线
p=mymalloc(SRAMIN,40); //申请32字节内存
Get_Temprate();
sprintf((char*)p,"{\"M\":\"update\",\"ID\":\"393\",\"V\":{\"400\":\"%.2f\",\"401\":\"223\"}}",chip_Temprate);//登录指令(float)chip_Temprate
atk_8266_send_cmd(p,0,0);
myfree(SRAMIN,p); //内存释放(外部调用)
}
}
//ESP8266//获取微信或者贝壳APP发送的控制命令
void ESP8266_task(void *pdata)
{
while(1)
{
ESP8266_search();
delay_ms(100);
}
}工程文件:
STM32F4跑ucosii ,配合AT指令保持在线并控制设备。.7z
(用Keil 5打开)