1  芯片及电路的介绍

1.1  8266WIFI模块

在文章的最开始我们首先要介绍今天的主角,8266WIFI模块。这是一个非常好用的模块,其他的废话不在多说,我们直接上干货.

这是一张我从百度上盗的一张8266WIFI模块的原理图,虽然8个引脚看着很复杂,但实际上我们只会用到最多五个引脚(1.VCC 2.GND 3.UTXD 4.URXD 5.CH_PD)。为什么说最多用到五个引脚呢,因为我在网上查资料的时候很多人只是用到了四个引脚,并没有使用CH_PD这个引脚,但是具体是什么原因呢,我们在这个入门篇就不进行深入的讨论了。咱们只要记住,如果只接了四个引脚不行的话那么我们就考虑一下接五个引脚。

下面我们来说一下五个引脚是如何连接的。首先电源和接地是必须要连的,VCC引脚接3V左右的电源,GND接地,UTXD接单片机的RXD,URXD接单片机的TXD,CH_PD引脚也需要接3V的电源(有的人不需要接也可以工作,但是我的那个模块不行)。这里要说明一下,我们51单片机的工作电压为5V,而8266WIFI模块的工作电压为3V,如果8266WIFI模块也接到5V的电源的话很有可能会烧坏,这里我们需要注意一下。还有在实际的操作时有一个参考电压的问题,在下文我们在详细讲解。下边一张又丑又简单的接线图送给大家。

说完了接线之后我们还需要了解一下关于8266WIFI模块的AT指令,如何让8266WIFI模块工作,这是单片机驱动8266WIFI模块过程中一个必须要了解的问题(敲黑板,划重点了)。8266WIFI模块的AT指令有很多,但是我们用到的其实也就只有那么几个,下边我们来一一介绍。

1、AT+CIOBAUD=4800——这是改变波特率的指令,这是非常重要的一个指令,我们买来的8266WIFI模块大多数的波特率都是115200(我买的那个就是),而单片机达不到这么高的波特率,所以我们要做的第一步就是设置波特率。当然了,波特率的设置必须是要在电脑上完成的,我用的软件是安可信串口调试助手这个软件,用这个软件的时候我们要记得把波特率调到115200才可以进行通信,如果各位买到的8266WIFI模块在115200这个波特率下无法与电脑实现通信,那么就需要联系一下卖家了。

2、AT+CWMODE=2——这是模式设定指令,8266WIFI模块有三种工作模式,AT+CWMODE=1为Station模式,AT+CWMODE=2为AP模式,AT+CWMODE=3为Station+AP模式。那么什么是Station模式呢,说白了就是这个WIFI模块可以连接别的WIFI信号,这个模式在我们这一次的设计中应用的不多,所以我们就先不做详细的讲解。AP模式是我们要讲解的重点,AP模式也就是我们可以发射WIFI信号,别的手机呀电脑呀可以连接我们的8266WIFI模块。那Station+AP模式大家就了然于胸了吧,也就是我们既可以连接别的WIFI信号又可以发送信号让别人连,但是由于固件的原因,我们并不能实现8266WIFI模块连接了别的有网的WIFI信号后,有手机在连接8266WIFI模块后手机就可以上网了,这个功能是不能实现的,这段话看着挺绕的,实际上就是8266WIFI模块不能做WIFI网络的信号中继器(具体叫什么功能我也不太清楚,大概就是这个意思吧,哈哈,这不是重点)。实际上在今后的开发中,由于云服务器的存在,我们需要用到Station+AP模式的次数还是很多的。在这个入门设计中我们先不说,大家可以关注我们博客,我还会发别的设计讲解的。

3、AT+CWSAP="名称",“密码”,通道,加密方式——这一指令就是设置WIFI信号名称和密码还有加密方式的一个指令,通道可以设置成3,加密方式建议设置成4,因为某米手机的某些原因导致其他加密方式连不上WIFI信号,这是我在实验过程中遇到的问题,不知道别人是否也遇到过这样的问题。我再来说一下加密方式的数字都代表了什么意思,0是没有密码的意思,1是WEP加密方式,2是WPA_PSK加密方式,3是WPA2_PSK加密方式,4是WPA_WPA2_PSK加密方式。

4、AT+CIPMUX=1——这个指令为设置多路,如果1变为零的话就是设置单路,但是我们在这里必须要设置为多路才能进行以后的工作。

5、AT+CIPSERVER=1,8080——这个指令是设置为服务器模式,数字1代表着开始,数字8080代表着端口号,这个数字可以随便设置,但是为了防止和电脑系统中其他程序的端口冲突我们还是建议设置成大一些的数字。

我们在单片机驱动8266WIFI模块的程序中基本上就只用到了这几个指令,其他指令我们不在多说。有一点我们要特别注意,第一条指令和第三条指令需要在电脑上完成。还有一点很重要,就是WIFI模块断电后第4条指令和第5条指令需要重新设置,所以我们在单片机程序编写的时候要进行编写。

1.2 51单片机

我用的51单片机是STM公司出的单片机,这款单片机有一个好处就是可以直接从RXD和TXD引脚直接进行通信,最小系统的构建相对来说比较简单,只涉及到了晶振电路、复位电路以及EA/VPP端的高电平。下面我们直接上图,哈哈,原理图非常简单,我就又盗了一张,大家将就着看。

这张原理图基本上已经是比较全的了,不过我在EA/VPP端接高电平的时候还加了一个10K欧姆的电阻进行限流。在这张原理图中,我们需要注意的就是晶振电路一定要有,不过这都是常识了,没有晶振单片机就不工作啦。其实单片机我们在学校的学习中已经是非常的熟悉了。在本设计中,对于单片机的知识也就只涉及到了中断、波特率的设置、IO口的输出还有RXD端口和TXD端口的数据读写。就这些知识点而言可以说是非常简单了,任何一本教科书都有讲解。

2  软件编写

2.1 单片机软件编写

废话不多说,直接上程序。这是一个非常简单的测试程序,可以直接跑通。在这个程序里有一点要注意,就是单片机波特率的设置问题。

#include<reg52.h>
#include<string.h>
sbit L1 = P1^0;
sbit kaiguan = P3^4;
sbit L2 = P1^1;
sbit L3 = P1^2;
sbit L4 = P1^3;
sbit L5 = P1^4;
sbit L6 = P1^5;
sbit L7 = P1^6;
sbit L8 = P1^7;
unsigned char Usart_Receive[20]={0};
unsigned char Usart_Cnt=0;
bit Usart_AT_flage;
unsigned char code RST[]="AT+RST\r\n";
unsigned char code CWMODE2[]="AT+CWMODE=2\r\n";
unsigned char code CIPMUX[]="AT+CIPMUX=1\r\n";
unsigned char code CIFSR[]="AT+CIFSR\r\n";
unsigned char code CIPSERVER[]="AT+CIPSERVER=1,8080\r\n";
/**********************************************************/
void delay_ms(unsigned long t)
{unsigned int x,y;for(x=t;x>0;x--){for(y=110;y>0;y--){}}
}
/**********************************************************/
void delays(void)
{unsigned char a,b,c;for(c=95;c>0;c--){for (b=26;b>0;b--){for (a=185;a>0;a--){}}}
}
/***************中断设置***********************************/
void InitUART(void)
{TMOD=0x20;SCON=0x50;
/***************波特率设置*********************************/TH1=0xFA;TL1=TH1;PCON=0x00;EA=1;ES=1;TR1=1;
}
/*************发送数据***************************************/
void Send_Uart(unsigned char value)
{ES=0;TI=0;SBUF=value;while(TI==0);TI=0;ES=1;
}
/*************接受数据***************************************/
void UARTInterrupt(void)interrupt 4
{if(RI){RI=0;Usart_Receive[Usart_Cnt]=SBUF;Usart_Cnt++;if(Usart_Receive[Usart_Cnt-2]=='\r'&&Usart_Receive[Usart_Cnt-1]=='\n'&&Usart_Cnt>=2){Usart_Cnt=0;Usart_AT_flage=1;}else if(Usart_Cnt>20){Usart_Cnt=0;}}
}
/*****************发送设置**********************************/
void ESP8266_Set(unsigned char *puf)
{while(*puf!='\0'){Send_Uart(*puf);puf++;}
}
/**************设置多连*************************************/
void ManyConnect_AP()
{L4=0;ESP8266_Set(RST);//返回一大溜,不用判断返回delays();delays();while(1){ESP8266_Set(CWMODE2);//返回okdelays();if(Usart_AT_flage ==1){if(strstr(Usart_Receive, "OK") ){Usart_AT_flage = 0;L1 = 0;break;}}}while (1){ESP8266_Set(CIPMUX);//返回okdelays();if(Usart_AT_flage ==1){if(strstr(Usart_Receive, "OK") ){Usart_AT_flage = 0;L2 = 0;break;}}}while (1){ESP8266_Set(CIPSERVER);//返回ok,多了也返回okdelays();if(Usart_AT_flage ==1){if(strstr(Usart_Receive, "OK") ){Usart_AT_flage = 0;L3 = 0;break;}}}
}
/***************延时500ms***************************/
void delays500ms(void)
{unsigned char a,b,c;for(c=123;c>0;c--){for(b=212;b>0;b--){for(a=25;a>0;a--){}}}
}
/**************主函数**********************************/
void main()
{int i;P2=0x00;kaiguan=0;InitUART();while(1){ManyConnect_AP();while(1){//由于消息的开头是+IP  故做此判断,00000000000000000号if((Usart_Receive[0]=='+')&&(Usart_Receive[1]=='I')&&(Usart_Receive[2]=='P')){if((Usart_Receive[3]=='D')&&(Usart_Receive[6]==',')){if(Usart_Receive[9]=='1'){delays500ms();P2=0xFF;delays();for(i = 0 ; i<20; i++){Usart_Receive[i]=' ';}}if(Usart_Receive[9]=='0'){P2=0x00;delays();for(i=0;i<20;i++){Usart_Receive[i]=' ';}}}}}}
}
 unsigned int x,y;for(x=t;x>0;x--){for(y=110;y>0;y--){}}
}
/**********************************************************/
void delays(void)
{unsigned char a,b,c;for(c=95;c>0;c--){for (b=26;b>0;b--){for (a=185;a>0;a--){}}}
}
/***************中断设置***********************************/
void InitUART(void)
{TMOD=0x20;SCON=0x50;
/***************波特率设置*********************************/TH1=0xFA;TL1=TH1;PCON=0x00;EA=1;ES=1;TR1=1;
}
/*************发送数据***************************************/
void Send_Uart(unsigned char value)
{ES=0;TI=0;SBUF=value;while(TI==0);TI=0;ES=1;
}
/*************接受数据***************************************/
void UARTInterrupt(void)interrupt 4
{if(RI){RI=0;Usart_Receive[Usart_Cnt]=SBUF;Usart_Cnt++;if(Usart_Receive[Usart_Cnt-2]=='\r'&&Usart_Receive[Usart_Cnt-1]=='\n'&&Usart_Cnt>=2){Usart_Cnt=0;Usart_AT_flage=1;}else if(Usart_Cnt>20){Usart_Cnt=0;}}
}
/*****************发送设置**********************************/
void ESP8266_Set(unsigned char *puf)
{while(*puf!='\0'){Send_Uart(*puf);puf++;}
}
/**************设置多连*************************************/
void ManyConnect_AP()
{L4=0;ESP8266_Set(RST);//返回一大溜,不用判断返回delays();delays();while(1){ESP8266_Set(CWMODE2);//返回okdelays();if(Usart_AT_flage ==1){if(strstr(Usart_Receive, "OK") ){Usart_AT_flage = 0;L1 = 0;break;}}}while (1){ESP8266_Set(CIPMUX);//返回okdelays();if(Usart_AT_flage ==1){if(strstr(Usart_Receive, "OK") ){Usart_AT_flage = 0;L2 = 0;break;}}}while (1){ESP8266_Set(CIPSERVER);//返回ok,多了也返回okdelays();if(Usart_AT_flage ==1){if(strstr(Usart_Receive, "OK") ){Usart_AT_flage = 0;L3 = 0;break;}}}
}
/***************延时500ms***************************/
void delays500ms(void)
{unsigned char a,b,c;for(c=123;c>0;c--){for(b=212;b>0;b--){for(a=25;a>0;a--){}}}
}
/**************主函数**********************************/
void main()
{int i;P2=0x00;kaiguan=0;InitUART();while(1){ManyConnect_AP();while(1){//由于消息的开头是+IP  故做此判断,00000000000000000号if((Usart_Receive[0]=='+')&&(Usart_Receive[1]=='I')&&(Usart_Receive[2]=='P')){if((Usart_Receive[3]=='D')&&(Usart_Receive[6]==',')){if(Usart_Receive[9]=='1'){delays500ms();P2=0xFF;delays();for(i = 0 ; i<20; i++){Usart_Receive[i]=' ';}}if(Usart_Receive[9]=='0'){P2=0x00;delays();for(i=0;i<20;i++){Usart_Receive[i]=' ';}}}}}}
}

2.2 手机端软件编写

废话不多说,先上程序。

首先,我先发一个Content_main的程序,这个段代码很简单,只有三个按钮以及一个Edittext,但是EditText这个功能并没有用到。在以后开发中会用到,在这里先埋下一个伏笔。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"><Buttonandroid:id="@+id/button_1"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="连接"/><Buttonandroid:id="@+id/button_2"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="开灯"/><Buttonandroid:id="@+id/button_3"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="关灯"/><EditTextandroid:id="@+id/text_1"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="显示开关状态"/>
</LinearLayout>

然后在上ActivityCollector和BaseActivity代码,这段代码的作用是对活动进行管理。Android开发我也是刚刚接触,正在摸索阶段,这段代码是我在《第一行代码》这本书上学习到的,哈哈,学了就多用一用才能熟悉掌握。其他的我也不在多说了,大家就看一看代码,其实很好理解。

import android.app.Activity;
import java.util.ArrayList;
import java.util.List;public class ActivityCollector {public static List<Activity> activities=new ArrayList<>();public static void addActivity(Activity activity){activities.add(activity);}public static void removeActivity(Activity activity){activities.remove(activity);}public static void finishAll(){for (Activity activity:activities){if(!activity.isFinishing()){activity.finish();}}activities.clear();}
}
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;public class BaseActivity extends AppCompatActivity {protected void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);ActivityCollector.addActivity(this);}protected void onDestroy(){super.onDestroy();ActivityCollector.removeActivity(this);}
}

下边我们在来一段MainActivity的代码,这段代码中就涉及到了Socket方面的知识了,其实我也是一个编程小白,好多东西也都是现学现卖。我在代码的下边会稍微讲解一下关于Socket方面的知识,很肤浅的一些东西,大家就参考的去看一下,求轻喷,哈哈。

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;import java.io.BufferedReader;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.net.Socket;public class MainActivity extends BaseActivity {private Button button1;private Button button2;private Button button3;public Socket socket;private EditText text1;private static final String HOST="192.168.4.1";private PrintWriter printWriter;private BufferedReader br;protected void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);button1=(Button)findViewById(R.id.button_1);button2=(Button)findViewById(R.id.button_2);button3=(Button)findViewById(R.id.button_3);text1=(EditText)findViewById(R.id.text_1);button1.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {new Thread(new Runnable() {@Overridepublic void run() {try {socket=new Socket(HOST,8080);}catch (Exception e){e.printStackTrace();}}}).start();}});button2.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {new Thread(new Runnable() {@Overridepublic void run() {try {PrintStream ps=new PrintStream(socket.getOutputStream());ps.println("1");}catch (Exception e){e.printStackTrace();}}}).start();}});button3.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {new Thread(new Runnable() {@Overridepublic void run() {try {PrintStream ps=new PrintStream(socket.getOutputStream());ps.println("0");}catch (Exception e){e.printStackTrace();}}}).start();}});}
}

这段代码其实在我测试完了之后发现了很多问题,但是也可以跑通,暂时就先不做优化了,等开发下一个功能的时候在去做深入的优化。我先来说一下我发现的问题吧,大家参考的时候可以自己优化一下。首先,第一个问题就是在开灯和关灯的时候我感觉应该不开启线程其实也能运行,不过我没试,也不是很懂,希望各位大神可以在帖子下边留言,哈哈,我也还是在学习的阶段,有不正确的地方还请多多指教。其次还有一个问题就是开关按键可以集成成一个按键。暂时我就想到了这两个问题,其他问题慢慢再去发掘。

其实我写的代码非常简单易懂,哈哈,毕竟我也是个小白嘛。下面我们就来很肤浅的说一下关于Socket套接字方面的知识,首先,我是基于TCP协议来使用8266WIFI模块的,而TCP会有服务端还有客户端,我是本着让8266WIFI模块作为服务端,手机作为客户端的思想来进行开发的。所以在我们手机端就用到了TCP客户端的编程代码。其次,我们来说一下Socket套接字的工作流程,其实我学习编程的学习方法是掌握一些类或方法或者硬件的工作流程来进行学习的,而Socket套接字的工作流程就是先创建Socket方法的实例,其中参数带入IP地址还有端口,这是第一步,完成这一步我们的客户端和服务器就算是连接上了。然后第二步就是数据的发送和接收,我们现在的设计中暂时没有涉及到接受数据的知识,所以不在讲解,我们只来说一下发送数据的方法。发送数据需要用到PrintStream方法以及getOutputStream方法。这两个方法是发送数据的关键,这一步做完之后直接调用Println方法来放入要存入的数据或指令。其实我们结合着单片机的代码可以发现,我们单片机只是判断接受到的数据到底是什么如果是1就开灯,如果是0就关灯。其实思想很简单。

3  开发过程中所遇到的问题

3.1 8266WIFI模块测试问题

当我买来8266WIFI模块的第一步当然是测试一下模块的功能都有什么了,那时候基本上是啥也不懂,就在网上看一些资料后就开始操作,这时候问题来了。我在买8266WIFI模块之前手里有一个TTL串口的连接线,我一开始以为用这个可以调试8266WIFI模块的,但是后来发现并不能,可能有的人可以用TTL串口连接线调试,但是我这个是真的遇到问题了,查了一下资料发现,实际上是TTL串口连接线的电压不稳定,导致8266WIFI模块不能正常工作。

解决方法:在某宝上买了一个专门调试8266WIFI模块的模块,然后问题解决了。

3.2 8266WIFI模块和单片机电源的问题

在开发的过程中我遇到了一个问题就是,单片机和8266WIFI模块无法正常通信,而且波特率也调的一致了,在电脑上用串口助手测试的也都通过了,但是单片机和8266WIFI模块一接线就不能用,后来查了一些资料发现,有一个参考电压的问题,也就是说,单片机和8266WIFI模块必须要共接地,这样才能实现通信。我遇到这个问题的原因是因为8266WIFI模块的工作电压是3V,而单片机的工作电压是5V,所以我找了两个电源进行供电,这时候问题就出来了。哈哈,这是一个比较低级的错误。

4  总结

在开发的过程中也是遇到了一些问题,但是也都解决了,这次的设计只是一个非常入门的设计,用到的网络也是局域网,操作指令也很简单,传输的数据量也很小,而且没有涉及到手机接收单片机发来的信息的功能。总而言之就是很简单,下一步的设计我打算做一些涉及到公共网络而且有接收有发送的设计,而且Android软件方面也会做一些优化。希望大家可以关注。哈哈,我只是普通学生一枚,不是大神,请各位多多指教,轻喷~轻喷~~哈哈,我会继续学习的。

基于8266WIFI模块实现智能手机与51单片机的通信入门相关推荐

  1. 51单片机串口通信【收集学习向】

    本篇整理了学习51串口通信过程中看到的一些比较好的文章,有很多的超链接.并根据自己遇到的情况分析了串口传输乱码的一些原因. 目录 1.原理知识 2.测试程序和虚拟仿真 3.电路设计与公母口连线 电路设 ...

  2. 51单片机串口通信模板_深入理解51单片机串口通信及通信实例

    串口通信的原理 串口通信(SerialCommunications)的概念非常简单,串口按位(bit)发送和接收字节.尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一 ...

  3. 51单片机的新手入门前所有疑问整理

    51单片机的新手入门前所有疑问整理 ///插播一条:我自己在今年年初录制了一套还比较系统的入门单片机教程,想要的同学找我拿就行了免費的,私信我就可以哦~点我头像黑色字体加我地球呺也能领取哦.最近比较闲 ...

  4. 51单片机攻略—入门

    51单片机攻略-入门测试:点亮一个LED 一.基础知识 (一)单片机的电平特性 1.TTL电平 TTL电平信号规定,+5V等价于逻辑"1",0V等价于逻辑"0" ...

  5. 51单片机红外通信及控制LED灯(LCD1602显示)

    51单片机红外通信及控制LED灯(LCD1602显示) 大家好,又和大家见面了,离上一次DS18B20传感器的文章已经过去了一个星期了,这期我将给大家带来,基于STC89C52芯片和HS0038红外接 ...

  6. 51单片机串口通信原理、相关寄存器配置与简单串口收发程序代码

    目录 1. 串口通信原理 2. 51单片机串口通信 2.1 串口简要模式图 2.2 相关寄存器 (1)PCON.SCON.SBUF (2)IE.IPH.IP (3)配置T1定时器 2.3 波特率和系统 ...

  7. 51单片机串口通信模板_51单片机串口通信

    51 单片机串口通信 51 单片机串口通信(转载) 2009-03-03 18:22 一.串口通信原理 串口通讯对单片机而言意义重大,不但可以实现将单片机的数据传输到计 算机端,而且也能实现计算机对单 ...

  8. 51单片机~串口通信(讲解+代码)

    51单片机~串口通信 (一)计算机串行通信原理: 综上:所以在设置的时候,经常将SCON设置为0X50==0101 0000 ,使用方式1. (二)工作: 中断控制 led灯,每发送一条指令灯亮或灭( ...

  9. 51单片机串口通信发送以及接收代码详解1

    #include <reg51.h> //实验现象:单片接收电脑发送的字符串,并发回给PC端的代码.//函数声明 void uart_init(void); void uart_seng_ ...

最新文章

  1. 详解分布式一致性机制
  2. EFLS开源 | 阿里妈妈联邦学习解决方案详解
  3. java开发人员_Java 8:开发人员怎么看?
  4. fastdfs windows部署_从零搭建分布式文件系统MinIO比FastDFS要更合适
  5. Qt4_使用QXmlStreamReader读取XML
  6. 编写适合于自己的代码生成器 (zhuan)
  7. php通过post请求_php代码post请求
  8. 视频教程-Oracle 11G 入门到项目实战-Oracle
  9. video.h5.player.js视频播放器
  10. Tungsten Fabric知识库丨构建、安装与公有云部署
  11. python课程作业-贪吃蛇
  12. workman实现websocket聊天nginx的配置
  13. 关于美国安利的真实情况 !!!!!
  14. 【私藏】开发APP必须知道的API集合
  15. easy-excel导出excel中日期列需要双击才能进行筛选
  16. spring2.5.6升级到4.3.7常见问题
  17. 软件测试人员面试技巧总结
  18. 英语发音规则---ir字母组合发音规律
  19. python市场_大交易数据的python市场篮子分析
  20. Spring MVC更多家族成员----文件上传---06

热门文章

  1. 利用主成分PCA进行特征提取
  2. 正则环视 php,正则高级环视
  3. python简单实例-python简单案例
  4. 云计算上安装mysql,redis
  5. linux termios结构
  6. 如何将pip更新到最新版本?
  7. 【C语言】图像处理-揭秘电影特效,随心所欲,合成图像
  8. anchor base和anchor free, 小物体检测, YOLO V1-3 9000 V4 V5 的区别,yolov5-8, yolox创新点
  9. 《统计学习方法》全部算法
  10. 在IntelliJ IDEA中,开发一个摸鱼看书插件