博客园 首页 新随笔 联系 订阅 管理 基于51单片机+ESP8266WiFi模块的网络TCP通信(控制LED亮灭)
前面用WiFi模块+Arduino接入云平台实现过语音助手打开台灯,其实现原理大同小异。初学者一般用高低电平点亮LED,现在我们用TCP网络助手发送一系列自定义的命令来控制LED的亮灭。
一、准备
硬件:一块51单片机开发板、一个ESP8266-01S WiFi模块、USB-TTL转串口;
软件:Keil 单片机编程软件、安信可串口调试助手、网络助手;
基础知识:C语言、单片机串口通信基础 、ESP8266AT指令集;
- AT指令使用事项
其对所传输的数据包大小有定义:即对于AT指令的发送,除AT两个字符外,最多可以接收1056个
字符的长度(包括最后的空字符)。
每个AT命令行中只能包含一条AT指令;对于由终端设备主动向PC端报告的URC指示或者response
响应,也要求一行最多有一个,不允许上报的一行中有多条指示或者响应。AT指令以回车作为结尾,响应或上报以回车换行为结尾。 - USB转TTL测试esp8266
接线说明
USB转TTL模块 ESP8266
RX TX
TX RX
GND GND
3.3V 3.3V
上电后通过串口助手发送指令AT,若返回OK,则通信及模块功能正常。接下依次发送下列指令:
配置串口波特率: AT+UART=9600,8,1,0,0
连接WiFi:AT+CWJAP="WIFI名","密码"
连接TCP服务器:AT+CIPSTART="TCP","192.168.1.110",8080
开启透传模式:AT+CIPMODE=1
发送数据:AT+CIPSEND
二、单片来发送指令联网
ESP8266与51单片机的连接
51单片机 esp8266
VCC 3.3V
RX TX
TX RX
GND GND
-
代码结构
数据类型定义
AT指令封装
延时函数
串口初始化
发送函数
main函数
串口中断服务函数 -
头文件的引用和变量的定义``
#include "reg52.h"
#include "intrins.h"
#include <string.h>
#define SIZE 12
sfr AUXR = 0x8E;
sbit LED = P3^7;
char re_cmd[SIZE];
- AT指令的封装
1 code char LJWL[] ="AT+CWJAP=\"MERCURY_5480\",\"502502502502\"\r\n"; //连接网络
2 code char LJFWQ[] ="AT+CIPSTART=\"TCP\",\"192.168.1.110\",8880\r\n"; //连接服务器
3 char TCMS[] = "AT+CIPMODE=1\r\n";//设置工作模式为透传模式
4 char SJCS[] = "AT+CIPSEND\r\n";//数据传输
- 延时函数
1void Delay1000ms() //@11.0592MHz
2 {
3 unsigned char i, j, k;
4
5 _nop_();
6 i = 8;
7 j = 1;
8 k = 243;
9 do
10 {
11 do
12 {
13 while (--k);
14 } while (--j);
15 } while (--i);
16 }`
- 串口配置
WiFi模块和单片机配置在同一波特率下进行通信
`1 /*
2 配置串口通信
3 9600bps @11.0592MHz
4 */
5
6 void Uart_Init(void)
7 {
8
9 SCON = 0x50; //8位数据,可变波特率,REN使能接收
10 AUXR &= 0x01; //定时器1时钟为Fosc/12,即12T
11 TMOD &= 0xF0; //清除定时器1模式位
12 TMOD |= 0x20; //设定定时器1为8位自动重装方式
13 TH1 = 0xFD;
14 TL1 = 0xFD; //设定定时初值9600波特率
15 TR1 = 1; //启动定时器1
16
17 EA=1;//开启总中断
18 ES=1;//打开串口中断
19 }
发送字符和字符串函数封装
1个8位寄存器SBUF作为数据缓存
1 //发送一个字节
2 void send_Byte(char data_msg)
3 {
4 SBUF = data_msg;
5 while(!TI);
6 TI = 0;
7 }
8
9 //发送字符串
10 void send_String(char* str)
11 {
12 while( *str != '\0'){
13 send_Byte(*str);
14 str++;
15 }
16 }
- 主函数
` 1 void main()
2 {
3
4 LED = 1;
5 //配置C51串口的通信方式
6 Uart_Init();
7
8 while(1){
9 Delay1000ms();//让WiFi模块稳定
10
11 send_String(LJWL);
12 Delay1000ms();
13 Delay1000ms();
14 Delay1000ms();
15 Delay1000ms();
16 Delay1000ms();
17
18 send_String(LJFWQ);
19 Delay1000ms();
20 Delay1000ms();
21 Delay1000ms();
22 Delay1000ms();
23 Delay1000ms();
24 send_String(TCMS);
25 Delay1000ms();
26 Delay1000ms();
27 Delay1000ms();
28 Delay1000ms();
29 Delay1000ms();
30 sendS_tring(SJCS);
31 Delay1000ms();
32 Delay1000ms();
33 Delay1000ms();
34 Delay1000ms();
35 Delay1000ms();
36 }
37 }
`
- 中断处理函数
`1 void Uart_Handler() interrupt 4
2 {
3 static int i = 0;//静态变量,被初始化一次
4 if(RI)//中断处理函数中,对于接收中断的响应
5 {
6 RI = 0;//清除接收中断标志位
7 re_cmd[i] = SBUF;
8 i++;
9 if(i == SIZE)
10 {
11 i = 0;
12 }
13 //检测到字符串en就点亮LED
14 if(strstr(re_cmd,"en"))
15 {
16 LED = 0;//点亮
17 i = 0;
18 memset(re_cmd,'\0',SIZE);
19 }
20 //检测到字符串se就熄灭LED
21 if(strstr(re_cmd,"se"))
22 {
23 D5 = 1;//熄灭
24 i = 0;
25 memset(re_cmd,'\0',SIZE);
26 }
27 }
28
29 } `
服务器连接成功ALL Connections括号里的0会变成1。
在TCP服务器端发送open、close命令就会通过WiFi模块发送到串口,单片机读取到指令变灰点亮或熄灭LED。
三、小结
WiFi模块联网代码还可以优化,延时函数使用太多,可以用一个标志位判断WiFi模块是否联网成功,成功则进行下一步。
WiFi模块使用过程中需注意,vcc最好接3.3v,当我接5v是模块发烫严重,第一个模块就这样烧了。