news 2026/5/30 23:08:59

STM32项目分享:工地环境监测系统

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
STM32项目分享:工地环境监测系统

目录

一、前言

二、项目简介

1.功能详解

2.主要器件

三、原理图设计

四、PCB硬件设计

PCB图

五、程序设计

六、实验效果 ​

七、包含内容

项目分享


一、前言

项目成品图片:

哔哩哔哩视频链接:

https://www.bilibili.com/video/BV1n3vsBREBD/?spm_id_from=333.337.search-card.all.click

(资料分享见文末)

二、项目简介

1.功能详解

基于STM32的工地环境监测系统

功能如下:

  1. 环境采集:温湿度、是否有噪音、PM2.5粉尘浓度
  2. 显示功能:环境数据显示在OLED屏幕上
  3. 模式切换:通过按键可以切换手动模式和自动模式
  4. 自动模式:环境温度高于阈值时开启风扇降温并蜂鸣器报警,有噪音时打开LED;环境PM2.5浓度超过阈值时开启加湿器沉降粉尘并开启蜂鸣器报警。湿度低于湿度下限打开加湿器,高于湿度上限打开风扇。
  5. 手动模式:可通过按键切换为手动模式,可以控制LED灯、蜂鸣器、风扇、加湿器的开关。
  6. 阈值调节:可设置温度阈值、噪声阈值和PM2.5浓度阈值、湿度上限、下限阈值。
  7. 机智云APP:接收温湿度、噪声大小和PM2.5浓度信息,可控制模式切换,在手动模式下可以控制LED灯、风扇、加湿器的开关以及阈值调节

2.主要器件

  • STM32F103C8T6最小系统板
  • OLED显示屏(4针IIC协议)
  • DHT11温湿度传感器
  • 声音传感器
  • PM2.5粉尘传感器
  • ESP8266-01S(WIFI模块)
  • 加湿器模块
  • 继电器
  • 风扇模块
  • 蜂鸣器
  • LED灯

三、原理图设计

四、PCB硬件设计

PCB图

五、程序设计

#include "stm32f10x.h" #include "led.h" #include "beep.h" #include "usart.h" #include "delay.h" #include "oled.h" #include "key.h" #include "Modules.h" #include "adcx.h" #include "flash.h" #include "usart2.h" #include "usart3.h" #include "dht11.h" #include "PM25.h" #include "TIM2.h" #include "JSQ.h" #include "relay.h" #include "timer.h" #include "TIM3.h" #include "gizwits_product.h" #include "gizwits_protocol.h" /****************异方辰电子工作室****************** STM32 *文件 : STM32工地监测系统 *版本 : V1.0 *日期 : 2025.12.24 *MCU : STM32F103C8T6 *接口 : 见代码 *BILIBILI : 异方辰电子 *小红书 : 异方辰电子 *CSDN : 异方辰电子 *授权IP : 辰哥单片机设计、异方辰、YFC电子、北海单片机设计 **********************BEGIN***********************/ #define KEY_Long1 11 #define KEY_1 1 #define KEY_2 2 #define KEY_3 3 #define KEY_4 4 #define AUTO_MODE 1 // 自动模式 #define MANUAL_MODE 2 // 手动模式 #define SETTINGS_MODE 3 // 设置模式 #define FLASH_START_ADDR 0x0801f000 //写入的起始地址 extern SensorModules sensorData; extern SensorThresholdValue Sensorthreshold; extern DriveModules driveData; uint8_t mode = 1; //系统模式 1自动 2手动 3设置 u8 dakai;//串口3使用的传递变量 u8 Flag_dakai;//串口3接收标志位 uint8_t is_secondary_menu = 0; // 0一级菜单,1二级菜单 uint8_t secondary_pos = 1; // 二级菜单光标位置(1-3对应时/分/秒) uint8_t secondary_type = 0; // 二级菜单类型:0=RTC时间,1=定时开启,2=定时关闭 //系统静态变量 //static uint8_t count_a = 1; //自动模式按键数 uint8_t count_m = 1; //手动模式按键数 uint8_t count_s = 1; //设置模式 uint8_t last_mode = 0; // 记录上一次的模式 //static uint8_t last_count_s = 0; // 记录设置模式内上一次的页面 int main(void) { SystemInit(); delay_init(72); ADCx_Init(); LED_Init(); BEEP_Init(); BEEP_OFF; USART1_Config(); USART2_Config(); USART3_Config(); Key_Init(); DHT11_Init(); PM25_Init(); OLED_Init(); RELAY_Init(); JSQ_Init(); OLED_Clear(); //flash读取 delay_ms(100); FLASH_ReadThreshold(); // 添加的状态管理变量 static uint8_t last_mode = 0; // 记录上一次模式 static uint32_t last_sensor_time = 0; // 传感器扫描时间控制 static uint32_t last_display_time = 0; // 显示刷新时间控制 //超过以下值,恢复默认阈值 if (Sensorthreshold.tempValue > 40 || Sensorthreshold.humimaxValue >80 || Sensorthreshold.humiminValue < 20 ||Sensorthreshold.pmValue > 200 ) { FLASH_W(FLASH_START_ADDR, 30, 50, 30,20); FLASH_ReadThreshold(); } TIM2_Init(72-1,1000-1); // 2ms定时中断 TIM3_Int_Init(1000-1,72-1); userInit(); // 机智云用户初始化(数据点初始化等) gizwitsInit(); // 机智云协议初始化(WiFi配网、数据通信初始化) gizwitsSetMode(WIFI_AIRLINK_MODE); //默认一键配网 delay_ms(200); printf("Start \n"); gizwitsHandle((dataPoint_t *)&currentDataPoint); ScanGizwitsMode(); delay_ms(200); while (1) { gizwitsHandle((dataPoint_t *)&currentDataPoint); // ==================== 获取当前系统时间(基于定时器2滴答计数)==================== uint32_t current_time = delay_get_tick(); // ==================== 优化传感器扫描频率 ==================== if(current_time - last_sensor_time > 100) // 每200ms扫描一次传感器 (100 * 2ms = 200ms) { SensorScan(); //获取传感器数据 last_sensor_time = current_time; } // ==================== 立即处理按键 ==================== uint8_t current_key_num = KeyNum; // 保存当前按键值 // 模式切换按键立即处理 if(current_key_num != 0) { switch(mode) { case AUTO_MODE: if(current_key_num == KEY_1) { mode = MANUAL_MODE; count_m = 1; // 切换到手动模式时关闭灯和蜂鸣器 driveData.LED_Flag = 0; driveData.BEEP_Flag = 0; driveData.JSQ_Flag = 0; driveData.Fan_Flag = 0; currentDataPoint.valueled = driveData.LED_Flag; currentDataPoint.valuebeep = driveData.BEEP_Flag; currentDataPoint.valueJSQ = driveData.JSQ_Flag; currentDataPoint.valueFAN = driveData.Fan_Flag; KeyNum = 0; } else if(current_key_num == KEY_Long1) { mode = SETTINGS_MODE; count_s = 1; KeyNum = 0; } break; case MANUAL_MODE: if(current_key_num == KEY_1) { mode = AUTO_MODE; KeyNum = 0; } break; case SETTINGS_MODE: // 设置模式内部按键在各自模式中处理 break; } } // ==================== 模式切换优化 ==================== if(last_mode != mode) { OLED_Clear(); last_mode = mode; // 立即绘制新模式的固定内容 switch(mode) { case AUTO_MODE: OLED_autoPage1(); break; case MANUAL_MODE: OLED_manualPage1(); break; case SETTINGS_MODE: OLED_settingsPage1(); break; } OLED_Refresh(); // 立即刷新显示 } // ==================== 模式处理 ==================== switch(mode) { case AUTO_MODE: // 直接调用显示,不使用SetAuto() SensorDataDisplay1(); //显示传感器1数据 AutoControl(); Control_Manager(); break; case MANUAL_MODE: { static uint8_t manual_page_initialized = 0; static uint8_t last_manual_count = 0; static uint8_t last_LED_Flag = 0; static uint8_t last_BEEP_Flag = 0; static uint8_t force_refresh = 0; // 强制刷新标志 // 模式切换时重新初始化 if(last_mode != mode) { manual_page_initialized = 0; last_manual_count = 0; last_LED_Flag = driveData.LED_Flag; last_BEEP_Flag = driveData.BEEP_Flag; force_refresh = 1; // 设置强制刷新标志 // 确保光标指向灯光 count_m = 1; // 确保设备状态为关 driveData.LED_Flag = 0; driveData.BEEP_Flag = 0; driveData.JSQ_Flag = 0; driveData.Fan_Flag = 0; currentDataPoint.valueled = driveData.LED_Flag; currentDataPoint.valuebeep = driveData.BEEP_Flag; currentDataPoint.valueJSQ = driveData.JSQ_Flag; currentDataPoint.valueFAN = driveData.Fan_Flag; } uint8_t current_manual_count = SetManual(); // 检查设备状态是否改变,如果改变则强制刷新显示 uint8_t need_refresh = 0; if(driveData.LED_Flag != last_LED_Flag || driveData.BEEP_Flag != last_BEEP_Flag) { need_refresh = 1; last_LED_Flag = driveData.LED_Flag; last_BEEP_Flag = driveData.BEEP_Flag; } // 确保页面已初始化或光标位置改变或设备状态改变或强制刷新时重新绘制 if(!manual_page_initialized || current_manual_count != last_manual_count || need_refresh || force_refresh) { OLED_manualPage1(); OLED_manualOption(current_manual_count); // 光标 ManualSettingsDisplay1(); // 状态 manual_page_initialized = 1; last_manual_count = current_manual_count; force_refresh = 0; // 清除强制刷新标志 OLED_Refresh(); // 强制刷新显示 } // 立即处理手动模式按键 if(current_key_num != 0) { ManualControl(current_manual_count); OLED_manualPage1(); // 重新绘制固定文字 OLED_manualOption(current_manual_count); // 光标 ManualSettingsDisplay1(); // 状态 OLED_Refresh(); // 按键操作后立即刷新 KeyNum = 0; // 立即清除按键标志 } // 确保显示内容始终正确 OLED_manualPage1(); // 固定文字 OLED_manualOption(current_manual_count); // 光标 ManualSettingsDisplay1(); // 状态 Control_Manager(); break; } case SETTINGS_MODE: { // 优化设置模式响应速度 static uint8_t is_threshold_page_inited = 0; uint8_t curr_count_s = SetSelection(); // 立即处理设置模式内的按键 if(current_key_num != 0) { if (is_secondary_menu == 1) { // 二级菜单按键立即处理 if (current_key_num == KEY_2 || current_key_num == KEY_3 || current_key_num == KEY_4) { // 这里根据你的二级菜单逻辑处理 // 处理完后立即刷新 OLED_Refresh(); KeyNum = 0; } else if (current_key_num == KEY_1) { is_secondary_menu = 0; secondary_pos = 1; OLED_Clear(); OLED_settingsPage1(); SettingsThresholdDisplay1(); OLED_settingsOption(curr_count_s); OLED_Refresh(); KeyNum = 0; } } else { // 一级菜单按键立即处理 if (current_key_num == KEY_3 || current_key_num == KEY_4) { ThresholdSettings(curr_count_s); SettingsThresholdDisplay1(); OLED_Refresh(); KeyNum = 0; } else if (current_key_num == KEY_1) { mode = AUTO_MODE; is_threshold_page_inited = 0; FLASH_W(FLASH_START_ADDR, Sensorthreshold.tempValue, Sensorthreshold.humimaxValue, Sensorthreshold.humiminValue,Sensorthreshold.pmValue); KeyNum = 0; } } } // 正常显示逻辑 if (is_secondary_menu == 1) { } else { // 一级菜单显示 if (curr_count_s >= 1 && curr_count_s <= 4) { if (is_threshold_page_inited == 0) { OLED_settingsPage1(); is_threshold_page_inited = 1; } } OLED_settingsOption(curr_count_s); SettingsThresholdDisplay1(); } break; } } // ==================== 限制显示刷新频率 ==================== if(current_time - last_display_time > 25) // 每50ms刷新一次显示 { // 所有模式都需要刷新显示 OLED_Refresh(); last_display_time = current_time; } userHandle(); } }

六、实验效果

七、包含内容

项目分享

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/29 17:20:22

当测试工程师遇见AI:智能求职信炼成术

在竞争激烈的软件测试领域&#xff0c;一封融合技术深度与岗位匹配度的求职信能让你从海量简历中脱颖而出。本文基于最新AI技术实践&#xff0c;为测试工程师拆解从JD解析、经历重构到风险规避的全流程方法论&#xff0c;助你将自动化测试思维转化为求职竞争力。 一、精准拆解测…

作者头像 李华
网站建设 2026/5/27 16:22:44

【为什么商城小程序源码比较贵】

这是一个很多创业者和中小企业都会有的困惑。为什么一个看起来“只是些页面和按钮”的商城小程序源码会卖到几万甚至几十万&#xff1f; 这背后是开发成本、技术价值、后期维护和商业逻辑的综合体现。让我们拆解来看&#xff1a; 一、核心原因&#xff1a;开发成本远高于你的…

作者头像 李华
网站建设 2026/5/28 23:39:42

为什么2026年是学习Rust的最佳时机?职业红利

在2026年&#xff0c;软件测试从业者正站在技术转型的关键节点。随着行业对高效、安全系统的需求激增&#xff0c;Rust语言凭借其独特优势&#xff0c;从niche工具跃升为主流选择。本文将从测试工程师的专业视角&#xff0c;解析Rust的核心价值、行业采用趋势&#xff0c;并重点…

作者头像 李华
网站建设 2026/5/28 21:07:40

复杂邮件路由场景下域名伪造钓鱼的成因与系统性防御研究

摘要 Microsoft于2026年初披露&#xff0c;攻击者正利用企业邮件基础设施中的复杂路由拓扑与安全协议配置缺陷&#xff0c;实施高隐蔽性的域名伪造&#xff08;domain spoofing&#xff09;钓鱼攻击。此类攻击通过操控未被SPF记录授权的中继节点、滥用第三方邮件网关或利用宽松…

作者头像 李华
网站建设 2026/5/28 23:58:18

[深度学习网络从入门到入土] 感知机Perceptron

[深度学习网络从入门到入土] 感知机Perceptron 个人导航 知乎&#xff1a;https://www.zhihu.com/people/byzh_rc CSDN&#xff1a;https://blog.csdn.net/qq_54636039 注&#xff1a;本文仅对所述内容做了框架性引导&#xff0c;具体细节可查询其余相关资料or源码 参考文…

作者头像 李华