600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > 51单片机通过WIFI模块ESP8266控制LED灯(大致内容 经过测试成功实现)

51单片机通过WIFI模块ESP8266控制LED灯(大致内容 经过测试成功实现)

时间:2021-03-10 04:44:55

相关推荐

51单片机通过WIFI模块ESP8266控制LED灯(大致内容 经过测试成功实现)

51单片机通过WIFI模块ESP8266控制LED灯

准备材料:stm89c516、esp8266-01、至少5根杜邦线。。、电路板。

大概思路:

1、控制esp和服务器连接。

2、pc向向服务器发送指令。

3、服务器接收到指令后,再向esp发送。

4、esp接收到指令后,再向单片机发送。

5、单片机接收到指令后,执行 指令。

先讲第一步:控制esp和服务器连接

首先用到是esp8266-01,如图:

然后是下面TTL-USB串口线,如图:

还需要一个串口调试助手,为了接发数据。我使用的调试助手如,下图:

下面是硬件连接,硬件连接并不复杂,如图:

之后打开串口进行连接,如图:

备注:由于我之前把模块的波特率修改成9600了,其实esp8266波特率默认是115200。因此如果你没有修改波特率,则需要选择115200,不然没有结果。

准备工作做好之后,开始进行指令发送:

发送:AT+URAT=9600,8,1,0,0//设置串口发送:AT+CWMODE=1//设置STA模式发送:AT+RST//重启发送:AT+CWJAP=“WIFI名”,“WIFI密码”//连接WIFI发送:AT+CIPMUX=1//启动多链接发送:AT+CIPSERVER=1//建立服务器发送:AT+CIPSTART=2,“TCP”,“115.29.109.104”,6520//通过协议,IP,端口连接服务器。

指令全部成功发送后,esp的基本工作就完成了

接下俩讲第二步,运行以下代码:

`#include

#include<winsock.h>

#pragma comment(lib,“ws2_32.lib”)

using namespace std;

void initialization();

int main() {

//定义长度变量

int send_len = 0;

int recv_len = 0;

//定义发送缓冲区和接受缓冲区

char send_buf[100];

char recv_buf[100];

//定义服务端套接字,接受请求套接字

SOCKET s_server;

//服务端地址客户端地址

SOCKADDR_IN server_addr;

initialization();

//填充服务端信息

server_addr.sin_family = AF_INET;

server_addr.sin_addr.S_un.S_addr = inet_addr(“115.29.109.104”);

server_addr.sin_port = htons(6520);

//创建套接字

s_server = socket(AF_INET, SOCK_STREAM, 0);

if (connect(s_server, (SOCKADDR *)&server_addr, sizeof(SOCKADDR)) == SOCKET_ERROR) {

cout << “服务器连接失败!” << endl;

WSACleanup();

}

else {

cout << “服务器连接成功!” << endl;

}

//发送,接收数据while (1) {cout << "you:";cin >> send_buf;send_buf[strlen(send_buf) - 1] = '\n';send_buf[strlen(send_buf) - 2] = '\r';send_len = send(s_server, send_buf, strlen(send_buf), 0);if (send_len < 0) {cout << "发送失败!" << endl;break;}/*recv_len = recv(s_server, recv_buf, 100, 0);if (recv_len < 0) {cout << "接受失败!" << endl;break;}else {cout << "other:" << recv_buf << endl;}*/}//关闭套接字closesocket(s_server);//释放DLL资源WSACleanup();return 0;

}

void initialization() {

//初始化套接字库

WORD w_req = MAKEWORD(2, 2);//版本号

WSADATA wsadata;

int err;

err = WSAStartup(w_req, &wsadata);

if (err != 0) {

cout << “初始化套接字库失败!” << endl;

}

else {

cout << “初始化套接字库成功!” << endl;

}

//检测版本号

if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wHighVersion) != 2) {

cout << “套接字库版本号不符!” << endl;

WSACleanup();

}

else {

cout << “套接字库版本正确!” << endl;

}

//填充服务端地址信息

}

`

成功运行,如图:

第三步已经在第一步里面完成了。

接下来讲第四步,如何让esp向单片机发送指令:

这里只要依照这电路图找出 RXD/TXD I/O 口就行,我这款单片机的 RXD、TXD 为 P30 和 P31 口,只要将 ESP8266 接通 3.3 V 电源,将 wifi 模块的 RX 和 TX 与单片机对应的口交叉相连就可以了,实际连线如下

第四步完成!

开始,第五步!!(最后一步了!!!)

将以下代码烧入单片机中

#include <stdio.h>

#include <reg51.h>

#include <ctype.h>

#include <string.h>

#include <math.h>

#define uchar unsigned char

#define uint unsigned int

sbit LED1 = P2^0;

sbit LED2 = P2^1;

sbit LED3 = P2^2;

sbit LED4 = P2^3;

sbit LED5 = P2^4;

sbit LED6 = P2^5;

sbit LED7 = P2^6;

sbit LED8 = P2^7;

// 串口中断接收相关

uint scount = 0, maxLen = 25, tscount = 0;

uchar srdatas[25];

// 计时器 0, 多大代表有多少个 50ms(0 ~ 65535)

uint time0Count = 0;

// 串口接收数据已处理标志

bit sflag = 0;

// 校验连接发送标志(1-表示需要发送)

bit tsflag = 0;

void Delay2(unsigned long cnt);

void Tranfer(uchars);

void SysInit();

void SetWifi();

void dealReceiveData();

void dealReceiveLine(ucharline, uint length);

void dealWifiConnectInfo();

// 10 进制 => 2 进制

//uchar* decimal2binary(uint val);

// 字符串转数字

// uint parseInt(uchar* str, uint len);

void Delay2(unsigned long cnt) {

long i;

for(i=0;i<cnt*10;i++);

}

/*

uchar* decimal2binary(uint val) {

uchar chs[8];

uint i = 0, tmp = val;

for(i = 0; i < 8; i++) {

if(tmp == 0) {

chs[i] = 0;

continue;

}

chs[i] = (tmp % 2) + 48;

tmp = tmp / 2;

}

for(i = 0; i < 4; i++) {tmp = chs[i];chs[i] = chs[8-i-1];chs[8-i-1] = tmp;}return chs;

}

*/

/*

uint parseInt(uchar* str, uint len) {

uint i = 0, resVal = 0;

for(i = 0; i < len; i++) {

resVal = resVal + ((str[i] - 0x30) * pow(10, len - i - 1));

}

return resVal;

}

*/

// 接收到字符串出现 /r/n, 视为新行标志

void dealReceiveData() {

uint t = 0;

if(sflag == 1 || scount <= 0) {return;}// 延时之后依然没有数据, 既断定为串口有数据接收到tscount = scount;// 使用 Delay2 有问题// Delay2(100);t = time0Count;// 演示 50 mswhile(abs(time0Count - t) <= 0);if(scount != tscount) {return;}// 数据处理期间暂停串口中断使能ES = 0;// 数组未溢出if(scount < maxLen) {// 接收到第二个数据之后, 判断是否出现了结束符if(scount > 2) {// 出现了换行符, 处理接收到的行的数据if(srdatas[scount - 2] == '\r' && srdatas[scount - 1] == '\n') {dealReceiveLine(srdatas, scount - 2);scount = 0;}}}// 执行之后即为串口接收到的数据已经处理sflag = 1;ES = 1;

}

void dealWifiConnectInfo() {

// 开始发送尝试重连

if(tsflag == 1) {

ET0 = 0;

printf(“AT+CIPCLOSE=2\r\n”);

Delay2(5);

printf(“AT+CIPSTART=2,“TCP”,“115.29.109.104”,6520\r\n”);

Delay2(10);

tsflag = 0;

ET0 = 1;

}

}

void dealReceiveLine(uchar* line, uint length) {

// bit hasCommand = 0;

uint i = 0, t = 0;

uchar command;

uchar newLine[25];

// 去除换行符if(length > 3) {for(i = 0; i < length; i++) {if(line[i] != '\r' && line[i] != '\n') {newLine[t] = line[i];t++; }if(t >= 25) {length = t;break;}}}if(length > 3) {// 处理开关控制指令if(newLine[0] == '+'&& newLine[1] == 'I'&& newLine[2] == 'P'&& newLine[3] == 'D') {i = 0;while(i < length && newLine[i] != ':') {i++;}// 存在有效位置if(i < length) {t = 0;for(i = i + 1; i < length; i++) {t++;if(newLine[i] == '/') {continue;}command = newLine[i] - 0x30;switch(t) {case 1:LED1 = !command;break;case 2:LED2 = !command;break;case 3:LED3 = !command;break;case 4:LED4 = !command;break;case 5:LED5 = !command;break;case 6:LED6 = !command;break;case 7:LED7 = !command;break;case 8:LED8 = !command;break;}if(t >= 8) {break;}}}}/*LED6 = ~LED6;// 处理定时轮询的远程连接状态响应数据if(tsflag == 1) {LED7 = ~LED7;if(newLine[0] == 'A'&& newLine[1] == 'L'&& newLine[2] == 'R'&& newLine[3] == 'E'&& newLine[4] == 'A'&& newLine[5] == 'D'&& newLine[6] == 'Y') {LED8 = 0;} else {LED8 = 1;}tsflag = 0;}*/}

}

void SysInit() {

// 初始化定时器1, 配置波特率发生器

TH1 = 0xFD; //晶振11.0592mhz 波特率设为9600

TL1 = TH1;

TMOD |= 0x20; //定时器1方式2

SCON = 0x50; //串口接收使能

ES = 1; //串口中断使能

TR1 = 1; //定时器1使能

TI = 1; //发送中断标记位,必须设置

// 初始化定时器0, 做系统定时任务(11.0592MHz, 定时 50ms)/* */TH0 = 0x4C;TL0 = 0x00;TMOD |= 0x01; // 工作在方式2TR0 = 1; // 定时器0使能ET0 = 1;//REN = 0; // 禁止串口接收数据printf("begin init wifi...\r\n");SetWifi();printf("wifi inited...\r\n");//REN = 1;EA=1;

}

void SetWifi() {

Delay2(1000);

printf(“AT+CIPMUX=1\r\n”);

Delay2(1000);

printf(“AT+CIPSERVER=1\r\n”);

Delay2(1000);

printf(“AT+CIPCLOSE=2\r\n”);

Delay2(2000);

printf(“AT+CIPSTART=2,“TCP”,“115.29.109.104”,6520\r\n”);

Delay2(2000);

}

/**/

void Timer0() interrupt 1 {

uint t = 0;

ET0 = 0;

// 继续下一轮定时

TH0 = 0x4C;

TL0 = 0x00;

time0Count = (time0Count + 1) % 1200;

// 大概 30s 判断一下连接是否断开, 断开之后需要重连

if(time0Count % 600 == 0) {

tsflag = 1;

}

ET0 = 1;

}

void Usart() interrupt 4 {

if(RI == 1)

{

RI = 0;

srdatas[scount] = SBUF;

scount += 1;

if(scount >= maxLen) {

scount = 0;

}

sflag = 0;

}

}

void main() {

SysInit();

while(1) {

dealReceiveData();

dealWifiConnectInfo();

}

}

备注:void dealReceiveLine(…) { … }

处理逻辑如下

去除接收到的行的前后换行符。

判断处理后的结果是否以 +IPD 开头。

找到 : 后的 8 个字符,依次控制 LED1 ~ LED8 的开关状态,1 为开启,0 为关闭。

发送1100000000之后的样子:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。