赞
踩
决定花点时间对51单片机使用esp8266模块与手机通信做个技术总结,帮助像我这样的小白少走弯路。虽然网上关于这个问题文章巨多,但可能因为关注点不同,或是我本人知识储备不够,虽然看了很多,过程还是碰到很多问题,又去补充相关知识,折腾好长一段时间,才最终解决。这篇总结,既是对过程知识点的梳理,也供被同样问题困扰的入门者参考。
一、设置esp8266
关于8266与电脑连接
8266模块有多种封装方式,一种是集成了ch340芯片,带有microUsb接口,可以直接用microUsb线连接到电脑usb口就可以了。另一种没有microUsb接口,则需要使用类似u盘的usb转ttl的小东西,用连接线与8266连接,再接到电脑usb口使用。
对8266进行AT配置
首先要使用电脑对8266进行初步配置,方式是在电脑上使用串口调试工具向8266发送AT命令。
初始8266固件是不支持AT命令的,需要刷固件。可以去安信可(8266开发商)的官网(www.ai-thinker.com)下载刷固件的工具,和固件文件。这个过程和刷手机类似,很简单,基本可以一次成功的,不再多说。
刷完固件后,就可以用串口调试工具(安信可官网也可以下载)配置8266了。配置方式为发送AT命令。AT命令非常多,完全没必要去全部搞清,只要把我们需要的几个掌握就可以了。
1.设置连接模式:
AT+CWMODE=2 开启 AP 模式(1为station模式,需要连别的wifi源,2为ap模式 esp8266作为wifi源)
2.设置wifi:
AT+CWSAP=“SSID”,“PWD”,CHI,ECN ;热点名字,热点密码,热点通道,热点加密方式。
如:AT+CWSAP="ESP8266","密码",4,3
加密方式0:OPEN, 1:WEP, 2:WPA_PSK, 3:WPA2_PSK, 4:WPA_WPA2_PSK.
3.设置IP:
AT+CIFSR=“192.168.4.1” 设置IP地址。
4.设置波特率
AT+UART=9600,8,1,0,0
5.设置完成进行重启
AT+RST
6.启动服务
AT+CIPMUX=1 ,开启服务器(设置1为多连接,0为单路连接)
AT+CIPSERVER=1,8080 设置模块服务器端口
以上命令,如果将设置内容(等号和后面设置值)改为问号,则可以查询该项当前设置状态。(唯一例外是ip 查询,无需问号)
另外,如果修改了波特率,记得关闭端口,设置好相应波特率,再打开端口继续配置。
在上述配置命令中,第6步启动服务断电后需重新进行,其它的一次配置成功后就保存在8266中,无需重新设置。启动服务的两条命令,需要通过单片机程序向8266发送。
还有需要注意的是,命令后不能带空格,命令中的逗号是英文状态的逗号,全角的是不行,复制其它网上命令可能存在这个问题,提醒注意。
二、如何连接8266与单片机
这个问题也困扰我不少时间,特别是软件调试不成功时,以为是连接问题,网上查资料,有些说要接限流电阻,有些说不需要,搞得我一头雾水。实际,就是连4根Vcc,Gnd,Tx,Rx,Tx和Rx与单片机连接时注意要交叉,8266的Tx连单片机的Rx,Rx同理。
另特别需要注意的是,如果单片机的下载线连在电脑上,然后8266又接在单片机TxRx上,这是无法工作的。因为下载线也是通过串口(TxRx)与单片机连接的,单片机串口同时连接了电脑和8266,它怎么知道要和谁通讯呢?
解决的办法是先下载程序到单片机,下载完,使用时,不能再用下载线给单片机供电,要用独立的电源,或者是把下载线里的数据线给断开,只留电源线。
三、关于程序
底稿是来自csdn网友的,后经自己修改实测通过,我尽量把备注写完整,大家结合代码看就可以了。实现效果就是手机发送1,led3点亮,发送0,led3灭。
#include<reg51.h>
#define uint unsigned int
#define uchar unsigned char
sbit led1=P1^5;
sbit led2=P1^6;
sbit led3=P1^7;
sbit btn1=P3^5;//本人开发板s1按键,用于按下后才进行8266 8080端口服务启动,防止单片机一上电就向8266发送启动命令,万一8266未初始完成,可能会启动不成功。
uchar Recive_table[15];
uchar i=0;
void delay_ms(uint ms)
{
uchar i,j;
for(i=ms;i>0;i--)
for(j=120;j>0;j--);
}
void delay_us(uchar us)
{
while(us--);
}
void Usart_Init()//初始化51单片机
{
SCON = 0x50;//串行口中断方式1,且启动串行口接受(REN=1)
TMOD = 0x20;//计数器1工作方式2,8位自动重装载 0010 0000
TH1 = 0xFA; //9600
TL1 = TH1;
PCON = 0x80;//第1位smod设为1,波特率是设0时的两倍
TR1 = 1;//启动计数器
EA = 1;//开总中断
}
void SENT_At(uchar *At_Comd)//指针指向At指令
{
ES = 0;//关闭串口中断
while(*At_Comd!='\0')
{
SBUF = *At_Comd;
while(!TI);//等待该字节发送完毕,发送完后硬件自动置一TI
TI = 0;//硬件之以后必须软件置零才能进行下一次数据传送
delay_us(5);
At_Comd++;//指向下一个字节
}
}
void WIFI_Init()//通过单片机配置AT指令
{
SENT_At("AT+CIPMUX=1\r\n");//多连接模式
delay_ms(1000);
led1=0;//发送成功后亮1号灯,因无反馈结果,亮灯只是表明单片机发送了命令,8266是否成功接收不得而知。
SENT_At("AT+CIPSERVER=1,8080\r\n");//设置端口号
delay_ms(1000);
led2=0;//设置成功后亮2号灯(是否成功设置不确定)
ES = 1;
}
void main()
{
Usart_Init();
while(1){
if (btn1==0)
{
WIFI_Init();
delay_ms(500);
btn1=1;
}
}
}
void Uart() interrupt 4 //中断程序
{
if(RI==1)//接受一帧完成后由硬件置一
{
RI = 0;//软件清零,防止下次未接收完成就执行程序
Recive_table[i] = SBUF; //将接受数据存入数组
if(Recive_table[0]=='+') i++;
if(Recive_table[9]=='1') led3 = 0;
if(Recive_table[9]=='0') led3 = 1;
if (i>=10) i=0;
}
}
四、关于波特率。
在波特率问题上走了一大圈弯路,差点让我从入门直接到放弃。一开始对单片机串口通讯初始化参数不明白,抄了别人代码,人家是设置波特率4800的,我不会调,就想着直接调8266的波特率吧,还方便些,就把8266波特率调到了4800,我以为单片机和8266只要波特率一致就可以通讯了,实则不然。我排除了各种可能存在的问题,把AT命令和波特率计算彻底搞明白,确认无误后,发现手机和8266还是连不上,在几乎要放弃挣扎时,发现8266后面印了一排小字:use 9600 baud rate.我试着把8266和单片机的波特率都设为9600,当看到手机屏上显示的连接成功时,一阵狂喜。
技术问题没弄通时,到处是陷阱,弄通了,其实也很简单。下面详细总结下关于波特率的知识点:
首先波特率是啥意思,简单说就是1秒钟传多少个位(不是字节,1个字节有8位)。
单片机串行通讯有4种模式(0,1,2,3),2和3模式是9位数字模式,不常用,暂不去说它。这4种模式是通过寄存器scon中的sm0和sm1组合来设置的。
模式0用的是时系统时钟来控制传输速度(波特率),波特率为1/12的晶体频率(晶体频率有11.0592M和12M两种,粗略计算估且都当成12M)。这个有多快呢?晶体振动12下,传输1位。
模式1是用定时器来控制传输速度,为什么不用系统时钟的1/n(n留给我们自行设置),而用定时器增加使用麻烦呢,我也没想明白,可能是这个1/n实现起来不容易吧。
模式1波特率计算公式:定时器溢出率/32或16 (当pcon的第一位smod设1时,除以16,当smod设0时除以32)。
定时器的溢出率,也就是1秒钟溢出多少次,怎么计算呢?这和定时器的初值有关。用家里的钟来举例,秒针走到12点,分针加1,可视为溢出一次,那每次溢出需多少秒呢,这和秒针初始位置有关,如果秒针初始在6点,那么溢出需要30秒,溢出率为1/30,如果在9点,只需15秒,溢出率为1/15。所以溢出率大小是和初值设置是有关的。串口通讯定时器使用8位寄存器,初值在TH1中设置,可设置0-255的任意一位。如果设置246,则定时器需要走256-246=10下溢出,如果设置初值0,则需要走256下才能溢出。每走一下的时间是固定的,就是1微秒。这个理解了,波特率就很容易计算了。
模式1的最大波特率,也就是最快传输速度怎么计算呢?初值越大,溢出越快,我们设初值为255,那么定时器只需走一下,1微秒就会溢出,这是最快的,再取smod=0,则最大波特率为:(1秒/1微秒)/16=62500。
模式1的最小波特率(设初值为0,再取smod=1):
(1秒/256微秒)/32=124。
明白了原理,计算TH1初值设置就很简单了。要求设波特率为9600,当smod=0时:1000000/(32*9600)≈3也就是定时器需要走3下,所以设置初值253(FD)。
当smod=1时:1000000/(16*9600)≈6,应该设置初值250(FA)。
如果还是搞不明白,有个简便的方法是烧写程序的stc-isp里有计算波特率的工具,设置好相应选项就可以生成代码。
五、最后吐槽一下安信可的手机端网络调试工具,简直是垃圾得不能再垃圾,推荐一下一个叫网络调试精灵的app,很好用。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。