//STC15W204 晶振为22.1M,有时钟0及2
//二路WIFI智能开关,带定时功能,但由于是用AT命令控制WIFI模块的,也没有时钟芯片,
//所以定时功能需不能停电,如停电,为防止乱开关,所以是关闭定时功能的。
//初始使用时先按开关12后开电,等指示灯亮后1-2S就放手,然后手机接入wifikong的WIFI,
//运行控制软件设置准备接入的WIFI的参数,然后重启就行了。
#include <STC15W204.h>
#include <intrins.h>
#include "string.h"
unsigned int jisu,setjisu,timejisu;
unsigned char kong05,oldkey,LEDkong,recRSjisu,rsfanhuvol,sec;
unsigned char idata recRSvol[70];//接收串口数据存储。
unsigned char idata password[6];//这是本硬件密码
unsigned char idata SSIDvol[18];//WIFIssid号,用<为结束码
unsigned char idata WIFIpass[18];//WIFI密码,用>为结束码
unsigned char LoaclIP1,LoaclIP2,SubnetMask1,SubnetMask2,GateWay1,GateWay2;
unsigned int timevol;
unsigned char kong1onhour,kong1onmin,kong1offhour,kong1offmin,kong2onhour,kong2onmin,kong2offhour,kong2offmin;
bit kong1en,kong2en,kong1rep,kong2rep,settimeok,settimewrEEP;
bit rskong,rsstart,sendkong,passwordok,setintcangok,setintwrEEP,oldout1,oldout2;
sbit OUT1=P3^2;
sbit OUT2=P3^3;
sbit KEY1=P5^5;
sbit KEY2=P5^4;
void delay(unsigned int t) //长延时程序,延时t毫秒,STC 1T单片机11.0592M晶振I值为648,22.1I值为1298,12MI值为705。
{
unsigned int i;
while(t--)
{
for(i=1298;i>0;i--);
}
}
//======================EEPROW偏程==============================
//写字节时,可以将原有数据中的1改为0,无法将0改为1,只能使用擦除命令将0改为1
//应注意,擦除命令会将整个扇区擦除
// 第二扇区地址0x0200-0x03ff,0x0400-0x05ff,0x0600-0x07ff,0x0800-0x09ff.
void IAPIDLE()
{
IAP_CMD = 0; //关闭令,保护
IAP_CONTR = 0; //关EEPROM,保护
IAP_TRIG = 0;
IAP_ADDRL = 0; //设置读取地址的低字节,地址改变才需要设置
IAP_ADDRH = 0X80; //设置读取地址的高字节,地址改变才需要设置
}
unsigned char readEEP(unsigned int adddata)
{ //读取
unsigned char eerdata;
IAP_CONTR=0X83;//设置等待时间,1MHz以下取7,2M以下取6,3M取5,6M取4,12M取3,20M取2,24M取1,30M取0,前导1表示许档IAP
IAP_CMD = 1; //读取值1,写取2,擦除取3,擦除时按所在字节整个扇区撺除
IAP_ADDRL = adddata; //设置读取地址的低字节,地址改变才需要设置
IAP_ADDRH = adddata>>8; //设置读取地址的高字节,地址改变才需要设置
IAP_TRIG = 0x5A; //先送5A
IAP_TRIG = 0xA5; //先送5A再送A5立即触发
_nop_();
eerdata=IAP_DATA;
IAPIDLE();
return eerdata;
}
void writeEEP(unsigned int adddata, unsigned char eerdata)
{//写入
IAP_CONTR=0X83;//设置等待时间,
IAP_CMD = 2; //读取值1,写取2,擦除取3,擦除时按所在字节整个扇区撺除
IAP_ADDRL = adddata; //设置读取地址的低字节,地址改变才需要设置
IAP_ADDRH = adddata>>8; //设置读取地址的高字节,地址改变才需要设置
IAP_DATA= eerdata;//传入数据
IAP_TRIG = 0x5A; //先送5A
IAP_TRIG = 0xA5; //先送5A再送A5立即触发
_nop_();
IAPIDLE();
}
void eraseEEP(unsigned int adddata)
{ //擦除
IAP_CONTR=0X83;//设置等待时间,
IAP_CMD = 3; //读取值1,写取2,擦除取3,擦除时按所在字节整个扇区撺除
IAP_ADDRL = adddata; //设置读取地址的低字节,地址改变才需要设置
IAP_ADDRH = adddata>>8; //设置读取地址的高字节,地址改变才需要设置
IAP_TRIG = 0x5A; //先送5A
IAP_TRIG = 0xA5; //先送5A再送A5立即触发
_nop_();
IAPIDLE();
}
//扇区0存控制值,扇区1存WIFI值
void writeEEPDAT0()
{
eraseEEP(0x0000);
writeEEP(0x0000, kong1rep);//
writeEEP(0x0001, kong1onhour);//
writeEEP(0x0002, kong1onmin);//
writeEEP(0x0003, kong1offhour);//
writeEEP(0x0004, kong1offmin);//
writeEEP(0x0005, kong2rep);//
writeEEP(0x0006, kong2onhour);//
writeEEP(0x0007, kong2onmin);//
writeEEP(0x0008, kong2offhour);//
writeEEP(0x0009, kong2offmin);//
}
void readEEPDAT0()
{
//readEEP(0x0000);kong1rep,kong1onhour,kong1onmin,kong1offhour,kong1offmin,kong2rep,kong2onhour,kong2onmin,kong2offhour,kong2offmin;
kong1rep=readEEP(0x0000);
kong1onhour=readEEP(0x0001);
if(kong1onhour>23)kong1onhour=18;
kong1onmin=readEEP(0x0002);
if(kong1onmin>59)kong1onmin=30;
kong1offhour=readEEP(0x0003);
if(kong1offhour>23)kong1offhour=1;
kong1offmin=readEEP(0x0004);
if(kong1offmin>59)kong1offmin=0;
kong2rep=readEEP(0x0005);
kong2onhour=readEEP(0x0006);
if(kong2onhour>23)kong2onhour=0;
kong2onmin=readEEP(0x0007);
if(kong2onmin>59)kong2onmin=0;
kong2offhour=readEEP(0x0008);
if(kong2offhour>23)kong2offhour=1;
kong2offmin=readEEP(0x0009);
if(kong2offmin>59)kong2offmin=0;
}
void writeEEPDAT1()
{//6位配对码+2位IP+2位掩码+2位网关+SSID+密码 SSID及密码用<>结束
unsigned char xx;
eraseEEP(0x0200);
writeEEP(0x0200, password[0]);//
writeEEP(0x0201, password[1]);//
writeEEP(0x0202, password[2]);//
writeEEP(0x0203, password[3]);//
writeEEP(0x0204, password[4]);//
writeEEP(0x0205, password[5]);//
writeEEP(0x0206, LoaclIP1);//
writeEEP(0x0207, LoaclIP2);//
writeEEP(0x0208, SubnetMask1);//
writeEEP(0x0209, SubnetMask2);//
writeEEP(0x020a, GateWay1);//
writeEEP(0x020b, GateWay2);//
for(xx=0;xx<18;xx++)
{
writeEEP(0x020c+xx, SSIDvol[xx]);//
}
for(xx=0;xx<18;xx++)
{
writeEEP(0x020c+xx, SSIDvol[xx]);//
}
for(xx=0;xx<18;xx++)
{
writeEEP(0x0220+xx, WIFIpass[xx]);//
}
}
void readEEPDAT1()
{
unsigned char xx;
password[0]=readEEP(0x0200);
password[1]=readEEP(0x0201);
password[2]=readEEP(0x0202);
password[3]=readEEP(0x0203);
password[4]=readEEP(0x0204);
password[5]=readEEP(0x0205);
LoaclIP1=readEEP(0x0206);
LoaclIP2=readEEP(0x0207);
SubnetMask1=readEEP(0x0208);
SubnetMask2=readEEP(0x0209);
GateWay1=readEEP(0x020a);
GateWay2=readEEP(0x020b);
for(xx=0;xx<18;xx++)
{
SSIDvol[xx]=readEEP(0x020c+xx);
}
for(xx=0;xx<18;xx++)
{
WIFIpass[xx]=readEEP(0x0220+xx);//
}
}
//*************************************************************
//***********串口发送一位数据子程序****************************
void rs1_232tx(unsigned char txdata)
{
SBUF=txdata;//把数据传给串口寄存器SBUF。
while(!TI);//检测是否发完。
TI=0;//重置初值。
}
void RS1_sendstr(unsigned char *dat)
{
unsigned char i,k;
k=strlen(dat);
for(i=0;i<k;i++)
{
rs1_232tx(*(dat+i));
}
}
//***********************键盘扫描子程序。******************
//*********************************************************
unsigned char keyboard()//键盘扫描
{
unsigned char keyboardj;
keyboardj=0;
if(KEY1==0)
{
delay(10);
if(KEY1==0)
{
keyboardj=1;
}
}
if(KEY2==0)
{
delay(10);
if(KEY2==0)
{
keyboardj=2;
}
}
return keyboardj;
}
//******************************************
//************键盘控制子程序***************
//******************************************
void keydisphong()//主要功能是
{
unsigned char keyyy;
keyyy=keyboard();
if (keyyy!=oldkey)
{
if(keyyy==1)//按键1,处于定时状态禁用开关
{
if(kong1en==0)
{//当处于定时状态,关开关控制
if(OUT1==1)
{
OUT1=0;
}
else
{
OUT1=1;
}
oldout1=OUT1;
}
}
if(keyyy==2)//按键2,
{
if(kong2en==0)
{//当处于定时状态,关开关控制
if(OUT2==1)
{
OUT2=0;
}
else
{
OUT2=1;
}
oldout2=OUT2;
}
}
}
oldkey=keyyy;
}
void datasend()
{
//由于只是用于测试,没有对命令后的返回数据判断,如实际应用需对数控进行判断才行。
//AT+CIPSEND=返回值,
//命令如下,0xff,0xee,0xfe(3B引导码),1B开关状态,1B定时器使能,1B定时器重复,4B1定时参数,4B2定时参数,1B设置成功,1B配对成功,1B定时设置成功
unsigned char kk;
RS1_sendstr("AT+CIPSEND=");
rs1_232tx(rsfanhuvol);
RS1_sendstr(",19\r\n");
delay(50);
//返回数据,需\r\n
rs1_232tx(0xff);//引导码
rs1_232tx(0xee);
rs1_232tx(0xfe);
if(OUT1==0)
{//当开关1处于开时
if(OUT2==0)
{//开关2处于开
kk=3;
}
else
{
kk=1;
}
}
else
{
if(OUT2==0)
{
kk=2;
}
else
{
kk=0;
}