文章目录
- 前言
- 预备知识
- 正文
- ESP8266模块的配置
- 代码设计
- 总结
前言
学了这么长,今天给大家分享一个小项目的雏形。这次智能家居,我们暂且实现一个智能灯。有三种控制方式的智能灯:
1、按键控制开关(单片机独立按键)
2、WiFi控制开关(ESP8266模块)
3、传感器控制开关(光敏电阻)
单片机(普中51A2)
当然还有一个必不可少的东西,液晶显示当前的状态。
开始吧!
预备知识
快速入门51单片机快速学习51单片机中断快速学习51单片机串口通信 以及单片机按键与液晶的使用
正文
(因为疫情原因,没开学只能用开发板)
ESP8266模块的配置
据说好多小伙伴都栽在这一步了。就目前我们这个小项目只需要大家简单配置即可。
拿到模块后我们用杜邦线连接到烧入工具上面,连接很简单。就是
TXD-RXD
RXD-TXD
VCC-VCC
GND-GND
连这四个足够了,然后插入电脑中,打开串口调试助手
设置串口调试助手的波特率为115200(因为模块初始化的波特率为这个)
1、测试模块
用串口调试助手发送AT,如果收到OK,证明模块没问题。
2、修改模块串口的波特率(因为单片机的波特率设置不了这么大,我们就设置为9600即可)
用串口调试助手发送:
AT+UART=9600,8,1,0,0
(方便我们用串口通信的方式1)
3、用模块连接自己家的wifi(注意此时串口调试助手的波特率记得改成9600)
AT+CWJAP=“WiFi名称”,“WiFi密码”
好了目前设置这么多就行了。
代码设计
这边我先把代码打出来,具体的说明,我会在你看完代码再进行讲解。
#include <reg52.h>
#include <intrins.h>
#include <stdio.h>
#define uchar unsigned char
#define uint unsigned int
sbit mode=P2^0; //mode=0为按键和WiFi控制 mode=1为传感器控制
sbit S1=P1^7;
sbit S2=P1^3;
sbit light=P2^1;
sbit key1=P3^2; //按键3
sbit key2=P3^3; //按键4
sbit DIN=P3^4;
sbit CS=P3^5;
sbit DCLK=P3^6;
sbit DOUT=P3^7;
sbit EN=P2^7;
sbit RS=P2^6;
sbit lcdWR=P2^5;
uchar code table1[]="loading...";
uchar code table2[]="OK";
uchar code table3[]="status";
uchar code table4[]="Light";
uchar code table5[]="low ";
uchar code table6[]="high";
uchar code table7[]="on ";
uchar code table8[]="off";
void lcdWriteCom(uchar dat);
void lcdString(uchar *str,uint length);
/*延时ms函数*/
void delayms(uint z)
{
uint i,j;
for(i=z;i>0;i--)
for(j=110;j>0;j--);
}
/*灯的开关*/
void switchLight(uchar i)
{
if(i==1)
light=0;
if(i==2)
light=1;
}
/*按键控制小灯开关*/
void keyControl(void)
{
if(key1==0)
{
delayms(10);
if(key1==0)
{
switchLight(1);
}
while(!key1);
}
if(key2==0)
{
delayms(10);
if(key2==0)
{
switchLight(2);
}
while(!key2);
}
}
/*光敏传感器控制灯开关*/
//AD写入操作
void adWrite(uchar dat)
{
uint i;
CS=0;
DCLK=0;
for(i=0;i<8;i++)
{
DIN=dat>>7;
dat<<=1;
DCLK=0;
DCLK=1;
}
}
//AD读取数据操作
uint adRead()
{
uint i,dat=0;
CS=0;
DCLK=0;
for(i=0;i<12;i++)
{
dat<<=1;
DCLK=1;
DCLK=0;
dat|=DOUT;
}
return dat;
}
//命令转换操作
uint adReadData() //光敏电阻为 0xa4
{
uint i,AD_value;
DCLK=0;
CS=0;
adWrite(0xa4);
for(i=6;i>0;i--);
DCLK=1;
_nop_();
_nop_();
DCLK=0;
_nop_();
_nop_();
AD_value=adRead();
CS=1;
return AD_value;
}
//封装开关
void adSwitch()
{
if(adReadData()<150)
{
switchLight(1);
delayms(10);
}
else
{
switchLight(2);
delayms(10);
}
}
/*WIFI控制小灯的亮灭*/
//初始化
void wifiInit()
{
TMOD=0x20; //波特率9600
TL1=0xfd;
TH1=0xfd;
TR1=1;
SM0=0;
SM1=1;
REN=1;
EA=1;
ES=1;
}
//设置WiFi打开端口号
void wifiConfig()
{
//液晶显示正在设置
lcdWriteCom(0x80+0x02);
lcdString(table1,10);
ES=0;
TI=1;
delayms(3000);
printf("AT+CIPMUX=1\r\n");//开启模块的多连接功能,即设置为server
delayms(2000);
printf("AT+CIPSERVER=1,8080\r\n");//这里我们开放8080端口
delayms(2000);
while(!TI);
TI=0;
ES=1;
//液晶显示设置成功
lcdWriteCom(0x01);
lcdWriteCom(0x80);
lcdString(table2,2);
}
/*液晶实时状态回显*/
//液晶写命令
void lcdWriteCom(uchar dat)
{
RS=0;
lcdWR=0;
P0=dat;
delayms(5);
EN=1;
delayms(5);
EN=0;
}
//液晶写数据
void lcdWriteData(uchar dat)
{
RS=1;
lcdWR=0;
P0=dat;
delayms(5);
EN=1;
delayms(5);
EN=0;
}
//初始化液晶
void lcdInit()
{
lcdWriteCom(0x38);
lcdWriteCom(0x0c);
lcdWriteCom(0x06);
lcdWriteCom(0x01);
}
//字符串显示函数
void lcdString(uchar *str,uint length)
{
uint i;
for(i=0;i<length;i++)
{
lcdWriteData(str[i]);
}
}
//光强显示
void lcdLight()
{
lcdWriteCom(0x80+0x40);
lcdString(table4,5);
lcdWriteCom(0x80+0x46);
if(adReadData()<200)
lcdString(table5,4);
else
lcdString(table6,4);
}
//液晶显示灯的状态变化
void lcdStatus()
{
lcdWriteCom(0x80);
if(light==0)
lcdString(table7,3);
if(light==1)
lcdString(table8,3);
}
/*模式设置*/
void modeConfig()
{
if(S1==0)
{
delayms(10);
if(S1==0)
{
mode=~mode;
}
while(!S1);
}
if(mode==1)
{
adSwitch();
}
}
/*主函数*/
void main()
{
wifiInit();
lcdInit();
wifiConfig();
mode=0;
S1=1;
S2=0;
while(1)
{
lcdStatus();
lcdLight();
keyControl();
// wifiSwitch();
modeConfig();
}
}
//WiFi封装开关
void wifi() interrupt 4
{
uchar a;
a=SBUF;
if(a=='1')
switchLight(1);
if(a=='2')
switchLight(2);
RI=0;
}
好的,代码大概两百多行。以下我给大家讲一下说明书。(啧)
我们的小灯是用P21这个灯来模拟的。(当然我接了继电器,接不接都一样)
两种大的模式(模式的选择是用矩阵按键进行选择)
mode0:可以用WiFi控制灯的开关以及WiFi控制灯的开关
mode1:用光敏电阻进行控制灯的开关(本来想加人体红外模块的,可是那个模块坏了–)
这里用两种方式,因为光敏电阻和强制性的开关冲突
按键控制开关
在mode0下,我们用两个按键控制灯的打开与关闭,分别是K3和K4(K1和K2与串口通信冲突)
WiFi控制开关
在mode0中,这边我们给单片机发送1即打开灯,发送2即关闭灯(这里我们是用手机上的一个别人做好的软件,目前能力有限还开发不出来app)
光敏电阻控制开关
在mode1中,如果灯光的亮度过暗,即打开电灯,反之关闭电灯(这里我们设置了光敏电阻的参数,让其小于150即打开)
液晶实时显示状态
当我们开机的时候,会有一个loading…的字符显示,证明在初始化(初始化的过程就是创建为TCPsever端以及打开可用的端口)
(这个过程大概会初始化5秒左右)
之后会显示目前灯的状态、目前光线亮度以及模式
目前程序已经测试过了,没有问题可以正常工作。
这里大家要注意一个事情,在你连接WIFI的时候,务必要与WiFi模块连接同一个模块,让其处于同一个网络号,不然不能通信。至于为什么这边就不多说了,不然又要写一篇
总结
经过前一阶段的学习,以及这个小项目的练手,估计大家对单片机的基本操作已经熟悉了。现在可以回过头去读一些以前你看不懂的书了。
这个项目还只是个雏形,等开学后估计会进一步完善,加上语音模块之类的。(目前由于没开学手上的资源仅有这么多)
关于项目的更新,有兴趣的可以在我的github上面看:链接在这 (可恶的疫情,开学就要升大二了。上学不过三个月)