基于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
以下是实物图,需要定制实物可咨询!
195