文章目录
一、前言
实物项目成品:

仿真项目成品:

哔哩哔哩开源视频链接(复制浏览器打开):
https://www.bilibili.com/video/BV185YX6JEfL/?vd_source=10da4d04d580bd6b34f7298120737c50
(资料分享见文末)
二、项目功能简介
【开源】STM32单片机智能安防与燃气监测系统(代码+原理图+仿真)-编号:CY26017
硬件:STM32+OLED+蜂鸣器+门磁+可燃气体传感器+排风+舵机阀门+温湿度传感器+WIFI+火焰传感器
功能介绍:
- 防盗模式切换功能:系统可切换防盗开启、防盗关闭两种工作模式。
- 入侵检测报警功能:防盗模式开启时,门磁检测到开门判定为非法闯入;防盗关闭时,门磁触发为正常出入,不报警。
- 可燃气体泄漏监测功能:实时采集可燃气体浓度,浓度超标触发蜂鸣器声光报警。
- 险情联动控制功能:燃气泄漏或者检测到火焰时,自动启动排风设备,舵机动作关闭燃气阀门;支持手动控制阀门开关。
- 火灾探测报警功能:火焰传感器检测到火情,触发声光报警,联动排风与燃气切断动作。
- 环境参数采集显示功能:实时采集室内温湿度,OLED 屏幕显示温湿度数据,数据异常时报警提示。
- WiFi 远程数据查看功能:通过 WiFi 模块上传各项监测数据,手机 APP 可远程查看系统实时状态。
- APP 远程报警推送功能:出现入侵、燃气泄漏、火灾险情时,报警消息推送至手机 APP 提醒用户。
三、PCB设计

四、原理图设计

五、程序设计
代码如下():
c
#include "sys.h"
#include "delay.h"
#include "oled.h"
#include "usart.h"
#include "dht11.h"
#include "key.h"
#include "adc.h"
#include "gpio.h"
#include "usart3.h"
#include "..\\HARDWARE\\ONENET\\cloud_onenet.h"
#include "..\\HARDWARE\\ONENET\\onenet_app_state.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include "math.h"
/**********************************
鍙橀噺瀹氫箟
**********************************/
char display_buf[50];
uint8_t key_num = 0; // 鎸夐敭鎵弿鏍囧織浣?
uint8_t flag_display = 0; // 鏄剧ず鐣岄潰鏍囧織浣?
uint8_t set_count = 0; // 闃堝€艰缃爣蹇椾綅
uint8_t flag_mode = 0; // 0:鑷姩 1:鎵嬪姩
uint8_t shuaxing = 0;
uint8_t beepflag = 0, sendyu_flag = 0;
uint8_t smart_config = 0;
uint8_t yanwu_value = 0; // 鐏劙鐘舵€?
uint8_t yanwu_max = 20; // 鐏劙鎶ヨ闃堝€?
uint8_t MQ_value = 0; // 鍙噧姘斾綋娴撳害
uint8_t gas_leak_th = 20; // 婕忔皵闃堝€?(%)
uint8_t gas_over_th = 40; // 瓒呮爣闃堝€?(%)
uint8_t gas_level = 0; // 0姝e父 1婕忔皵 2瓒呮爣
uint8_t temp = 0; // 鐜娓╁害
uint8_t temp_max = 35; // 娓╁害涓婇檺
uint8_t humi = 0; // 鐜婀垮害
uint8_t humi_max = 70; // 婀垮害涓婇檺
uint8_t humi_min = 30; // 婀垮害涓嬮檺
uint8_t smoke_detected = 0; // 鍙噧姘斾綋鐘舵€?
uint8_t fire_detected = 0; // 鐏劙杈撳叆鐘舵€?
uint8_t door_opened = 0; // 闂ㄧ杈撳叆鐘舵€?
uint8_t security_enabled = 0; // 闃茬洍妯″紡
uint8_t intrusion_alarm = 0; // 鍏ヤ镜鎶ヨ
uint8_t gas_alarm = 0; // 鍙噧姘斾綋鎶ヨ
uint8_t fire_alarm = 0; // 鐏伨鎶ヨ
uint8_t gas_alarm_type = 0; // 0鏃?1婕忔皵 2瓒呮爣
uint8_t manual_fan_on = 0; // 鎵嬪姩鎺掗
uint8_t auto_valve_locked = 0; // 鑷姩妯″紡閿侀榾鏍囧織
uint16_t gas_alarm_hold_ms = 0; // 鍙噧姘斾綋鎶ヨ淇濇寔鏃堕棿
uint16_t fire_alarm_hold_ms = 0;// 鐏伨鎶ヨ淇濇寔鏃堕棿
uint16_t CO2 = 0;
uint16_t CO2_max = 2000;
u8 sendbuff[30];
/**********************************
鍑芥暟澹版槑
**********************************/
void Key_function(void);
void Monitor_function(void);
void Display_function(void);
void Manage_function(void);
void Move_function(uint8_t num);
void Update_Valve_Output(uint8_t closed);
/****
******* 瀹氭椂鍣ㄥ垵濮嬪寲鍑芥暟
*****/
void TIM4_Init(u16 arr, u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
TIM_TimeBaseStructure.TIM_Period = arr;
TIM_TimeBaseStructure.TIM_Prescaler = psc;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_Cmd(TIM4, ENABLE);
}
/****
******* 涓诲嚱鏁?*****/
int main(void)
{
delay_init();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
BEEP_Init();
Key_Init();
Usart1_Init(9600);
Usart2_Init(9600);
USART3_Config();
DHT11_Init();
Adc_Init();
TIM4_Init(1000, 72);
Oled_Init();
Oled_Clear_All();
Cloud_StartupUI();
while(1)
{
Key_function();
Monitor_function();
Display_function();
Manage_function();
Cloud_Task();
}
}
/****
******* 鎸夐敭鍑芥暟
*****/
void Key_function(void)
{
key_num = Chiclet_Keyboard_Scan(0);
if(key_num != 0)
{
switch(key_num)
{
case 1:
flag_display++;
if(flag_display >= 3)
flag_display = 0;
if(flag_display == 2)
{
set_count = 1;
}
else
{
set_count = 0;
}
Oled_Clear_All();
break;
case 2:
if(flag_display == 2)
{
set_count++;
if(set_count > 4)
set_count = 1;
}
else
{
flag_mode++;
if(flag_mode > 1)
flag_mode = 0;
if(flag_mode == 0)
{
manual_fan_on = 0;
}
}
break;
case 3:
if(flag_display == 0)
{
security_enabled = !security_enabled;
}
else if(flag_display == 1 && flag_mode == 1)
{
manual_fan_on = !manual_fan_on;
ExhaustFan_Set(manual_fan_on);
}
else if(flag_display == 2)
{
switch(set_count)
{
case 1:
if(temp_max < 99) temp_max++;
break;
case 2:
if(humi_max < 99) humi_max++;
break;
case 3:
if(gas_leak_th < (uint8_t)(gas_over_th - 1)) gas_leak_th++;
break;
case 4:
if(gas_over_th < 99) gas_over_th++;
break;
default:
break;
}
}
break;
case 4:
if(flag_display == 1 && flag_mode == 1)
{
Update_Valve_Output(!ServoValve_IsClosed());
}
else if(flag_display == 2)
{
switch(set_count)
{
case 1:
if(temp_max > 0) temp_max--;
break;
case 2:
if(humi_max > 0) humi_max--;
break;
case 3:
if(gas_leak_th > 0) gas_leak_th--;
break;
case 4:
if(gas_over_th > (uint8_t)(gas_leak_th + 1)) gas_over_th--;
break;
default:
break;
}
}
break;
default:
break;
}
}
}
/****
******* 鍏夋爣鍑芥暟
*****/
void Move_function(uint8_t num)
{
(void)num;
}
void Update_Valve_Output(uint8_t closed)
{
if(closed)
{
ServoValve_Close();
}
else
{
ServoValve_Open();
}
}
/****
******* 鐩戞祴鍑芥暟
*****/
void Monitor_function(void)
{
uint16_t mq_adc_raw = 0;
uint8_t gas_alarm_now = 0;
uint8_t fire_alarm_now = 0;
DHT11_Read_Data(&humi, &temp);
mq_adc_raw = Get_Adc_Average(1, 1); // PA1瀵瑰簲ADC1_IN1
MQ_value = (uint8_t)((mq_adc_raw * 100U) / 4095U);
if(MQ_value > 100)
{
MQ_value = 100;
}
if(MQ_value >= gas_over_th)
{
gas_level = 2;
}
else if(MQ_value >= gas_leak_th)
{
gas_level = 1;
}
else
{
gas_level = 0;
}
smoke_detected = (gas_level > 0) ? 1 : 0;
fire_detected = Fire_IsDetected();
door_opened = Door_IsOpen();
yanwu_value = fire_detected ? 100 : 0;
gas_alarm_now = (gas_level > 0) ? 1 : 0;
fire_alarm_now = (yanwu_value >= yanwu_max) ? 1 : 0;
if(gas_alarm_now)
{
gas_alarm_hold_ms = 3000;
gas_alarm_type = gas_level;
auto_valve_locked = 1;
}
if(fire_alarm_now)
{
fire_alarm_hold_ms = 3000;
auto_valve_locked = 1;
}
gas_alarm = (gas_alarm_now || (gas_alarm_hold_ms > 0)) ? 1 : 0;
fire_alarm = (fire_alarm_now || (fire_alarm_hold_ms > 0)) ? 1 : 0;
intrusion_alarm = (security_enabled && door_opened) ? 1 : 0;
if(!gas_alarm)
{
gas_alarm_type = 0;
}
}
/****
******* 鏄剧ず鍑芥暟
*****/
void Display_function(void)
{
static uint8_t door_display_state = 0xFF;
static uint8_t fire_display_state = 0xFF;
static uint8_t last_display_page = 0xFF;
uint8_t current_door_state = 0;
uint8_t current_fire_state = 0;
if(last_display_page != flag_display)
{
door_display_state = 0xFF;
fire_display_state = 0xFF;
last_display_page = flag_display;
}
switch(flag_display)
{
case 0:
Oled_ShowCHinese(1, 0, "温度");
sprintf(display_buf, ":%2dC", temp);
Oled_ShowString(1, 4, display_buf);
Oled_ShowCHinese(2, 0, "湿度");
sprintf(display_buf, ":%2d%%", humi);
Oled_ShowString(2, 4, display_buf);
Oled_ShowCHinese(3, 0, "防盗模式");
if(security_enabled)
{
Oled_ShowCHinese(3, 4, "开");
}
else
{
Oled_ShowCHinese(3, 4, "关");
}
if(intrusion_alarm)
{
Oled_ShowCHinese(4, 0, "入侵报警");
}
else if(fire_alarm)
{
Oled_ShowCHinese(4, 0, "火灾报警");
}
else
{
Oled_ShowCHinese(4, 0, "可燃气体");
sprintf(display_buf, ":%2d%%", MQ_value);
Oled_ShowString(4, 8, display_buf);
if(gas_alarm_type >= 2)
{
Oled_ShowCHinese(4, 6, "超标");
}
else if(gas_alarm_type == 1)
{
Oled_ShowCHinese(4, 6, "漏气");
}
else
{
Oled_ShowCHinese(4, 6, "正常");
}
}
break;
case 1:
Oled_ShowCHinese(1, 0, "排风");
if(ExhaustFan_Get())
{
Oled_ShowCHinese(1, 2, "开");
}
else
{
Oled_ShowCHinese(1, 2, "关");
}
if(flag_mode == 0)
{
Oled_ShowCHinese(1, 6, "自动");
}
else
{
Oled_ShowCHinese(1, 6, "手动");
}
Oled_ShowCHinese(2, 0, "燃气阀");
if(ServoValve_IsClosed())
{
Oled_ShowCHinese(2, 3, "关");
}
else
{
Oled_ShowCHinese(2, 3, "开");
}
current_door_state = door_opened ? (security_enabled ? 2 : 1) : 0;
if(door_display_state != current_door_state)
{
if(current_door_state == 2)
{
Oled_ShowCHinese(3, 0, "门磁入侵报警");
}
else if(current_door_state == 1)
{
Oled_ShowCHinese(3, 0, "门磁正常出入");
}
else
{
Oled_ShowCHinese(3, 0, "门磁关");
Oled_ShowString(3, 6, " ");
}
door_display_state = current_door_state;
}
current_fire_state = fire_alarm ? 1 : 0;
if(fire_display_state != current_fire_state)
{
if(current_fire_state)
{
Oled_ShowCHinese(4, 0, "火灾报警");
}
else
{
Oled_ShowCHinese(4, 0, "火焰正常");
}
fire_display_state = current_fire_state;
}
break;
case 2:
Oled_ShowCHineseMode(1, 0, "温度阈值", set_count == 1);
sprintf(display_buf, ":%2d", temp_max);
Oled_ShowStringMode(1, 8, display_buf, set_count == 1);
Oled_ShowCHineseMode(2, 0, "湿度阈值", set_count == 2);
sprintf(display_buf, ":%2d", humi_max);
Oled_ShowStringMode(2, 8, display_buf, set_count == 2);
Oled_ShowCHineseMode(3, 0, "漏气阈值", set_count == 3);
sprintf(display_buf, ":%2d", gas_leak_th);
Oled_ShowStringMode(3, 8, display_buf, set_count == 3);
Oled_ShowCHineseMode(4, 0, "超标阈值", set_count == 4);
sprintf(display_buf, ":%2d", gas_over_th);
Oled_ShowStringMode(4, 8, display_buf, set_count == 4);
break;
default:
break;
}
}
/****
******* 绠$悊鍑芥暟
*****/
void Manage_function(void)
{
if(gas_alarm || fire_alarm)
{
ExhaustFan_Set(1);
Update_Valve_Output(1);
auto_valve_locked = 1;
}
else
{
if(flag_mode == 0)
{
ExhaustFan_Set(0);
if(auto_valve_locked)
{
Update_Valve_Output(1);
}
else
{
Update_Valve_Output(0);
}
}
else
{
ExhaustFan_Set(manual_fan_on);
}
}
if(intrusion_alarm || gas_alarm || fire_alarm || temp > temp_max || humi > humi_max || humi < humi_min)
{
BEEP = !BEEP;
beepflag = 1;
}
else
{
BEEP = 0;
beepflag = 0;
}
}
/****
******* 瀹氭椂鍣ㄤ腑鏂湇鍔″嚱鏁?*****/
void TIM4_IRQHandler(void)
{
static uint16_t count = 0, count1 = 0;
if(TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
g_tick_ms++;
if(gas_alarm_hold_ms > 0)
{
gas_alarm_hold_ms--;
}
if(fire_alarm_hold_ms > 0)
{
fire_alarm_hold_ms--;
}
if(count++ > 500)
{
count = 0;
shuaxing = 1;
}
if(count1++ > 2000)
{
count1 = 0;
sendyu_flag = 1;
}
if((g_tick_ms % 5000u) == 0u)
{
g_report_5s_flag = 1;
}
}
}
六、包含内容

七、资料分享
资料获取:请查看主页介绍搜索或观看开源视频获取