基于ESP8266和STC89C52的寝室电费实时显示
寝室电费实时显示
一、前言
在炎炎夏日,由于担心寝室电费突然没了,查电费又比较麻烦,前面做了一个电费实时显示的一个网站,有天看到了桌上的单片机和WiFi模块,我便想着WiFi模块能不能够联网,发送请求,返回数据,通过查阅ESP8266的手册,发现这些都是可以实现的,后面便是如何让ESP8266与STC89C52通信并显示数据了。
二、ESP8266模块
以下仅列举用到的命令,所有命令可查阅官方文档。
简介
一种WiFi模块。属于网络层以上的设备,拥有MAC地址和IP地址,支持UDP和TCP。
参数
引脚
| PIN | Function | Description |
|---|---|---|
| 1 | URXD | 1)UART_RXD,接收; 2)General Purpose Input/Output:GPIO3; |
| 2 | UTXD | 1)UART_TXD,发送; 2)General Purpose Input/Output:GPIO1; 3)开机时禁止下拉; |
| 3 | RESET(GPIO 16) | 外部Reset信号,低电平复位,高电平工作(默认高); |
| 4 | GND | GND |
| 5 | VCC | 3.3V,模块供电; |
| 6 | GPIO0 | 1)默认WiFi Status:WiFi工作状态指示灯控制信号; 2)工作模式选择: 悬空:Flash Boot,工作模式; 下拉:UART Download,下载模式; |
| 7 | CH_PD | 1)高电平工作; 2)低电平模块供电关掉; |
| 8 | GPIO2 | 1)开机上电时必须为高电平,禁止硬件下拉; 2)内部默认已拉高 |
最简化启动模块,将VCC、GND接3.3v电源;CH_PD上拉,可通过一个电阻接到VCC。
波特率
ESP8266模块的默认波特率是115200,若想改变波特率请使用以下语句进行修改:1
2
3AT+CIOBAUD=<baudrate>,<databits>,<stopbits>,<parity>,<flow control>
或者
AT+UART=<baudrate>,<databits>,<stopbits>,<parity>,<flow control>连接stc89c52单片机建议把波特率设置为9600
1
2
3AT+CIOBAUD=9600,8,1,0,0
或者
AT+UART=115200,8,1,0,0用到的AT指令
1
2
3测试连接
AT\r\n
响应:OK\r\n1
2
3设置 wifi 模式:
AT+CWMODE=1\r\n
响应:OK\r\n数字 WiFi应用模式 1 STA(Station)模式 2 AP模式 3 AP+Station模式
1 | 连接路由: |
1 | 连接到服务器: |
1 | 开启透传模式: |
1 | 通知模块开始数据传输: |
这一步操作后,模块会回复一个“>”,代表接下来的所有串口数码均为数据,不解析成指令。
1 | 发送数据: |
二、ESP8266调试
1、利用单片机USB串口连接电脑调试
接线

调试
连接WIFI
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30AT
OK
AT+CWMODE=1
OK
AT+CWJAP="5226","52265226"
WIFI DISCONNECT
WIFI CONNECTED
WIFI GOT IP
OK
AT+CIPSTART="TCP","192.168.31.156",8088
CONNECT
OK
AT+CIPMODE=1
OK
AT+CIPSEND
OK
>{"id":"123","dormitory":"5-226","lighting":"121.04","airconditioner":"164.98","time":""}
2、利用ESP8266连接单片机
需要把之前上面连接中的P31与P30口的线换一下,如图
- 接线
三、将ESP8266上单片机
按照利用ESP8266连接单片机的接线图即可。扯一扯,当时脑子有点抽,一直忘记把串口的收发口线调换顺序,然后写程序用单片机向ESP8266发送指令根本没有用,我一度以为是我写的程序有问题,百度了各种文章尝试用其他方式配置端口,都没有效果,然后用串口调试助手调试是没有问题的,我一度怀疑人生了,就这样卡在这一步卡了两天,后面因为马上就要期末考,就把这个搁了几天,再度重新弄这个的时候,两个串口线我就瞎连的,尽然能够通过单片机发送指令,我当时欣喜若狂,后来突然觉悟了,是真的愚蠢,避坑避坑!!!。
接线没问题后就是写代码将上面的一些连接服务器指令通过单片机发送,获得数据后再数码管或者LCD1602上显示,这里我选择LCD1602。
- 反馈识别:
如何识别ESP8266返回的数据判断发送的指令是否成功,需不需要重新发送。
由于考虑到单片机硬件资源紧张(存储空间小、晶振慢),所以我们要缩减对返回数据的识别。
因此我这里采用的是关键字匹配。比如识别WIFI GOT IP,我只识别第一个字符w、第6个字符G和第10个字符I。就可以确认这个是WIFI GOT IP。
如果是出现干扰,可能性也是比较低的,我们的交互是在网络层的,下层也可以把出错的报文挡掉。 - 如何进行调试:
单片机开发,代码在哪步出错比较难发现,没有报错,也没有try catch语句,也没有C语言中黑乎乎的命令行。
利用8个流水灯,如果执行了某一个语句,指定一个流水灯亮。我开始使用的是LCD1602上面显示数字,LCD老是自己不稳定,显示错乱啥的,很烦。文章后面我会把这些问题归纳一下。
四、代码
定义了函数指针,可以实现模块化事件化,关于函数指针如何使用,可阅读函数名,代表的是函数的入口地址
- ASCII
因为用于通讯,ASCII内所有的特殊字符我都写到了这一个头文件里。虽然下面只用到其中的几个,但以后可以重复利用这个头文件。
ASCII.h
1 |
- 延时函数
Delay.h
1 |
|
Delay.c
1 | void Delay(unsigned int xms) |
- 定时器0
Timer0.h
1 |
|
Timer0.c
1 |
|
- LCD1602
LCD1602.h
1 |
|
LCD1602.c
1 |
|
- 串口通信
stc52ser.h
1 |
|
stc52ser.c
1 |
|
- ESP8266无线模块
esp8266.h
1 |
|
esp8266.c
1 |
|
- 主函数
main.c
1 |
|
五、效果
六、问题汇总
- LCD1602经常性出现字符乱码错乱,可能是由于插上ESP8266后电压不够导致的,其自身也不稳定。
- 单片机hex下载不进行,由于ESP8266占用了串口,关掉ESP8622或者拔掉接收口的线。