您的位置:首页 > 其它

关于51单片机+ESP8266

2016-03-02 11:52 204 查看
前言:这个题目是我在单片机课程设计《基于ESP8266的物联电梯系统》中用到的,其实本质上就是实现了单片机对esp8266进行初始化,再将手机连上esp8266的WiFi,然后再通过手机端发送指令,esp8266接收到命令传入单片机,单片机再进行相应的操作。esp8266这种小型模块,在物联世界的发展中,有着强大的生命力,我本人比较喜欢它。同时这个也有相应的作品,程序也比较完整,希望能帮到大家。

代码概况:将模块的VCC,GND,TXD,RXD与单片机的VCC,GND,RXD,TXD接好,以为51单片机没有进程和线程的概念,所以就在main函数的while(1)中放入我们要的主程序,而用串口中断的方式来接收esp8266发过来的数据信息,从而实现用esp8266控制单片机。

/***************************************************main.c***************************************************************/

void main()

{

init(); //这里是你自己的程序里面自定义的初始化程序

init_esp(); //初始化esp8266

while(1)

{

ES=1; //因为每次处理完接收到的数据都关闭串口中断,所以在主程序循环中加入ES=1开启中断

reach_floor(); //这个是我的主程序的名称

}

}

//*********************串口中断程序********************************

void ser() interrupt 4

{

unsigned char ldat;

RI=0;

ldat=SBUF;

remote_control(ldat); //esp8266接收数据并且作相应处理

}

/*********************************************esp8266.h****************************************************************/

#ifndef ESP8266_H

#define ESP8266_H

//#include <AT89X52.H>

#include<reg52.h>

#include <stdio.h>

#include"main.h"

#define uint unsigned int

#define uchar unsigned char

void init_esp();

void remote_control(unsigned char ldat);

extern uint lift_key_5,lift_key_4,lift_key_3,lift_key_2,lift_key_1; //因为我做的是电梯系统,所有这里需要接收到对应楼层号码信息,就改变楼层的数值。

#endif

/***********************************************esp8266.c***************************************************************/

#include"esp8266.h"

void init_esp()

{

unsigned int a;

TH1=0XFD; //串口中断的波特率设为9600,同时记得将esp8266的AT固件代码改为9600的波特率,然后刷入该AT固件。

TH0=0XFD;

TR1=1;

REN=1; //使能串口允许接收

SM0=0; //工作在串口的工作方式1

SM1=1;

ES=0; //串口中断关闭,待初始化后再打开

EA=1; //总中断打开

TI = 1;

for (a=0; a<50000; a++); //延时几秒,让模块有时间启动

printf ("AT+CWMODE=3\n"); //设置为softAP和station共存模式

for (a=0; a<30000; a++);

printf ("AT+RST\n"); //重新启动模块

for (a=0; a<50000; a++);

printf ("AT+CIPMUX=1\n"); //启动多连接

for (a=0; a<20000; a++);

printf ("AT+CIPSERVER=1\n");//建立server,默认端口为333

for (a=0; a<20000; a++);

printf ("AT+CIPSTO=50\n"); //服务器超时时间设置

for (a=0; a<20000; a++);

RI=0;

ES=1; //初始化完成,串行口中断打开

//到了这里,就有一个疑问:ESP8266在接收到AT命令之后都会返回一个OK,为什么这里我没有相应的语句保证ESP8266成功接收到上面的几条命令呢?

//答案是:因为单片机与esp8266通过的直接连接极少的情况才会丢失信息,比较可靠,而且我想速度达到最快。

//执行上述命令,模块进入服务模式,下面单片机就可以接收远程发来的数据

}

//远程选择电梯楼层程序

//这里楼层的号码用了符号来代替,应为在给esp8266发送命令的过程中,通常需要输入一些数值,而esp8266有时又会返回一些数值,

//在串口接收的过程中,这些接收到的数字会影响我们的程序对楼层的判断,所以要采取特殊的表示楼层的方法。

void remote_control(unsigned char ldat)

{

unsigned int a;

switch(ldat)

{

case '!': //感叹号表示1楼,当然你也可以用其他表示方式,你也可以先接收到1,然后再进行其他的判断

printf ("AT+CIPSEND=0,33\n"); //发送语句的命令

for (a=0; a<10000; a++);

printf ("%c\nplease enter your destination:",'1'); //需要发送的语句

lift_key_1=on;

break;

case '@':

printf ("AT+CIPSEND=0,33\n");

for (a=0; a<10000; a++);

printf ("%c\nplease enter your destination:",'2');

lift_key_2=on;

break;

case '#':

printf ("AT+CIPSEND=0,33\n");

for (a=0; a<10000; a++);

printf ("%c\nplease enter your destination:",'3');

lift_key_3=on;

break;

case '$':

printf ("AT+CIPSEND=0,33\n");

for (a=0; a<10000; a++);

printf ("%c\nplease enter your destination:",'4');

lift_key_4=on;

break;

case '%':

printf ("AT+CIPSEND=0,33\n");

for (a=0; a<10000; a++);

printf ("%c\nplease enter your destination:",'5');

lift_key_5=on;

break;

}

ES=0;

}

//下面附上更为可靠的esp8266初始化函数(使用了do...while...循环,确保esp8266回复了ok)

//这里使用的是定时器2,所以程序与上面的有点不同

void init_esp()

{

uint a;

uchar ldat;

int d =1;

SCON=0x50; //串口工作方式1,8位UART,波特率可变

TH2=0xFF;

TL2=0xFD; //波特率:115200 晶振=11.0592MHz

RCAP2H=0xFF;

RCAP2L=0xFD; //16位自动再装入值

TCLK=1;

RCLK=1;

C_T2=0;

EXEN2=0; //波特率发生器工作方式

TR2=1 ; //定时器2开始 //

TI = 1;

REN=1; //使能串口允许接收

SM0=0; //工作在串口的工作方式1

SM1=1;

ES=0; //串口中断关闭,待初始化后再打开

EA=1; //总中断打开

for (a=0; a<50000; a++); //延时几秒,让模块有时间启动

printf ("AT+CWMODE=3\n"); //

do{

if(RI)

{ //查询是否有数据接收

ldat=SBUF; //数据暂存于变量中

RI=0;

if (ldat=='K')//命令执行成功,就会返回OK,这里就是查询是否有K返回,若有K返回,就说明执行成功,可以执行下一条,否则继续循环

d=0;

}

}while (d);

d =1;//b、c、d复位,便于执行下一条命?

for (a=0; a<50000; a++);

printf ("AT+RST\n");

do{

if(RI)

{

ldat=SBUF;

RI=0;

if (ldat=='K')

d=0;

}

}while (d);

d =1;

for (a=0; a<80000; a++);

printf ("AT+CIPMUX=1\n");

do{

if(RI)

{

ldat=SBUF;

RI=0;

if (ldat=='K')

d=0;

}

}while (d);

d =1;

for (a=0; a<10000; a++);

printf ("AT+CIPSERVER=1\n");

do{

if(RI)

{

ldat=SBUF;

RI=0;

if (ldat=='K')

d=0;

}

}while (d);

d =1;

for (a=0; a<10000; a++);

printf ("AT+CIPSTO=50\n"); //服务器超时时间

do{

if(RI)

{

ldat=SBUF;

RI=0;

if (ldat=='K')

d=0;

}

}while (d);

d =1;

for (a=0; a<10000; a++);

ES=1; //串行口中断打开

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: