系统功能
通过温湿度传感器DHT11采集温、湿度,能够通过显示单元显示出温、湿度,并控制继电器。
1. 开机液晶屏上显示姓名、学号3秒。
2.
显示当前温、湿度和设定的温度、湿度上下限。
温度测量范围:0℃~50℃
温度测量误差:±2℃
湿度测量范围:20%~95%
湿度测量误差: ±5%
测量精度:±1℃,±1%
测量数值均为整数
3.
当温度或者湿度超过上下限时启动继电器带动风扇。
4.
可以通过矩阵键盘调节温度、湿度上下限。
可调控温度范围:1℃~99℃
可调控湿度范围:1%~99%
5.
温度、湿度上下限设置后断电不丢失。
6.
通过ESP8266模块连接WIFI上传数据至onenet物联网平台,并进行可视化展示。
7.
单片机与上位机进行通信,通过单片机上位机实时显示获取到的温湿度数据。
8. 通过微信小程序在后台对温度、湿度信息进行监测。
原理框图及说明
测量原理
根据设计任务,设计如下框图:
- 主控单元,主要负责从DHT11传感器中获取温度、湿度信息,获取矩阵键盘的设置温湿度信息,并将设置的温湿度信息和温湿度上下限显示在液晶显示模块上,并通过RX、TX串口发送数据到上位机以及ESP8266WIFI模块中去,便于向云平台传输数据。当温度或者湿度超过设定的温湿度阈值时,主控单元通过控制设置的继电器引脚电平带动直流电机工作。
- 电源部分,为单片机提供5V稳压电源和3.3V稳压电源。
- 矩阵键盘部分,其中K1~K9键盘用来设置温度湿度阈值,K13和K14按键可以用来设置单片机的显示界面和发送数据界面。
- 独立按键部分,其中K1~K4分别代表温度上限、温度下限、湿度上限、湿度下限四个部分的设置。
- 液晶显示模块,用来显示初始界面(基本信息显示3s)、设置温度界面、显示温度界面、温度上下限、发送数据界面。
- EEPROM电路,用来存储设置的温度湿度上下限信息,当突然断电时,保存信息,当下次通电时,读取上次设置的温湿度信息并且展示液晶显示模块上。
- WIFI模块,用来接收DHT11温度传感器获取到的温湿度数据并通过AT指令发送给网址和指定的设备。
- 晶振电路以及时钟电路:晶振电路主要是用来提供一个固定频率的脉冲方便时钟电路计时;时钟电路主要是用来为第一个功能的3s钟进行计时,以及为后面的显示模块刷新率进行设置。
使用说明
- 首先打开单片机电源,烧录编写好的程序
- 单片机显示模块会显示开机页面即姓名、学号信息3s。
- 3s之后会进入温度和湿度设置界面,通过独立键盘模块
K1~K4次选择温度下限、温度上限、湿度下限、湿度上限并通过矩阵键盘K1~K9进行按键设置。如果出现设置错误的情况只需要再通过独立键盘选择错误的设置参数并通过矩阵键盘重新设置即可。 - 当温湿度阈值设置完成后,按下矩阵键盘K13即可进入温湿度显示模块,该模块会显示当前的温湿度信息和设置的温湿度上下限。
- 按下矩阵键盘的K14即可把温湿度信息发送到OneNet云平台进行数据存储和可视化展示并实时同步到微信小程序平台进行后台监测。
- 连接上usb上位机即可实时显示获取的温湿度数据。
- 当温度和湿度超过设定的上下限时,启动继电器带动直流电机工作。
- 当整个系统断电后,再次打开单片机系统会自动保存之前设置的温度和湿度上下限。
| # 主要电路说明、元件选择及参数计算 |
| | 内部模块 | 数量 | | :--------------: | :----: | | 核心芯片STC89C52 | 1 | | 电容 | 若干个 | | 杜邦线 | 若干个 | | USB转串口 | 1 | | 3.3V 5V供电模块 | 6 | | 按键 | 4 | | 72M 晶振 | 1 | | 矩阵键盘模块 | 1 | | 24CO2 芯片 | 1 | |
| | 外部资料 | 数量 | | :--------------: | :--: | | DHT11 温湿度传感器 | 1 | | ESP8266WIFI模块 | 1 | | 直流电机 | 1 | | 1路 5V继电器 | 1 | |
| ## 复位与振荡电路
复位电路如下图所示,由C14和R9构成。由于51单片机为低电平复位,图示电路利用电容的特性,在刚刚外加5V电源时RST脚的电压为低。时间常数=RC=1000mS,满足芯片复位要求。由于电压为5V,可选择耐压6.3V的电解电容即可。 |
![]() |
| 振荡电路按照说明书的推荐,选择12MHz晶体,C7、C8选择33pF瓷片电容。 |
![]() |
| ## 显示电路 |
| 经过大量的测试和调研,最终我的显示元件选择20引脚的12864液晶显示屏(128X64显示分辨率为128×64,内置8192个1616点汉字,和128个168点ASCII字符集。利用该模块灵活的接口方式和简单、方便的操作指令。可以显示8×4行16×16点阵的汉字。也可完成图形显示),这里把各个引脚的功能以及连接方式做成了一个表格,以便直观地显示,通过51单片机上自带的可调电阻来调节12864的背光。 |
| | GND | +5V | V_com | RS | R/W | EN | D0 | D1 | D2 | D3 | | :----------: | :------------: | :---------------: | :---------------------: | :----------------: | :------------: | :---: | :---: | :---: | :---: | | 模块的电源地 | 模块的电源正端 | LCD驱动电压输入端 | 并行的指令/数据选择信号 | 并行的读写选择信号 | 并行的使能信号 | 数据0 | 数据1 | 数据0 | 数据0 | | GND | VCC | 电位器 | P2^6 | P2^5 | P2^7 | P0^0 | P0^1 | P0^2 | P0^3 | |
| | D4 | D5 | D6 | D7 | PSB | NC | RST | V_OUT | BLA+ | BLA- | | :---: | :---: | :---: | :---: | :-------------: | :--: | :-------------: | :---: | :--------: | :----------: | | 数据4 | 数据5 | 数据6 | 数据7 | 并/串行接口选择 | 空脚 | 复位 低电平有效 | 空脚 | 背光源正极 | 背光源和负极 | | P0^4 | P0^5 | P0^6 | P0^7 | P3^2 | | VCC | | VCC | GND | |
![]() |
| ## 按键电路 |
| 由于89C52的P3口内部有上拉电阻,为简化电路,即当K1没有按下时,P3.1=1,当K1按下时,P3.1=0。 |
| 矩阵键盘本质是使用8个io口来进行16个按键的控制读取,可以减小io口的使用,用4条I/O线作为行线,4条I/O线作为列线组成的键盘。在行线和列线的每个交叉点上,设置一个按键。而这样的按键中按键的个数是4 X 4个。第一行接到p17,第二行接到p16,第三行接到p15,第4行接到p14,第一列接到p13,第二列接到p12,第三列接到p11,第四列接到p10。先从P1口的高四位(四个行)输出高电平,低四位(四个列)输出低电平,假设有按键按下,从P1口的高四位读取键盘状态。判断高四位的四行哪一行变成了低电平,就知道是第几行,再从P1口的低四位(四个列)输出高电平,高四位(四个行)输出低电平,从P1口的低四位读取键盘状态。判断低四位的四列哪一行变成了低电平,就知道是第几列,将两次读取结果组合起来就可以得到当前按键的特征编码。 |
| | K1 | K2 | K3 | K4 | | ---- | ---- | ---- | ---- | | P3.1 | P3.0 | P3.2 | P3.3 | |
![]() |
![]() |
| ## 温度湿度检测电路 |
![]() |
| 经过大量的测试和我们所有的知识储备,最终我选择DHT11模块对温度,湿度进行检测并显示在12864显示器上。DHT的引脚图如下所示。
|
| DHT11共有三个引脚,其中VCC,GND分别接入单片机电源模块上的VCC,GND。程序初始化后,单片机首先向DATA管脚发送一个低电平脉冲. |
| 触发DHT11采集数据 |
| 总线空闲状态为高电平,单片机把总线拉低等待DHT11响应,单片机把总线拉低必须大于18ms,保证DHT11能检测到起始信号。 |
| 当DHT11接收到单片机的开始信号后,等待单片机开始信号结束,然后发送80us低电平响应信号。 |
| 单片机发送开始信号结束后,延时等待20-40us后,切换为输入状态,等待DHT11的80us低电平信号结束,然后判断DHT11是否是否发出 80us 的高电平;如果是,即可开始采集数据。 |
![]() |
| 数字0和1的信号时序 |
| 当DHT11输出数字0时, 单片机读取到的信号为50 us的低电平,之后为26-28 us的高电平。当DHT11输出数字1时, 单片机读取到的信号为50 us的低电平,之后为70 us的高电平。 |
![]() |
![]() |
| 总时序图 |
| 用户MCU发送一次开始信号后,DHT11从低功耗模式转换到高速模式,等待主机开始信号结束后,DHT11发送响应信号,送出40bit的数据,并触发一次信号采集,用户可选择读取部分数据。 |
| 从模式下,DHT11接收到开始信号触发一次温湿度采集,如果没有接收到主机发送开始信号,DHT11不会主动进行温湿度采集。当一次完整的采集数据后,DHT11会转换到低速模式。 |
![]() |
| ## ESP8266WIFI模块 |
| ESP8266是一款高性能的WIFI串口模块,内部集成MCU能实现单片机之间串口通信,是目前使用最广泛的一种WIFI模块之一。接线时只需要将RXD、TXD、GND、VCC这4个引脚,分别和USB转TTL模块的TXD、RXD、GND、VCC相连接。 |
![]() |
| 然后再通过USB转TTL模块和AT指令集通过以下步骤在串口助手中或者直接在单片机程序中对ESP8266模块进行配置。 |
| 1. AT——测试ESP8266是否工作完好 2. AT+CWMODE=1——设置ESP8266的工作模式为Station模式 3. AT+CWJAP=”WIFI名称,”WIFI密码”——进行WIFI连接(注意这里的手机热点或者外部热点只能是英文名称) 4. AT+CIPSTART=”TCP”,” 你电脑自己的IP地址”,”设置的端口”——建立TCP连接,设置IP地址和PORT端口。 5. AT+CIPMODE=1——开启ESP8266的透传模式。 6. AT+CIPSEND——准备发送数据 7. POST /devices/1051580320/datapoints?type=3 HTTP/1.1 ——onenet的设备 |
| api-key:1ZXQyfKnqL1bqEV0D0JJqbL7pmc= ——onenet的master key |
| Host:api.heclouds.com ——onenet的主机ip地址 |
| Content-Length:21 ——传输的数据长度 |
| {"temp":temp,"humi":humi} ——传输的数据 |
![]() |
| ## EEPROM电路 |
| EEPROM电路的主要部分为AT24C02,原理图如下所示。 |
![]() |
| AT24C02 器件地址为 7 位,高 4 位固定为 1010,低 3 位由 A0/A1/A2 信号线的电平决定。 因为传输地址或数据是以字节为单位传送的,当传送地址时,器件地址占 7 位,还有最后一位(最低位 R/W)用来选择读写方向。 A0/A1/A2 默认连接到 GND,所以器件地址为1010000,即 0x50(未计算最低位)。如果要对芯片进行写操作时,R/W 即为 0,写器件地址即为 0XA0;如果要对芯片进行读操作时,R/W 即为 1,此时读器件地址为 0XA1。开发板上我们也将 WP 引脚直接接在 GND 上,此时芯片允许数据正常读写。 |
![]() |
总电路设计
软件设计思路及框图
软件设计思路及主流程图
根据题目的设计要求以及我自己附加的功能,我采用定时器0和定时器1作为时钟数据源,定时器0每用来完成功能1姓名学号显示3s,定时器1用来对ESP8266和II2C进行初始化并实现发送数据、存储数据以及初始化数据线的功能。设置温湿度、显示温湿度信息和上下限、继电器以及直流电机的工作、矩阵键盘扫描、比较当前数据和设定阈值的差别、发送温湿度数据等全部放在主程序中实现。
温湿度获取部分设置数据缓冲区,DHT11传感器获取的温湿度信息直接送入缓冲区,由程序完成动态扫描。
设计的全局变量
- 温湿度数据缓冲区:
uchar wendu[4]、uchar shidu[4] - 设置的温湿度上下限:
uchar temtop[4]、uchar temlow[4]、uchar humtop[4]、uchar humlow[4] - 温湿度传感器接收数据:
uchar rec_dat[9] - 矩阵键盘的扫描值
char key、uint flag - 独立键盘的扫描值:
uchar func - ESP8266接收状态标记:
uint UART_RX_STA - ESP8266接收缓冲:
uchar UART_RX_BUF[UART_REC_LEN]
设计的端口
- LCD端口
1 | sbit LCD_RS = P2^6; //寄存器选择输入 |
- DHT11端口
1 | sbit Data=P3^6; |
- 继电器端口
1 | sbit wind=P2^1; |
- 蜂鸣器端口
1 | sbit beep=P2^5; |
定义的端口
1 |
函数设计
- 主函数main()
入口:无,出口:无。 一个大的循环,程序用不结束。
- ESP8266发送数据 void send_data()
功能:对ESP8266进行云平台连接并通过ESP8266发送获取的DHT11温湿度传感器获取的数据。
入口:无,出口:无0
- 初始化定时器0 void time1_init(void)
功能:初始化定时器的工作模式,并对定时器0赋初值。
入口:无,出口:无。 改动当前显示位号。
- 定时器的中断函数 void time0() interrupt 1
功能:通过设置count计数变量,每1mS中断一次,记录中断次数到3000次则初始化页面跳转至设置温度界面,并调整为合法的时间格式。
入口:无,出口:无。
延时模块
函数设计
- void delay_ms(uint ms)
功能:设置延迟ms的函数
入口:延迟的时间,出口:无
- void delay(int ms)
功能:设置延迟ms的函数
入口:延迟的ms时间 出口:无
- void delay_us(uchar n)
功能:设置延迟的us的函数
入口:延迟us的函数 出口:无
LCD12864显示模块
- 设计的端口值
1 | bit LCD_RS = P2^6; //寄存器选择输入 |
- 定义的端口值
1 |
- 设计的函数如下
- bit lcd_busy()
功能:检查LCD忙状态
入口:无,出口:,lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。
- void lcd_wcmd(uchar cmd)
功能:写指令数据到LCD
入口:LCD指令集 出口:无
- void lcd_wdat(uchar dat)
功能:写显示数据到LCD
入口:写入的数据 出口:无
- lcd_init()
功能:LCD初始化设定
入口:无 出口:无 调用函数:lcd_wcmd,lcd_busy()
- void lcd_showstring(uchar x,uchar y,uchar *str)
功能:LCD根据设定的位置显示字符串
入口:设置的x轴和y轴,显示的字符串 出口:无 调用的函数:lcd_wdat(uchar dat)
按键扫描模块
定义的端口值
1 |
函数设计
uchar Keypress()
功能:扫描哪个按键按下了
入口:无,出口:按下的按键
DHT11传感器数据获取模块
设计的全局变量
1 | uchar rec_dat[9]; |
定义的端口
1 | sbit Data=P3^6; |
函数设计
- DHT11_start()
功能:初始化DHT11温湿度传感器模块
入口:无,出口:无
- DHT11_rec_byte()
功能:DHT11接收获取到的字节数据
入口:无 出口:接收到的字节数据
- DHT11_receive()
功能:接收所有的温度湿度电平数据并进行转换
入口:无 出口:转换的温湿度数据
- DHT11_temget()
功能:把转换过的数据存进湿度和温度数组中去
入口:无 出口:无 调用函数:lcd_wcmd,lcd_busy()
显示温度界面
设计的全局变量
1 | uchar number[]="123456789"; ——矩阵键盘的按下值 |
定义的端口
1 | sbit beep=P2^5; ——蜂鸣器引脚 |
函数设计
- showtem()
功能:显示当前温度和湿度
入口:无,出口:无
- settem()
功能:设置温湿度上下限
入口:无 出口:无
ESP8266WIFI发送模块
函数设计
- UART_Init(void)
功能:初始化UART协议和定时器1
入口:无 出口:无
- UART_SendData(uchar dat)
功能:发送一个字符数据
入口:字符数据 出口:无
- UART_SendString(uchar *pbuf)
功能:发送一个字符串数据
入口:字符串数据 出口:无
ESP8266_SendCmd(uchar *pbuf)
功能:向ESP8266发送AT指令集
入口:AT指令,字符串格式,出口:无
ESP8266_SendData(uchar *pbuf)
功能:ESP8266 WIFI发送数据到APP
入口:数据 出口:无
- ESP8266_ModeInit(void)
功能:ESP8266 WIFI模块工作模式初始化
入口:无 出口:无
- ESP8266_SendData(uchar *pbuf)
功能:ESP8266 WIFI发送数据到APP
入口:数据 出口:无
- wifi_control_init(void)
功能:WIFI控制的初始化
入口:无 出口:无
EEPROM断电不丢失模块
定义的端口
1 | sbit sda = P2 ^ 0; //I2C总线数据线 |
函数设计
c02_init()
功能:初始化24C02芯片
入口:无,出口:无
start()
功能:启动II2C总线
入口:无 出口:无
- stop()
功能:停止II2C总线
入口:无 出口:无
- writebyte(unsigned char j)
功能:向数据线中写入一个字节
入口:一个字符数据 出口:无
- readbyte()
功能:读取数据线中的一个字节
入口:无 出口:无
- read24c02(unsigned char address)
功能:从24c02的地址address中读取一个字节数据
入口:24C02的地址 出口:无
- write24c02(unsigned char address, unsigned char info)
功能:向24c02的address地址中写入一字节数据info
入口:地址,字符数据 出口:无
- save_data()
功能:保存温度和湿度数据
入口:无 出口:无
- read_data()
功能:读取保存的温度和湿度数据
入口:无 出口:无
结果及测试分析
硬件电路
说明
硬件部分的连接过程在原理图中都有具体列出。
对于电源模块,由于51单片机自带的电源输出端口只有一个5V和3.3V不能够满足我们众多外加模块的供电需求,所以我这里采用面包板模拟拓展5V电源和3.3V电源。
在连接实物图时由于51单片机自带的12864端口会遮挡住引脚的连接,所以在这里我采用杜邦线把51单片机端口与12864端口相连接。DHT11温湿度传感器直接连接我们配置好的引脚并连接电源即可。继电器模块由于我们采用的是电平触发模式,所以需要把继电器模块的IN端口连接至配置好的端口并接上电源即可,COM端口接地、NC端口接电源,NO端口悬空,直流电机分别于GND和NC端口相连从而达到继电器控制直流电机的效果。ESP8266WIFI模块的RX和TX分别于单片机的TX和RX相连并且连接上3.3V电源和GND就可以达到上传数据至上位机和云平台的效果。
测试记录及结果分析
测试记录
首先通过usb线把单片机和电脑相连烧录程序,烧录完程序将自动进入初始界面,初始界面如下图所示。
当显示初始界面3s过后将会自动跳转至设置温度和湿度阈值的界面,然后通过独立键盘K1K4分别设置温度上限、温度下限、湿度上限、湿度下限,通过矩阵键盘K1K9设置温湿度阈值的具体数值
- 当设置好温湿度阈值时,点击矩阵键盘的K13即可进入温湿度显示页面,该页面可以显示温湿度的当前值和温湿度上下限值,显示界面如下图所示。
当温度和湿度超过设定的阈值时,继电器会启动,继电器的指示灯变为绿灯。
当按下矩阵键盘的K14键即可把单片机获取的温湿度数据发送至onenet云平台进行存储,我还绘制了一个可视化平台用来实时展示单片机获取的数据。数据存储以及可视化展示如下图所示。
- 我还制作了配套的微信小程序方便客户在手机端实时对温湿度的情况进行掌控和调配,小程序的页面如下图所示。
- 单片机与上位机通信,能够通过单片机实时把数据发送给电脑,电脑显示的数据如下图所示。
- 当断开单片机电源再接通单片机电源时我们设置的单片机上下限值会被保。













