上一章我们学习了52单片机串口的使用,本章我们将使用51单片机的串口连接上ESP8266-01s这个wifi模块来实现网络通信,通过手机连接WIFI,控制51单片机上led亮灭(使用AT指令方式)
本实验使用的是安信可公司设计的WIFI模块——ESP-01S,该模块搭载有乐鑫出品的ESP8266EX核心处理器。ESP8266是一款高性能的SOC,其内部除了内嵌有低功耗32位的CPU(80MHz default or 160MHz),还支持WIFI g/g/n协议、TCP/IP协议、WIFI Direct(P2P)、soft-AP和RTOS。在目前物联网飞速发展的年代,其在智能家居等领域有着一席之地,在开发者社区中十分受欢迎。
1、 ESP-01S模块介绍
ESP-01S模组共接出了8个接口,板上除了有一块ESP8266EX的核心处理器,还搭载的有一片外部flash,可以用于存储程序。ESP-01S模块外观及引脚如下图1所示,图片和数据来源于安信可官方文档。
图1 ESP-01S模块外观及引脚图
引脚功能定义如下表所示:
ESP8266的三种工作模式
(1)AP模式(模块作为热点,可以发散出wifi信号,实现手机或电脑直接与模块通讯,实现局域网无线控制)
(2)STA模式(模块通过路由器连接互联网,手机或电脑通过互联网实现对设备的远程控制)
(3)STA+AP模式(两种模式的共存即可通过互联网控制可实现无缝对接切换)
2、 ESP8266 AT指令集
在ESP8266的开发过程中,有两种最主要的方式:SDK方法、AT方法。前者的优势是让系统的成本降低、体积小,因为使用的是芯片内部自带的MCU,劣势是入门时间较长,新手需要一个星期到半月的时间去熟悉开发环境;后者的优势是只需要使用AT指令即可,无需花大量的时间去熟悉环境,开发速度快,劣势是需要额外增加外部CPU成本,体积也相对变大。
AT指令是以AT开头、结尾的特定字符串,AT后面紧跟的字母和数字表明AT指令的具体功能。AT指令具有以下特点:
①几乎所有的AT指令(除了“A/”及“+++”两个指令外)都以一个特定的命令前缀开始,以一个命令结束标志符结束。命令前缀一般由AT两个字符组成,命令结束符通常为。
②每一条AT指令执行完后,调制解调器都会返回一个结果,以对接收到的命令作出应答。
本章将使用简单的AT指令,来使用ESP-01S,即将串口与ESP-01S连接后,在使用串口发送AT指令到ESP-01S上,即可使用ESP-01S。
说了这么多,接下来开始介绍常用的一些AT指令,数据来源于乐鑫官方文档。
AT指令可以细分为四类:测试指令、查询指令、设置指令和执行指令,其指令格式和描述如下表所示:
本章将使用到关于ESP-01S的WIFI功能AT指令,如下,可去乐鑫官网查看。
(3)TCP/IP功能AT指令
(4)AP模式+TCP client
(注:AT+ CIPMUX=1(多连接)时才能开启服务器;关闭 server 模式需要重启。开启 server 后自动建立server监听,当有client接入会自动按顺序占用一个连接。AT+CIPSTATUS除了用来查看TCP的连接服务,还可以用来查看UDP连接服务)
(3)station模式+TCP client
相比与AP模式+TCP client,不同之处在与2、3两步,变成了三个步骤的同时,操作也不一样了。将下面的操作替换掉AP模式+TCP client的2、3两步即可。
3.ESP8266工作模式的选择及AT指令的刷入
ESP8266配置成服务器(PC或单片机发指令)先将ESP-01S用串口和PC端连接,使用串口助手刷入AT指令:
(1) 测试AT指令:AT
(2) 更改模块波特率: AT+CIOBAUD=9600 (波特率设置成功后要更改后再进行设置其它波特率)
(3) 设置为AP模式:AT+CWMODE=3
(4) 设置name password,加密方式:AT+CWSAP=\"PRECHIN\",\"prechin168\",11,0"
(5) 设置主机端的ip地址:AT+CIPAP=\"192.168.4.2\"(此处的IP地址是模块本身的IP,不是ST模式中加入路由器后分配的IP)
(6) 复位重启模块:AT+RST
(7) 设置为多连接模式,启动模块:AT+CIPMUX=1
(8) 服务器的设置端口:AT+CIPSERVER=1,8080 (TCP client连接server时端口号要保持一致)
注:把以上AT指令刷入ESP8266模块,刷入成功都会返回ok,蓝色部分的指令掉电后不会被抹去,红色部分的指令掉电后会被自动抹去,每次重启模块都要进行配置一遍,故在ESP初始化函数中都要加上红色部分的指令.
4.ESP8266与51单片机的连接(附加外接电源的连接)
ESP8266的 RXD TXD VCC GND
51单片机的 TXD RXD VCC GND
5.实现ESP8266对51单片机的LED灯的无线控制
ESP8266在AP模式下发散出来一个热点,模块作为服务器TCP server.
手机APP或网络调试助手作为客服端TCP client 去访问服务器,从而实现无线控制.
这里介绍一下手机APP对LED无线控制的具体操作过程:
(1)手机上下载一个TCP连接或NetAssist的APP
(2)打开手机WiFi可以搜索到ESP8266点击连接,连接成功后会有提示说"此热点无上网功能,是否切换"点击否.
(3)打开手机APP,点击TCP client 连接,输入AT指令中获取的IP地址,选择端口号,点击连接.
(4)连接成功后,输入字符大写的A就会打开LED灯,输入大写字符B关闭LED灯.
6.代码实现
1.串口的初始化
#define RELOAD_COUNT 0xFA //宏定义波特率发生器的载入值 9600
void UART_Init()
{
SCON=0X50; //设置为工作方式1
TMOD=0X20; //设置计数器工作方式2
PCON=0X80; //波特率加倍
TH1=RELOAD_COUNT; //计数器初始值设置
TL1=TH1;
ES=0; //关闭接收中断
EA=1; //打开总中断
TR1=1; //打开计数器
}
2.串口发送数据函数
void UART_SendByte(u8 dat)
{
ES=0; //关闭串口中断
TI=0; //清发送完毕中断请求标志位
SBUF=dat; //发送
while(TI==0); //等待发送完毕
TI=0; //清发送完毕中断请求标志位
ES=1; //允许串口中断
}
3.串口发送AT命令函数
void ESP8266_SendCmd(u8 *pbuf)
{
while(*pbuf!='\0') //遇到空格跳出循环
{
UART_SendByte(*pbuf);
delay_10us(5);
pbuf++;
}
delay_10us(5);
UART_SendByte('\r');//回车
delay_10us(5);
UART_SendByte('\n');//换行
delay_ms(1000);
}
4.ESP8266AT指令,工作模式初始化
//ESP8266-WIFI模块工作模式初始化
void ESP8266_ModeInit(void)
{
ESP8266_RST_Pin=1;
ESP8266_CH_PD_Pin=1;
ESP8266_SendCmd("AT");
ESP8266_SendCmd("AT+CWMODE=3");//设置路由器模式 1 staTIon模式 2 AP点 路由器模式 3 station+AP混合模式
ESP8266_SendCmd("AT+CWSAP=\"PRECHIN\",\"prechin168\",11,0"); //设置WIFI热点名及密码
ESP8266_SendCmd("AT+CIPAP=\"192.168.4.2\"");//重新启动wifi模块
ESP8266_SendCmd("AT+RST");//重新启动wifi模块
ESP8266_SendCmd("AT+CIPMUX=1"); //开启多连接模式,允许多个各客户端接入
ESP8266_SendCmd("AT+CIPSERVER=1,8080"); //启动TCP/IP 端口为8080 实现基于网络控制
}
5.串口接收数据中断函数
u8 RecBuf[50];
u8 recFlagOK=0;
void Uart() interrupt 4
{
static u8 i=0;
if(RI)
{
RI=0;
RecBuf[i]=SBUF; //+IPD,0,1:F
if(RecBuf[0]=='+')i++;
else i=0;
if(i==10)
{
i=0;
if(RecBuf[0]=='+'&&RecBuf[1]=='I'&&RecBuf[2]=='P'&&RecBuf[3]=='D')
{
switch(RecBuf[9])
{
case 'A': led1=0;break;//点亮led1
case 'B': led1=1;break;//关闭led1
case 'C': led4=0;break;//继电器
case 'D': led4=1;break;//
}
}
}
}
}
注(当 ESP8266 设备接收到服务器器发来的数据,将提示如下信息:+IPD,0,F:xxxxxxxxxx // received n bytes, data=xxxxxxxxxxx)故数据判断从RecBuf[9]开始。
完整示例:
#include <reg52.h>
sbit ESP8266_RST_Pin=P2^5;
sbit ESP8266_CH_PD_Pin=P2^6;
sbit led1=P2^0;
sbit led2=P2^1;
sbit led3=P2^2;
sbit led4=P2^3;
typedef unsigned long u32; //对数据类型进行声明定义
typedef unsigned int u16;
typedef unsigned char u8;
#define RELOAD_COUNT 0xFA //宏定义波特率发生器的载入值 9600
u8 RecBuf[50];
u8 recFlagOK=0;
void delay_10us(u16 us)
{
while(us--);
}
void delay_ms(u16 ms)
{
u16 i,j;
for(i=ms;i>0;i--)
for(j=114;j>0;j--);
}
void UART_Init()
{
SCON=0X50; //设置为工作方式1
TMOD=0X20; //设置计数器工作方式2
PCON=0X80; //波特率加倍
TH1=RELOAD_COUNT; //计数器初始值设置
TL1=TH1;
ES=0; //关闭接收中断
EA=1; //打开总中断
TR1=1; //打开计数器
}
void UART_SendByte(u8 dat)
{
ES=0; //关闭串口中断
TI=0; //清发送完毕中断请求标志位
SBUF=dat; //发送
while(TI==0); //等待发送完毕
TI=0; //清发送完毕中断请求标志位
ES=1; //允许串口中断
}
void ESP8266_SendCmd(u8 *pbuf)
{
while(*pbuf!='\0') //遇到空格跳出循环
{
UART_SendByte(*pbuf);
delay_10us(5);
pbuf++;
}
delay_10us(5);
UART_SendByte('\r');//回车
delay_10us(5);
UART_SendByte('\n');//换行
delay_ms(1000);
}
//ESP8266-WIFI模块工作模式初始化
void ESP8266_ModeInit(void)
{
ESP8266_RST_Pin=1;
ESP8266_CH_PD_Pin=1;
ESP8266_SendCmd("AT");
ESP8266_SendCmd("AT+CWMODE=3");//设置路由器模式 1 staTIon模式 2 AP点 路由器模式 3 station+AP混合模式
ESP8266_SendCmd("AT+CWSAP=\"PRECHIN\",\"prechin168\",11,0"); //设置WIFI热点名及密码
ESP8266_SendCmd("AT+CIPAP=\"192.168.4.2\"");//重新启动wifi模块
ESP8266_SendCmd("AT+RST");//重新启动wifi模块
ESP8266_SendCmd("AT+CIPMUX=1"); //开启多连接模式,允许多个各客户端接入
ESP8266_SendCmd("AT+CIPSERVER=1,8080"); //启动TCP/IP 端口为8080 实现基于网络控制
}
void Uart() interrupt 4
{
static u8 i=0;
if(RI)
{
RI=0;
RecBuf[i]=SBUF; //+IPD,0,1:F
if(RecBuf[0]=='+')i++;
else i=0;
if(i==10)
{
i=0;
if(RecBuf[0]=='+'&&RecBuf[1]=='I'&&RecBuf[2]=='P'&&RecBuf[3]=='D')
{
switch(RecBuf[9])
{
case 'A': led1=0;break;//点亮led1
case 'B': led1=1;break;//关闭led1
case 'C': led4=0;break;//继电器
case 'D': led4=1;break;//
}
}
}
}
}
void main()
{
u16 i=0;
led1=0;
led2=0;
led3=0;
led4=0;
UART_Init(); //串口初始化
ESP8266_ModeInit();
ES=1; //允许串口中断
while(1)
{
i++;
if(i%10==0)
{
led3=!led3;
}
delay_ms(100);
}
}