一、工作原理
本设计选用STM32F103VET6为控制核心,DHT11为温湿度传感器,每隔两秒将得到的温度、湿度值经过处理后通过液晶屏和串口显示,并通过I2C—读写 EEPROM具有储存历史数据的功能,可以通过按键中断的方式切换LCD液晶屏的页面以柱状图的形式显示历史温湿度,另外该设计还具有报警功能,温度超过27度会触发蜂鸣器报警,湿度大于70%会亮红灯。
二、主要功能
1. 开机画面显示
用字模显示“欢迎”二字,并且使用字模的方式显示一个看门的小狗,此为 LCD 上显示的第一屏的内容,显示 2 秒左右。
2.温湿度实时显示
采样间隔 2s 同时显示温度和湿度表盘,在 LCD 上显示为第二屏。并将采集的数据发送到串口显示,同时用 EEPROM 保存实时的温湿度数据,在串口上显示保存的成功和失败。
3.历史信息保存与显示
保存历史信息到 I2C EEPROM。历史信息包括按键 K1 切换显示上一次关机前保存的 100 次历史信息(每次的数据包含温度和湿度的整数部分),共 200 字节的数据并在 LCD 上利用柱状图的方式显示为第三屏。
4 报警功能
当实时温度大于 27℃,蜂鸣器进行报警,湿度大于 70%RH 时 LED 亮红灯报警提示。
三、各功能模块的软件设计
-
系统软件设计
- 主要分为 4 个任务来完成:各部分初始化、获取温湿度数据、处理数据并显示以及报警提示。
- 初始化主要是对各个部分进行配置、函数初始化、波特率设置等;获取温湿度数据主要是通过 DHT11 温湿度传感器得到相应的温度、湿度值;处理数据并显示主要是控制器通过相关计算公式及转换将数据进行实时处理在液晶上进行显示,并可通过串口将数据发送给上位机;将历史信息储存到 EEPROM 中,并添加按键中断的方式切换 LCD 液晶屏的显示,以柱状图的形式显示历史数据;报警提示则主要是当湿度值大于 70%RH 时,蜂鸣器报警,温度大于 27℃时,LED 红灯报警提示,提醒系统采取相关措施。
-
字模部分
- 使用取模软件 PCtoLCD2002 完美版对相应的文字进行配置和取模,得到对应的像素点数组,然后对像素点进行轮询,描点,便可在 LCD 液晶屏上显示出对应的文字。对图片的取模同上。
- 然后把这些同开机界面放在一起,在程序的最开始执行 2 秒,显示在 LCD 液晶屏上。
-
温湿度检测部分
- 数字式温湿度传感器 DHT11 与 STM32F103VET6 单片机相应的引脚相连,对 DHT11 的读写遵循一定的通信时序。
- 读取 DHT11 温湿度值后需对数值进行数据校验,即判断校验和是否等于 8 位湿度整数数据、8 位湿度小数数据、8 位温度整数数据、8 位湿度小数数据的和,如果相等,则数据传输正确,将温湿度值传送给 LCD 液晶屏和通过串口发送到上位机。
-
LCD 液晶显示部分
- 使用定时器中断,每两秒对温湿度进行一次检测,然后把检测的数据进行处理,在液晶屏上以仪表盘的形式显示实时的温湿度数据,仪表盘上方用文字的形式显示近十次所测量的平均温湿度值,添加按键中断,如果按下 K1 按键则切换到历史数据页面,显示 2 秒左右,便会回到实时温度仪表盘显示界面。
-
串口模块
- 系统采用串口 1 与上位机通信,STM32F103VET6 单片机的串口 1 是由 PA9、PA10 端口复用构成,PA9 对应 USART1_TX,PA10 对应 USART1_RX,采用全双工模式,故需将 PA9 管脚配置为复用推挽输出(GPIO_Mode_AF_PP)模式,将 PA10 管脚配置为空输入(GPIO_Mode_IN_FLOATING)模式。
-
AT24C02
- 使用 ee_ReadBytes 函数从串行 EEPROM 指定地址处开始读取若干数据,使用 ee_WriteBytes 函数向串行 EEPROM 指定地址写入若干数据,采用页写操作提高写入效率。
-
LED 和蜂鸣器报警模块
- 当湿度值大于 70%RH 时,蜂鸣器报警,温度大于 27℃时,LED 红灯报警提示,提醒系统采取相关措施。
五、代码
wenshidu.c
#include "./systick/bsp_SysTick.h"
#include "./dht11/bsp_dht11.h"
#include "./usart/bsp_usart.h"
#include "bsp_TiMbase.h"
#include "stm32f10x.h"
#include "wenshidu.h"
uint32_t time = 0; // ms 计时变量
int Temp_sum_int=0,Humi_sum_int=0,Temp_max=-1000,Humi_max=-1000,Temp_min=9999,Humi_min=9999,Temp_aver=0,Humi_aver=0,pei=0;
int a[45]={0};
DHT11_Data_TypeDef DHT11_Data;
void wenshidu_read()
{
if( DHT11_Read_TempAndHumidity ( & DHT11_Data ) == SUCCESS)
{
a[pei]=DHT11_Data.humi_int;
a[pei+10]=DHT11_Data.temp_int;
Humi_sum_int+=a[pei];
Temp_sum_int+=a[pei+10];
if(Temp_max<a[pei+10])Temp_max=a[pei+10];
if(Humi_max<a[pei])Humi_max=a[pei];
if(Temp_min>a[pei+10])Temp_min=a[pei+10];
if(Humi_min>a[pei])Humi_min=a[pei];
//Delay_ms(50);
printf("\r\n读取DHT11成功!\r\n\r\n湿度为%d.%d %RH ,sum1=%d,sum2=%d,温度为 %d.%d℃ \r\n",\
DHT11_Data.humi_int,DHT11_Data.humi_deci,Humi_sum_int,Temp_sum_int,DHT11_Data.temp_int,DHT11_Data.temp_deci);
pei++;
printf("max1=%d,max2=%d\r\n",Temp_max,Humi_max);
printf("min1=%d,min2=%d\r\n",Temp_min,Humi_min);
}
else
{
printf("Read DHT11 ERROR!\r\n");
}
}
void wenshidu_display()
{
if(pei==10)
{
Temp_aver=(Temp_sum_int-Temp_max-Temp_min)*1/8;
Humi_aver=(Humi_sum_int-Humi_max-Humi_min)*1/8;
printf("\r\n读取DHT11成功!\r\n\r\n湿度为%d%RH ,温度为 %d℃ \r\n",\
Humi_aver,Temp_aver);
pei=0;
Temp_sum_int=0,Humi_sum_int=0;
Temp_max=-1000,Humi_max=-1000,Temp_min=9999,Humi_min=9999,Temp_aver=0,Humi_aver=0;
}
}