文章框架
前言
扯单一周目BOSS出现!请速速讨伐!
ESP8266是我第一个,也是唯一一个接触过的无线网络模块,我非常喜欢!大部分网上的教程都是ARM架构单片机配用ESP8266。我比较抠门,给大家上51版的。
我记得当时和老板承诺可以做成无线通信的时候我也不是很确定,心里一直打鼓。好在最后做出来了,很有成就感!所以今天的代码案例是我把我之前在公司写的项目代码简化之后分享给大家的。虽然结构有点恶心,但应该还是入得了眼的。
如果有没看懂的地方,大家评论区告诉我。
需求
利用ESP8266芯片,通过无线网络同电脑建立TCP连接。接收电脑传来的消息并显示在LCD上。
每条信息以
\
结尾。
每条信息字符数不超过32。
信息内容只能是ASCII表内的字符。
清单
硬件
学习板
简介
由于这次要用到WIFI模块,没法用Proteus模拟,所以就上真家伙。
自己焊板子就太麻烦了,所以就买学习板(其实我不会焊)。
这是我入的学习板,你也可以入其他的,如果把握不大就跟我入一样的。
这个是我在淘宝上小挑了一阵子选的板子:QX-MINI51。尺寸不大不小,想玩的基本都有。配备的单片机是STC89C52。电路
下面是QX-MINI51在本节会用到的电路图
使用89C52芯片,和我们之前用的单片机一样。
CH340芯片是用于普通串口和USB转换的,其上的RXD
为串口输入,TXD
为串口输出。UD+
和UD-
对应USB数据线。
虽说是用了USB,其实和普通串口通信线用法一致,只是人家成品方便我们使用封装成了USB。这里不深究。
流水灯在本节中的角色是辅助调试(具体的看后面),这里有用的信息就是让你知道这8个流水灯接哪了。
ESP8266
- 简介
主角,简而言之就是Wi-Fi模块,属于网络层以上的设备。拥有MAC地址和IP地址,支持UDP和TCP。
这款的型号是ESP8266-01,其他的和QX-MINI51配合使用不太方便。
淘宝链接 - 参数
型号 | 主芯片 | 无线标准 | 工作电压 | 安全机制 | 支持模式 |
---|---|---|---|---|---|
ESP8266-01 | ESP8266 | IEEE 802.11b/g/n | 3.3V | WEP/WPA-PSK/WPA2-PSK | STA、AP、STA+AP |
STA 模式:ESP8266模块通过路由器连接互联网,手机或电脑通过互联网实现对设备的远程控制。
AP 模式:ESP8266模块作为热点,实现手机或电脑直接与模块通信,实现局域网无线控制。
STA+AP 模式:两种模式的共存模式,即可以通过互联网控制可实现无缝切换,方便操作。
上图对8个针脚进行说明。
UTXD | GND | CH_PD | GPIO2 | GPIO16 | GPIO0 | VCC | URXD | ||
---|---|---|---|---|---|---|---|---|---|
发送 | 接地 | 高电平工作 | \ | \ | \ | 电源 | 接收 |
本例只用到这五个引脚(画“\”的不用),其他引脚的说明资料请自行到淘宝链接处下载。
AT指令
操作ESP8266芯片是靠AT指令的,类似之前的操作LCD1602(《51单片机实战:液晶显示器のLCD1602》)。操作LCD1602的指令都是一个字节的十六进制码,比较难记和理解。AT指令是字符串形式的指令,一般都是单词缩写,对可笑的人类比较友好。
之前和LCD1602交互是靠并口传输,而这次是用串口传输(串口传输简例:《51单片机实战:与计算机异步串行通信》),所以这次的Wi-Fi通信是建立在串口通信基础上的。波特率
注意,这个模块的默认波特率是115200
,本例也是根据这个波特率进行演示的。若想改变波特率请使用以下语句进行修改:
1 | AT+CIOBAUD=<baudrate>,<databits>,<stopbits>,<parity>,<flow control> |
如:
1 | AT+CIOBAUD=9600,8,1,0,0 |
软件
程序 | 说明 | 下载 |
---|---|---|
UartAssist | 串口调试助手,用来给单片机发送消息 | 度娘网盘 |
NetAssist | 网络调试助手,在电脑端建立TCP连接与单片机的ESP8266进行通信 | 度娘网盘 |
STC-ISP | STC单片机工具集,很强大,可烧录程序,可串口调试等等 | 度娘网盘 |
CH340驱动 | CH340的USB驱动,如果没有这个驱动,你的电脑可能识别不到单片机(识别到CH340就相当于识别到单片机的串口。) | 度娘网盘 |
51单片机波特率初值计算工具 | 用于计算在各种波特率和晶振频率等参数下计时器的初值,属于辅助工具,省的还得算。 | 度娘网盘 |
分析
调试
在开始用单片机直接和无线模块通信之前,首先要绕过单片机直接和无线模块通信以确定其可以使用和接入默认网络(接入一个热点后,模块每次断电后启动都会自动连接该热点),这样可以让单片机少做很多事情(要知道我们用的是51单片机,硬件资源极其有限,能省则省)。
TXD/RXD反接
首先要绕过单片机直接给ESP8266下指令,就要用电脑的串口。但ESP-01是针脚接口,所以我们可以利用QX-MINI51上的针脚和USB接口。回看前面QX-MINI51的主控芯片和USB的电路图,可以发现,单片机的串口引脚是被并联式的暴露再外的,分别为:
P30 - P31
和USB
,前者为针脚接口,后者为USB接口。且它们的RXD和TXD的数据信息是一摸一样的,注意并不是两个独立的串口,是同一个串口。比方说,单片机要往出发送一个1,P30针脚和USB都会是往出发送一个1。所以我们利用这个特点,将ESP8266的TXD接到P31(单片机的TXD),RXD接到P30(单片机的RXD),这样就等于让ESP8266直接和USB打交道,也就是和电脑直接打交道了。
为什么叫反接,我一般管RXD对TXD叫正接。嗯…
强势秀一波画工!
我觉得应该可以看得懂吧,ESP8266的引脚说明请看前面的引脚图。看红色号码对应接线,其中4、5、6号引脚不用。
这个图就很难看出线是怎么连的了,所以你要忍受我丑陋的画工。
- 接入网络
打开串口调试助手,调好参数
其中串口号你连的哪个串口就设置哪个串口号,我是连的COM3。
另一个要注意的就是波特率要115200(ESP-01的默认波特率,也可以统一改为9600)。
打开串口后,给开发板上电。你的串口调试助手会有信息出来(文本显示,不要十六进制显示)。
1 | ?諄MEM CHECK FAIL!!! |
显示的信息类似上面,你可以先给个测试命令AT
看看是否可以接受指令
注意!每个指令后要跟回车再发送!
如果返回OK
则说明指令可以被接收并识别。
如果下面的指令都会返回ERROR
(在没有给错指令的情况下),可以尝试AT+RST
重启模块。
1. 更改模式
指令:AT+CWMODE?
一般情况下,第一次使用会返回2
,也就是AP模式,我们不用它发热点,所以要改回Station模式(模式1)。
指令:AT+CWMODE?
一般情况下,第一次使用会返回2
,也就是AP模式,我们不用它发热点,所以要改回Station模式(模式1)。
指令:AT+CWMODE=1
返回:OK
则成功
2. 接入热点(连Wi-Fi)
指令:AT+CWJAP=<SSID>,<Password>
参数:
例如:AT+CWJAP="CMCC","123456"
指令:AT+CWJAP=<SSID>,<Password>
参数:
例如:AT+CWJAP="CMCC","123456"
返回:WIFI CONNECTED
:连接到热点
返回:WIFI GOT IP
:分配到IP,走到这一步,就算已经连入到热点了。
如果忘记SSID了,想看一下可以使用下面的指令,列出广播的SSID(隐藏的不会显示)。
指令:AT+CWLAP
3. 连接TCP服务器
首先打开NetAssist,设置TCP Server,然后建立连接(注意防火墙)。注意,Server必须在Client所在内网或其外网(我的是在同一个内网)。
首先打开NetAssist,设置TCP Server,然后建立连接(注意防火墙)。注意,Server必须在Client所在内网或其外网(我的是在同一个内网)。
指令:AT+CIPSTART=<Type>,<DomainName>,<Port>
参数:
本例:AT+CIPSTART="TCP","192.168.1.110",1234
返回:
1 | CONNECT |
说明连接成功。
在NetAssist中,数据接收框的下面有一个连接对象,点开后发现除了All Connections
之外,多了一个客户,就确定客户连接到服务器了。
在下方文本框输入信息后发送,可在串口调试助手中看到ESP8266所接收到的信息
UartAssist收到的信息:+IPD,10:Hello 简书
到这里就说明网络连接及建立TCP都可以顺利完成,在下面的单片机操作中就会变得方便很多。
注意,ESP8266每次断电后重新上电,最多只会自动连到之前连接的热点,但不会自动连接到TCP服务器,所以,建立连接要交给单片机来做。
问题
波特率
本例要使用的波特率为115200的,不是9600。引申出来的问题就是:算初值(方法详见:《51单片机实战:与计算机异步串行通信》 - 知识点 - 波特率 - 溢出率)。
手算真的很麻烦,因为在参数固定的情况下,算起来已经很烦了,更何况那些参数可能还会变得情况。
所以上神器:反馈及识别
我们要做的是让单片机在收到ESP8266回馈的WIFI GOT IP
后发出连接TCP服务器的指令。
发送指令不用多说,只要记得在后面跟”换行(CR)”和”新行(NL)”字符就行(这两个是不一样的)。
1. 关键字符配对
如果是电脑程序的高级语言编程,这个问题就不存在了。但是我们给单片机写程序就要牢记它的一些点(《扯会儿单片机开发:开始》),比如硬件资源十分紧张。
一个是因为它存储空间很小,另一个是因为晶振太慢,所以我们要想办法缩减配对时间。因为单片机的使用往往很单一,所以策略都是根据情况来设定的。比如本例,单片机接收的回馈无非那么几种,所以我制定的策略就是关键字符配对。比如识别
WIFI GOT IP
,我只是别第一个字符W
和第6个字符G
,就说明我收到的就是这个回馈信息。如果收到第一个是W
,只有这条指令的第六个字符是G
,所以就可以确定。如果是出现干扰,可能性也是比较低的,我们的交互是在网络层的,下层也可以把出错的报文挡掉。总体来说还是蛮可靠的,如果你有更棒的方法,请在评论区告诉我,大家一起学习进步。
2. 利用流水灯
上面就是理论工作,已经做得7788了。但实际经验告诉我,如果的代码哪里也出岔子了在51单片机开发中真的比较难发现,他不像高级程序语言可以报错,可以try - catch
。但这个就别想了,所以我们要自己想办法,让他可以反馈我们的程序至少是正常运行的,这样可以节省很多时间。我在这里介绍的我的方法是利用LED,或成组的流水灯(更好)。承租的流水灯一般是8个,可以直接显示一个字节的信息,可能有人问为什么不用LCD?你若会LCD或者看过《51单片机实战:液晶显示器のLCD1602》就会发现,LCD本身的开发就有点复杂了。你很难保证这个子程序运行正常,更别提用它抓错了。只能是不推荐哈,我觉得不可靠。LED的话就很简单了,就是个关开,一般不会出错。
QX-MINI51开发板上自带流水灯,你要是入的其他开发板,一般都是有的。如果没有,就单买LED回来(如果不知道去哪买,链接)。
我一般会怎么做呢,先让流水灯直接显示串口接收的数据,为了知道我们至少是能接收到东西的。然后利用上面的关键字符识别,收到
WIFI CONNECTED
亮一号灯,收到WIFI GOT IP
亮二号灯,收到CONNECT OK
亮三号灯。这样,根据灯亮灭的情况就能确定哪一步出了问题,然后定位到代码或者设置。还是那句话,如果你有更棒的方法,欢迎在评论区交流。
到这里就做完了所有理论上的准备工作,也就是理论上我们已经可以实现这个程序了,下面代码实现。
代码
说下这次代码比较新颖的地方,一个是用到了.c
和.h
文件组合的模块形式,另一个是用到了函数指针(函数名也被括起来的那个)。前者这种写法是为了将各子功能模块化,.h
文件里的内容相当于面向对象编程里的public
,.c
文件一个是实现.h
内的函数,另一个就是隐藏函数和变量,相当于private
。后者是用来充当高级语言中的“事件”,让函数调用变得更加灵活,其具体用法请自己查资料或者看相关C语言书籍。
总而言之,这次的代码是模块化和事件化的,类似面向对象的编码风格。
准备
因为用于通讯,所以我把ASCII内所有的特殊字符都写到一个头文件里。虽然本例只用到其中的几个,但以后重复利用这个头文件。ASCII.h
1 |
- LCD
这里都是关于LCD1602显示器的主要代码,与文章《51单片机实战:液晶显示器のLCD1602》所讲的一样,这里就不给出注释了。
lcd1602.h
1 |
|
lcd1602.c
1 |
|
- 串口通信
这里用于单片机和ESP8266交互,与文章《51单片机实战:与计算机异步串行通信》相似。其中的不同点前面已经说过。
stc52ser.h
1 |
|
stc52ser.c
1 |
|
简单说一下,这里留了两个初始化函数,SerialPort_Init_Low()
用于11.0592MHz下的9600波特率,SerialPort_Init_High()
用于22.1184MHz下的115200波特率(此例用这个)。这样写只是为了以后可以重用(软工狗的矫情)。
- 无线
这里是最主要的代码,都是关于ESP8266的,也是作为一个模块给主函数调用。
esp8266.h
1 |
|
esp8266.c
1 |
|
- 主函数
main.c
1 |
|
- 编译
编译前要设置一下目标参数,如下图。
注意这里要改成XDATA,不然编译通不过的。
效果
开始前请确定在同一个网络下,并且服务端已开启。
我只是把单片机连到移动电源上了。
为了能让1602第一行显示Hello
,第二行显示World
,中间可以留了11个空格。
结语
猴!到这里这个程序就算完成了。这个比那些用手机控制开关灯要复杂一些。所以你只要掌握了这个例子,那些都不在话下了。
扯单一周目BOSS正式刷完,这个系列的文章将会暂告一段落,因为接下来笔者又要去考试了,还有什么噼里啪啦科三学车,烦。消失一小阵子后我会再次诈尸的!
恭喜你获得一周目BOSS神装:物联网神技!