串口通讯(第2篇)WIFI模块

编程入门 行业动态 更新时间:2024-10-08 08:22:15

<a href=https://www.elefans.com/category/jswz/34/1769224.html style=串口通讯(第2篇)WIFI模块"/>

串口通讯(第2篇)WIFI模块

目录

1.WIFI模块ESP-01s

2.AT指令

2.1初始配置和验证

2.2入网设置

2.3连接到 TCP server

3.使用单片机进行AT设置-连接服务器

4.ESP作为服务器


注意:需要在同一个局域网下(连接到相同的WiFi),才能连接到服务器

1.WIFI模块ESP-01s

蓝牙,ESP-01s,Zigbee, NB-Iot等通信模块都是基于AT指令的设计

2.AT指令

对终端设备进行配置。

2.1初始配置和验证

ESP-01s出厂波特率正常是115200, 注意:AT指令,控制类都要加回车,数据传输时不加回车。

上电后,串口输出系统开机信息,购买的部分模块可能电压不稳乱码,以 ready 为准。

################################################
arch:ESP8266, 1
compile_time:Ai-Thinker|B&T
wifi_mac:4c75250dAE2F
sdk_version:v3.4-22-g967752e2
firmware_version:2.2.0
compile_time:Jun 30 2021 11:28:20
ready
################################################

上电后发送AT指令测试通信及模块功能是否正常

AT
OK

通过一下命令配置成9600波特率

AT+UART=9600,8,1,0,0

2.2入网设置

设置工作模式

AT+CWMODE=3 //1. 是station(设备)模式 2.是AP(路由)模式 3.是双模
OK

以设备模式接入家中路由器配置

AT+CWJAP="TP-LINK_3E30","18650711783" //指令
WIFI CONNECTED //结果
WIFI GOT IP   //结果

查询IP地址

AT+CIFSR  //指令
+CIFSR:APIP,"192.168.4.1"
+CIFSR:APMAC,"4e:75:25:0d:ae:2f"
+CIFSR:STAIP,"192.168.0.148"
+CIFSR:STAMAC,"4c:75:25:0d:ae:2f"
OK

2.3连接到 TCP server

1. 开关网络助手,设立TCP服务器

 2. 连接服务器

AT+CIPSTART="TCP","192.168.0.113",8888 //指令,注意双引号逗号都要半角(英文)输入
CONNECT  //结果:成功
OK    //结果:成功

3. 发送数据1-限制字节

AT+CIPSEND=4 // 设置即将发送数据的长度 (这里是4个字节)
>CLCA // 看到大于号后,输入消息,CLCA,不要带回车
Response :SEND OK  //结果:成功
//注意,这种情况下,每次发送前都要先发送AT+CIPSEND=长度 的指令,再发数据!

4.发送数据2-透传模式

AT+CIPMODE=1  //开启透传模式
Response :OK
AT+CIPSEND //带回车Response: >  //这个时候随意发送接收数据咯

退出透传模式

//在透传发送数据过程中,若识别到单独的⼀包数据 “+++”,则退出透传发送

3.使用单片机进行AT设置-连接服务器

服务器和ESP 联网时需要在一个局域网LAN下。

白盒测试方式,用串口助手查看AT设置情况。单片机接线图:

 单片机代码:

需要注意烧录的串口com3和查看的串口com4是不一样的

 #include "reg52.h"	//超声波控制LED#include "string.h"
sfr AUXR=0x8e;
sbit led1=P3^6;
sbit led2=P3^7;void Delay5000ms();
void init_usb(void);
void data_uart_transport(char *p);void main(void)
{code char LAN_connect[]         ="AT+CWJAP=\"yangkai\",\"12345678\"\r\n";code char TCP_server_connect[]  ="AT+CIPSTART=\"TCP\",\"172.20.10.5\",80\r\n";char touchuan_start[]      ="AT+CIPMODE=1\r\n";char datatransport_start[] ="AT+CIPSEND\r\n";init_usb();	   //串口初始化while(1){	data_uart_transport(&LAN_connect);Delay5000ms();data_uart_transport(&TCP_server_connect);Delay5000ms();data_uart_transport(&touchuan_start);Delay5000ms();data_uart_transport(&datatransport_start);Delay5000ms();		//data2=SBUF;   //接受外部数据后产生中断	 进入interrupt 4		}	
}
void data_uart_transport(char *p)
{while(*p != '\0'){SBUF= *(p++);	 //发送完成后产生中断   进入interrupt 4while(!TI);TI=0;			}			
}void UART_Pountine(void) interrupt 4
{static int i=0;static char cmd[12];if(TI){//Delay500ms();led2=~led2;	  //每次发送完一个字符h e l就进入一次,因为太快,所以感觉一直亮着}if(RI){				   //接受外部数据后产生中断	 进入interrupt 4RI=0;cmd[i]=SBUF;i++;if(strstr(cmd,"en")){led1=0;i=0;memset(cmd,'\0',12);}if(strstr(cmd,"cl")){led1=1;i=0;memset(cmd,'\0',12);}if(i==12){i=0;}}
}void init_usb(void)
{SCON=0x50;//采用工作方式1进行通讯PCON &= 0x7F;  //要清0就 &上0ET1=0;//串口用的定时器1,关闭中断。配置相同的波特率//TCON 定时器控制寄存器TR1=1;  //打开定时器1//TMOD? 定时器模式寄存器TMOD &=0x0F; //&0就清0TMOD |=0x20; // |1就变1TH1=0xFD; //高位? ? ? 自动重装时TH1将自动装入TL1TL1=0xFD; //低位//TI 中断请求标志位   RI中断请求标志位EA=1;ES=1;   //总中断允许位  串口中断允许位 
}void Delay5000ms()		//@11.0592MHz
{unsigned char i, j, k;//	_nop_();i = 36;j = 5;k = 211;do{do{while (--k);} while (--j);} while (--i);
}

优化代码——(不是延迟5s执行下一步)——换一种链接方式(用返回值确定是否执行下一步)

ERROR
WIFI CONNECTED
WIFI GOT IP
AT+CIPSTART="TCP","172.20.10.5",80
CONNECTOK
AT+CIPMODE=1OK
AT+CIPSENDOK

需要注意问题:串口通讯是接收和发送是同时进行的;
//所以上一个发送后的接收,不能影响这一个,
解决方法// 给予接收时间(延迟)   再执行下一步的发送指令

方法论:在软件中——快速是需要付出错误的代价的。 

 

 #include "reg52.h"	#include "string.h"sfr AUXR=0x8e;
sbit led1=P3^6;
sbit led2=P3^7;
int LAN_mark=0;
int other_land_mark=0;
int suceed_mark=0;
int error=1; void Delay5000ms();
void init_usb(void);
void data_uart_transport(char *p);
void Delay10ms();void main(void)
{code char LAN_connect[]         ="AT+CWJAP=\"yangkai\",\"12345678\"\r\n";code char TCP_server_connect[]  ="AT+CIPSTART=\"TCP\",\"172.20.10.5\",80\r\n";char touchuan_start[]      ="AT+CIPMODE=1\r\n";char datatransport_start[] ="AT+CIPSEND\r\n";char reset[]               ="AT+RST\r\n";char my_word[]             ="hello world";init_usb();	   //串口初始化while((!suceed_mark) || (!error)){		  //不成功就重启然后执行data_uart_transport(&reset);		//重启other_land_mark=0;   //重新置0LAN_mark=0;			 //重新置0error=1;			//重新置1Delay5000ms();data_uart_transport(&LAN_connect);	   //发送联网指令    "yangkai\",\"12345678\"\r\n";while(!LAN_mark);   //接收到 wifi  GOTIP执行下一步LAN_mark变为1Delay10ms();Delay10ms();Delay10ms();Delay10ms();Delay10ms();    //发送和接收都在一直执行,所以上一个不能影响这一个,接收一会儿不接受了再执行下一步Delay5000ms();data_uart_transport(&TCP_server_connect);			//发送"TCP\",\"172.20.10.5\",80\r\n";while(!other_land_mark); //接收到OK执行下一步other_land_mark 变为1other_land_mark=0;   //重新置0Delay10ms();data_uart_transport(&touchuan_start);		//AT+CIPMODE=1\r\n";while(!other_land_mark); //other_land_mark接收到OK执行下一步other_land_mark=0;   //重新置0Delay10ms();data_uart_transport(&datatransport_start);	   //"AT+CIPSEND\r\n"while(!other_land_mark); //other_land_mark接收到OK执行下一步Delay10ms();if(LAN_mark==1 && other_land_mark==1 && error==1){led1=0; led2=0;  //联网成功点亮led1	   led2=0;  //eps进入透传接收模式suceed_mark=1;   //成功了}}while(1){	data_uart_transport(&my_word);Delay5000ms();//data2=SBUF;   //接受外部数据后产生中断	 进入interrupt 4		}	
}
void data_uart_transport(char *p)
{while(*p != '\0'){SBUF= *(p++);	 //发送完成后产生中断   进入interrupt 4while(!TI);TI=0;			}			
}void UART_Pountine(void) interrupt 4
{static int i=0;static char cmd[7];char tmp;if(TI){//Delay500ms();//led2=~led2;	  //每次发送完一个字符h e l就进入一次,因为太快,所以感觉一直亮着}if(RI){				   //接受外部数据后产生中断	 进入interrupt 4RI=0;tmp=SBUF;if(tmp=='W' || tmp=='O' || tmp=='L' || tmp=='E' ){		 //w 和o、L、e 始终放置在第0位i=0;}cmd[i]=tmp;if(cmd[0]=='W' && cmd[5]=='G'){   //局域网接入成功		 如果出现WIFI GOT IPLAN_mark=1;//memset(cmd,'\0',7);}if(cmd[0]=='O' && cmd[1]=='K'){	  //其它操作接入成功	 如果出现OKother_land_mark=1;//memset(cmd,'\0',7);}if(cmd[0]=='E' && cmd[1]=='R'){					   //如果出现错误ERROR		如果出现错误FALL联局域网失败没办法、有BUG。解决办法是字符的精确匹配和每个标志位单独设置标记,当4个标记同时成功才不重启了						   other_land_mark=1;	                //出现错误ERROR如何让其通畅 回到while   但是suceed——mark不变error=0;						   //用error进行互锁}if(cmd[0]=='L' && cmd[1]=='1'){					   //点led1	 如果出现L1led1=~led1;i=0;//memset(cmd,'\0',7);}if(cmd[0]=='L' && cmd[1]=='2'){					   //点led2	 如果出现L2led2=~led2;i=0;//memset(cmd,'\0',7);}i++;if(i==7){					   //存储数组恢复i=0;}}
}void init_usb(void)
{SCON=0x50;//采用工作方式1进行通讯PCON &= 0x7F;  //要清0就 &上0ET1=0;//串口用的定时器1,关闭中断。配置相同的波特率//TCON 定时器控制寄存器TR1=1;  //打开定时器1//TMOD? 定时器模式寄存器TMOD &=0x0F; //&0就清0TMOD |=0x20; // |1就变1TH1=0xFD; //高位? ? ? 自动重装时TH1将自动装入TL1TL1=0xFD; //低位//TI 中断请求标志位   RI中断请求标志位EA=1;ES=1;   //总中断允许位  串口中断允许位 
}void Delay5000ms()		//@11.0592MHz
{unsigned char i, j, k;//	_nop_();i = 36;j = 5;k = 211;do{do{while (--k);} while (--j);} while (--i);
}
void Delay10ms()		//@11.0592MHz
{unsigned char i, j;i = 18;j = 235;do{while (--j);} while (--i);
}

4.ESP作为服务器

注意:用某些字符去匹配很容易出现BUG

想用ERROR中的ER去检测错误发送,但是CIPSERVER中也有ER根本卡不住。换成ERR就可以

(现在都不明白为什么发送字符CIPSERVER,检测也会检测到,明明说是两个物理地址啊。

而且检测到OK之后必须延迟一点,不然数据会BUSY忙,不成功。(但是老师的不用延时))

说明发送和接收用的同一个物理地址,只有发送完了,清空才能进行接收。

电脑晶振比单片机的快,所以用串口发送时,会提前反应,不是串口通讯进出有快慢

USB转TTL插入电脑,TX--RX RX-TX VCC-3.3V GDN-GND
查询IP地址:AT+CIFSR

//0重启
+STA_CONNECTED:"c0:a5:dd:54:0c:ef"
+DIST_STA_IP:"c0:a5:dd:54:0c:ef","192.168.4.2"
WIFI DISCONNECT
隔5秒后下一个
//1 配置成双模
AT+CWMODE=2
Response :OK
//2 使能多链接
AT+CIPMUX=1
Response :OK
//3 建立TCPServer
AT+CIPSERVER=1,8888 // default port = 333
Response :OK//然后TCP client去连接服务器1,8888
Response :0,CONNECT//4 发送数据
AT+CIPSEND=0,4 // 发送4个字节在连接0通道上
>abcd //输入数据,不带回车
Response :SEND OK
//• 接收数据
+IPD, 0, n: xxxxxxxxxx  //+IPD是固定字符串 0是通道,n是数据长度,xxx是数据
//断开连接
AT+CIPCLOSE=0
Response :0, CLOSED OK
#include "reg52.h"	
#include "string.h"
#define SIZE 7sfr AUXR=0x8e;
sbit led1=P3^6;
sbit led2=P3^7;
char buffer[SIZE];
int TCP_mark=0;
int other_land_mark=0;
int suceed_mark=0;
int error=1; void Delay5000ms();
void init_usb(void);
void data_uart_transport(char *p);
void Delay500ms();void main(void)
{char mode_AP[]             ="AT+CWMODE=2\r\n";char mutiple_connect[]     ="AT+CIPMUX=1\r\n";char TCPserver[]		   ="AT+CIPSERVER=1,8888\r\n";char data_trans[]		   ="AT+CIPSEND=0,11\r\n";char reset[]               ="AT+RST\r\n";char my_word[]             ="hello world";Delay500ms();init_usb();	   //串口初始化while((!suceed_mark) || (!error)){		  //不成功就重启然后执行error=1;suceed_mark=0;other_land_mark=0;data_uart_transport(&reset);		//重启Delay5000ms();					   //延迟5sdata_uart_transport(&mode_AP);	   //发送配置双模模式    "AT+CWMODE=2\r\n"while(!other_land_mark);   //接收到 OK执行下一步LAN_mark变为1Delay500ms();Delay500ms();    //发送和接收都在一直执行,所以上一个不能影响这一个,接收一会儿不接受了再执行下一步	other_land_mark=0;data_uart_transport(&mutiple_connect);	   //发送配置多链接    "AT+CIPMUX=1\r\n"while(!other_land_mark);   //接收到 OK执行下一步Delay500ms();Delay500ms();    	TCP_mark=0;data_uart_transport(&TCPserver);	   //建立TCP服务器    AT+CIPSERVER=1,8888while(!TCP_mark);   //接收到 0,CONNECT执行下一步Delay500ms();Delay500ms();    	if(TCP_mark==1 && other_land_mark==1 && error==1){led1=0; led2=0;  //联网成功点亮led1	   led2=0;  //eps进入透传接收模式suceed_mark=1;   //成功了}}led1=0; while(1){led2=0;other_land_mark=0;data_uart_transport(&data_trans);while(!other_land_mark);		  //接收到OKdata_uart_transport(&my_word);Delay5000ms();//data2=SBUF;   //接受外部数据后产生中断	 进入interrupt 4		}	
}
void data_uart_transport(char *p)
{while(*p != '\0'){SBUF= *p;	 //发送完成后产生中断   进入interrupt 4while(!TI);TI=0;p++;			}			
}void UART_Pountine(void) interrupt 4
{static int i=0;char tmp;if(RI){				   //接受外部数据后产生中断	 进入interrupt 4RI=0;tmp=SBUF;if(tmp == 'W' || tmp == 'O' || tmp == 'L' || tmp == '0' || tmp == 'E'){		 //w 和o、L、e 始终放置在第0位i=0;}buffer[i++] = tmp;if(buffer[0] == 'O' && buffer[1] == 'K'){	  //其它操作接入成功	 如果出现OKother_land_mark=1;memset(buffer,'\0',sizeof(buffer));}	  if(buffer[0] == '0' && buffer[2] == 'C'){   //接入ESP服务器TCP成功 如果出现0,CONNECTTCP_mark = 1;memset(buffer,'\0',sizeof(buffer));}if(buffer[0]=='E' && buffer[1]=='R' && buffer[2]=='R'){	   //如果出现错误ERROR		如果出现错误FALL联局域网失败没办法、有BUG。解决办法是字符的精确匹配和每个标志位单独设置标记,当4个标记同时成功才不重启了						   other_land_mark=1;TCP_mark=1;	                //出现错误ERROR如何让其通畅 回到while   但是suceed——mark不变error=0;				   //用error进行互锁memset(buffer,'\0',sizeof(buffer));						   }if(buffer[0]=='L' && buffer[1]=='1'){					   //点led1	 如果出现L1led1=~led1;i=0;memset(buffer,'\0',sizeof(buffer));}if(buffer[0]=='L' && buffer[1]=='2'){					   //点led2	 如果出现L2led2=~led2;i=0;memset(buffer,'\0',sizeof(buffer));}if(i==6)i=0;					   //存储数组恢复			}
}void init_usb(void)
{AUXR=0X01;SCON=0x50;//采用工作方式1进行通讯//PCON &= 0x7F;  //要清0就 &上0	    //是不是有问题ET1=0;//串口用的定时器1,关闭中断。配置相同的波特率//TCON 定时器控制寄存器TR1=1;  //打开定时器1//TMOD? 定时器模式寄存器TMOD &=0x0F; //&0就清0	   这个和老陈不一样TMOD |=0x20; // |1就变1TH1=0xFD; //高位? ? ? 自动重装时TH1将自动装入TL1TL1=0xFD; //低位//TI 中断请求标志位   RI中断请求标志位EA=1;ES=1;   //总中断允许位  串口中断允许位 
}void Delay5000ms()		//@11.0592MHz
{unsigned char i, j, k;//	_nop_();i = 36;j = 5;k = 211;do{do{while (--k);} while (--j);} while (--i);
}
void Delay500ms()		//@11.0592MHz
{unsigned char i, j, k;//_nop_();i = 4;j = 129;k = 119;do{do{while (--k);} while (--j);} while (--i);
}

更多推荐

串口通讯(第2篇)WIFI模块

本文发布于:2024-02-07 01:22:48,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1752189.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:串口   模块   通讯   WIFI

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!