• 方案介绍
  • 相关推荐
申请入驻 产业图谱

基于STM32的温湿度采集监测报警OLED显示_proteus仿真+程序代码+设计报告+讲解

58分钟前
195
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

基于STM32的远程温湿度采集监测报警OLED显示设计

本设计包含proteus仿真+程序代码+设计报告+讲解视频

一、开发环境

仿真图:proteus 8.17

程序编译器:keil 5

编程语言:C语言

设计编号:C0137

二、主要功能

本次嵌入式设计综合实验的内容为基于STM32F103c8t6单片机的温湿度采集报警系统。完成OLED液晶显示、DHT11温湿度测量、指示灯、蜂鸣器控制等多项任务。

1、以STM32为最小系统电路进行连接,用OLED显示屏显示温度、湿度、温度阈值,湿度阈值。

2、用DHT11温湿度传感器进行温湿度的测量。

3、可以通过按键可以设置温湿度阈值。设置按键进入设置模式/退出设置模式,按键加减调整阈值。

4、当温度超过设置的阈值时有声光报警,对应报警指示灯点亮,蜂鸣器报警。

5、默认温度低阈值20℃,高阈值30℃,湿度低阈值50%,湿度高阈值80%。

6、云平台远程查看温湿度检测值(仿真使用串口模拟)

主要硬件设备:STM32F103C8 单片机 DHT11温湿度传感器 OLED 蜂鸣器

资料下载链接:

KEY_C0137 STM32温湿度报警器OLED显示

链接: https://pan.baidu.com/s/1lxCel6dXsWPQSoyx4RD2Dw?pwd=tqy4

提取码: tqy4

以下为本设计资料展示:

三、仿真设计

打开仿真工程,双击proteus中的单片机,选择hex文件路径,然后开始仿真。

四、程序代码

程序是用keil5 mdk版本打开的,如果打开有问题,核实下keil的版本。程序有注释可以结合讲解视频理解。

main.c

//单片机头文件#include "stm32f10x.h"//网络协议层#include "onenet.h"//网络设备#include "esp8266.h"//硬件驱动#include "delay.h"#include "usart.h"#include "beep.h"#include "led.h"#include "fan.h"#include "key.h"#include "dht11.h"#include "oled.h"#include "mq2.h"#include "fan_pwm.h"//C库#include <string.h>#include <stdio.h>// ESP8266 连接 OneNET 服务器 (MQTTs 协议,端口1883)#define ESP8266_ONENET_INFO		"AT+CIPSTART=\"TCP\",\"mqtts.heclouds.com\",1883rn"// 函数声明void Hardware_Init(void);void Display_Init(void);void Refresh_Data(void);void Led_beep_sta(void);// 全局变量u8 temp, humi;                      // 温度和湿度值 (来自DHT11)uint8_t Beep_Status;                // 蜂鸣器状态标志 uint16_t set_temp_dat_l = 20;       // 温度下限报警值 (低阈值)uint16_t set_temp_dat = 30;         // 温度上限报警值 (高阈值)uint16_t set_hum_dat = 50;          // 湿度下限报警值uint16_t set_hum_dat_h = 80;        // 湿度上限报警值uint8_t Status_Change;              // 状态变化标志 (代码中未实际使用)u8 set_sta = 0;                     // 设置状态: 0-无编辑, 1-编辑温度下限, 2-编辑温度上限, 3-编辑湿度下限, 4-编辑湿度上限// char data_str2[]="        ";      // 注意: 原注释提到这样会越界,所以分配24字节char data_str2[24];                 // 用于OLED显示报警阈值的字符串缓冲区/**************************************************************	函数名称:	main*	函数功能:	主函数,程序入口*	入口参数:	无*	返回参数:	0*	说明:		初始化硬件、连接网络,循环读取传感器数据并上传至OneNET,*               处理云平台下发指令,刷新本地显示,控制LED和蜂鸣器*************************************************************/int main(void){    DHT11_Data_TypeDef DHT11_Data;	    // DHT11 数据结构体    unsigned short timeCount = 0;	    // 发送间隔计数器    unsigned char *dataPtr = NULL;      // 接收网络数据指针    Hardware_Init();			        // 初始化外围硬件 (GPIO、串口、传感器等)    ESP8266_Init();				        // 初始化ESP8266 WiFi模块    // 以下连接OneNET的代码被注释,实际产品中应取消注释    // UsartPrintf(USART_DEBUG, "Connect MQTTs Server...rn");    // OLED_Clear(); OLED_ShowString(0,0,"Connect MQTTs Server...",16);    // while(ESP8266_SendCmd(ESP8266_ONENET_INFO, "CONNECT"))    //     DelayXms(500);    // UsartPrintf(USART_DEBUG, "Connect MQTT Server Successrn");    // OLED_ShowString(0,4,"Connect MQTT Server Success",16); DelayXms(500);    // OLED_Clear(); OLED_ShowString(0,0,"Device login ...",16);    // while(OneNet_DevLink())			// 接入OneNET    // {    //     ESP8266_SendCmd(ESP8266_ONENET_INFO, "CONNECT");    //     DelayXms(500);    // }    // OneNET_Subscribe();               // 订阅云平台下发指令的主题    Display_Init();                     // 初始化OLED显示界面    // Led_Set(LED_ON);                 // (注释) 默认开LED    Beep_Set(BEEP_OFF);                 // 蜂鸣器初始关闭    // 临时赋值,用于测试显示     temp = 25;    humi = 65;    while(1)    {        // 每隔约2.5秒 (50 * 50ms) 上传一次数据到OneNET        if(++timeCount >= 50)        {            // 读取DHT11温湿度传感器            if(DHT11_Read_TempAndHumidity(&DHT11_Data) == SUCCESS) {                humi = DHT11_Data.humi_int;                temp = DHT11_Data.temp_int;            }	            UsartPrintf(USART_DEBUG, "humi = %d,temp = %d  rn", humi, temp);            // UsartPrintf(USART_DEBUG, "OneNet_SendDatarn");            OneNet_SendData();			                // 发送数据到OneNET            timeCount = 0;                              // 重置计数器            ESP8266_Clear();                            // 清空ESP8266接收缓冲区        }        // 再次读取温湿度 (非间隔期间也频繁刷新,保证显示实时)        if(DHT11_Read_TempAndHumidity(&DHT11_Data) == SUCCESS) {            humi = DHT11_Data.humi_int;            temp = DHT11_Data.temp_int;        }			        // 检查ESP8266是否收到来自OneNET的MQTT消息        dataPtr = ESP8266_GetIPD(0);        if(dataPtr != NULL)            OneNet_RevPro(dataPtr);                     // 处理接收到的MQTT协议数据        Refresh_Data();                                 // 刷新OLED显示的数值        Led_beep_sta();                                 // 根据阈值控制LED和蜂鸣器        DelayMs(10);                                    // 主循环延时10ms,避免CPU过忙    }}/**************************************************************	函数名称:	Hardware_Init*	函数功能:	硬件初始化*	入口参数:	无*	返回参数:	无*	说明:		配置中断分组、延时函数、串口(调试/ESP8266)、按键、LED、*               蜂鸣器、DHT11、OLED等外设*************************************************************/void Hardware_Init(void){    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	// 中断控制器分组设置 (2位抢占,2位响应)    Delay_Init();									// SysTick延时初始化    Usart1_Init(115200);							// 串口1,用于打印调试信息    Usart2_Init(115200);							// 串口2,用于驱动ESP8266    Key_Init();                                     // 按键初始化     Led_Init();										// LED初始化 (4个LED)    Beep_Init();									// 蜂鸣器初始化    DHT11_Init();                                   // DHT11温湿度传感器初始化    OLED_Init();		                            // OLED显示屏初始化    UsartPrintf(USART_DEBUG, " Hardware init OKrn");    OLED_Clear();     OLED_ShowString(0,0,"Hardware init OK",16);     DelayMs(1000);}/**************************************************************	函数名称:	Display_Init*	函数功能:	OLED显示界面初始化 (显示固定标签和当前报警阈值)*	入口参数:	无*	返回参数:	无*	说明:		设置的温湿度上下限,*               并根据set_sta在对应数值旁显示光标('^')表示正在编辑的项*************************************************************/void Display_Init(void){    OLED_Clear();      // 第6行显示温湿度报警阈值 (根据set_sta显示光标)    if(set_sta == 0) {        sprintf(data_str2," %d--%d  %d--%d ", set_temp_dat_l, set_temp_dat, set_hum_dat, set_hum_dat_h);        OLED_ShowString(0,6,(u8*)data_str2,16);    }    if(set_sta == 1) {   // 设置温度下限,在数值后加'^'        sprintf(data_str2,"%d^-%d  %d--%d ", set_temp_dat_l, set_temp_dat, set_hum_dat, set_hum_dat_h);        OLED_ShowString(0,6,(u8*)data_str2,16);    }    if(set_sta == 2) {   // 设置温度上限        sprintf(data_str2,"%d--%d^ %d--%d ", set_temp_dat_l, set_temp_dat, set_hum_dat, set_hum_dat_h);        OLED_ShowString(0,6,(u8*)data_str2,16);    }    if(set_sta == 3) {   // 设置湿度下限        sprintf(data_str2,"%d--%d  %d^-%d ", set_temp_dat_l, set_temp_dat, set_hum_dat, set_hum_dat_h);        OLED_ShowString(0,6,(u8*)data_str2,16);    }    if(set_sta == 4) {   // 设置湿度上限        sprintf(data_str2,"%d--%d  %d--%d^ ", set_temp_dat_l, set_temp_dat, set_hum_dat, set_hum_dat_h);        OLED_ShowString(0,6,(u8*)data_str2,16);    }}/**************************************************************	函数名称:	Refresh_Data*	函数功能:	刷新OLED显示的温度、湿度数值以及报警阈值*	入口参数:	无*	返回参数:	无*	说明:		将temp和humi转换为字符串显示在对应位置,*               并根据set_sta重新绘制带有光标的阈值行*************************************************************/void Refresh_Data(void){    char buf[5];        if(Status_Change) {        // 如果状态变化标志为真,此处预留处理 (本代码未实现)    }    else {        // 显示温度值        sprintf(buf, "%2d", temp);        OLED_ShowString(54,0,(u8*)buf,16);                // 显示湿度值        sprintf(buf, "%2d", humi);        OLED_ShowString(54,3,(u8*)buf,16);               // 重新显示报警阈值行 (与Display_Init类似,保持光标同步)        if(set_sta == 0) {            sprintf(data_str2," %d--%d  %d--%d ", set_temp_dat_l, set_temp_dat, set_hum_dat, set_hum_dat_h);            OLED_ShowString(0,6,(u8*)data_str2,16);        }        if(set_sta == 1) {            sprintf(data_str2,"%d^-%d  %d--%d ", set_temp_dat_l, set_temp_dat, set_hum_dat, set_hum_dat_h);            OLED_ShowString(0,6,(u8*)data_str2,16);        }        if(set_sta == 2) {            sprintf(data_str2,"%d--%d^ %d--%d ", set_temp_dat_l, set_temp_dat, set_hum_dat, set_hum_dat_h);            OLED_ShowString(0,6,(u8*)data_str2,16);        }        if(set_sta == 3) {            sprintf(data_str2,"%d--%d  %d^-%d ", set_temp_dat_l, set_temp_dat, set_hum_dat, set_hum_dat_h);            OLED_ShowString(0,6,(u8*)data_str2,16);        }        if(set_sta == 4) {            sprintf(data_str2,"%d--%d  %d--%d^ ", set_temp_dat_l, set_temp_dat, set_hum_dat, set_hum_dat_h);            OLED_ShowString(0,6,(u8*)data_str2,16);        }    }}/**************************************************************	函数名称:	Led_beep_sta*	函数功能:	根据温湿度与设定阈值的比较结果,控制4个LED和蜂鸣器*	入口参数:	无*	返回参数:	无*	说明:		温度高于上限 -> LED1亮;温度低于下限 -> LED2亮;*               湿度低于下限 -> LED3亮;湿度高于上限 -> LED4亮;*               任何一个LED亮则蜂鸣器报警*************************************************************/void Led_beep_sta(void){    // 如果传感器读数为0或处于设置模式,不进行报警控制    if(temp == 0 || humi == 0 || set_sta != 0) {        return;    }        // 温度上限报警 (高温)    if(temp > set_temp_dat) {        LED1 = LED_ON;      // 温度高于高阈值,LED1点亮    } else {        LED1 = LED_OFF;     // 温度未超上限,LED1熄灭    }        // 温度下限报警 (低温)    if(set_temp_dat_l > temp) {        LED2 = LED_ON;      // 温度低于低阈值,LED2点亮    } else {        LED2 = LED_OFF;     // 温度高于低阈值,LED2熄灭    }        // 湿度下限报警 (干燥)    if(humi < set_hum_dat) {        LED3 = LED_ON;      // 湿度低于下限,LED3点亮    } else {	        LED3 = LED_OFF;     // 湿度正常,LED3熄灭    }        // 湿度上限报警 (潮湿)    if(humi > set_hum_dat_h) {        LED4 = LED_ON;      // 湿度高于上限,LED4点亮    } else {	        LED4 = LED_OFF;     // 湿度正常,LED4熄灭    }        // 如果任意一个LED处于点亮状态,则蜂鸣器报警    if(!LED1 || !LED2 || !LED3 || !LED4) {        Beep_Set(BEEP_ON);    } else {        Beep_Set(BEEP_OFF);    }}

程序流程图:

五、设计说明书

9706字,内容包括硬件设计、软件设计、结论等。

六、资料清单&下载链接

资料下载链接:

链接: https://pan.baidu.com/s/1lxCel6dXsWPQSoyx4RD2Dw?pwd=tqy4

提取码: tqy4

更多资源 点击下方链接:

https://docs.qq.com/sheet/DS0xIa0llTmtNakRW

以下是实物图,需要定制实物可咨询!

相关推荐