FEATURED · 精选文章

基于STM32的智能安防与燃气监测系统设计实战

发布时间 / 2026/9/18 11:43:53
来源 / 创域科博编辑部
栏目 / 资讯中心
基于STM32的智能安防与燃气监测系统设计实战 去年冬天的一个晚上我在厨房热牛奶转身去客厅拿了个东西回来时整个厨房已经弥漫着一股焦糊味——锅烧干了。那一刻我就在想如果有个东西能在我离开时盯着燃气和火情该多好。后来我花了两周时间用STM32做了一整套智能安防与燃气监测系统从原理图设计、代码编写到Proteus仿真验证全部开源出来。这篇文章把整个项目的设计思路、关键电路、代码逻辑和调试过程中踩过的坑完整记录下来给同样想做嵌入式项目或者准备参加电赛、毕设的同学一个可以直接复现的参考。1. 系统需求拆解安防和燃气监测到底要做什么动手画原理图之前我先把需求一条条列清楚。很多人做项目上来就画图写代码做到一半发现功能之间互相冲突再回头改就很痛苦。这个系统的核心场景是家庭厨房和入户区域需要同时解决两个问题一是燃气泄漏的实时监测与告警二是非法入侵的探测与报警。1.1 功能需求清单燃气浓度实时采集超过阈值立即声光报警人体红外感应检测到非法闯入时触发报警支持布防/撤防切换白天在家时关掉入侵报警晚上睡觉或外出时开启报警状态通过OLED屏幕和指示灯直观显示蜂鸣器声音告警同时预留继电器接口控制电磁阀切断燃气或启动排风扇这里有个容易忽略的点燃气报警和入侵报警是两套完全不同的逻辑。燃气监测必须全天候工作不管你是否布防而入侵报警只有在布防状态下才需要响应。所以代码里不能简单用一个全局标志位控制所有报警输出必须把两条逻辑链分开设计。1.2 系统框图设计整个系统的数据流向是这样的燃气传感器和人体红外传感器的模拟量/数字量信号进入STM32的GPIO和ADC引脚经过内部逻辑判断后输出到蜂鸣器、LED指示灯、继电器和OLED屏幕。同时通过按键输入实现人机交互设定布防状态。从开发顺序上我建议先做燃气监测这条链路再做入侵报警最后整合到一起。因为燃气监测涉及ADC采集、阈值判断、模拟量校准链路更长先跑通它能把底层的驱动代码框架定下来。1.3 供电方案的取舍系统供电我设计了两种方式USB 5V直接供电以及通过AMS1117-3.3稳压芯片降压给主控和传感器供电。燃气传感器MQ-2的加热丝需要5V供电这一点特别容易踩坑——如果你只给传感器供3.3V加热温度不够输出数据会严重漂移甚至完全检测不到气体。所以原理图上传感器的VCC必须接5V而它输出的模拟量信号经过分压后进入STM32的ADC引脚3.3V容忍度以内这个匹配关系要提前算清楚。2. 硬件选型与原理图设计的关键节点核心主控我选了STM32F103C8T6也就是俗称的“蓝丸”核心板。原因很简单性价比极高、资料最多、引脚够用、ADC资源丰富。这个项目用到1路ADC、若干GPIO、I2C和定时器中断C8T6的资源配置完全够用没必要上F407这种更大的芯片。2.1 传感器选型MQ-2还是MQ-5燃气传感器我对比了MQ-2和MQ-5。MQ-2对丙烷、丁烷、液化石油气灵敏度高MQ-5对天然气甲烷更敏感。考虑到国内家庭燃气管道以天然气为主同时部分场景还在用液化气罐我最终选了MQ-2做通用方案响应范围更宽。如果项目定位是天然气专用检测换成MQ-5只需要改一下引脚配置代码里的校准逻辑完全通用。人体红外传感器选了HC-SR501这个模块内置了BISS0001芯片能把热释电红外探头输出的微弱信号放大并处理成数字电平输出直接接STM32的GPIO即可。模块上有两个可调电位器一个调感应距离一个调延时时间。实测下来感应距离调到中间位置约5米延时调到最左端约3秒适合安防场景。2.2 原理图设计的几个关键节点电源电路VIN 5V ──┬── AMS1117-3.3 ── 3.3V ── STM32 VDD │ ├── MQ-2 VCC5V直接供电 │ └── 去耦电容 100uF 100nF这里需要注意去耦电容的放置100uF电解电容放在电源入口100nF陶瓷电容尽量靠近STM32的VDD引脚。MQ-2的加热丝启动瞬间电流接近150mA如果电源设计余量不足会导致3.3V电压跌落单片机直接复位。实测下来USB供电时这个问题不明显但如果用劣质充电宝供电启动瞬间确实出现过复位现象后来加了100uF电容解决。燃气传感器输出电路MQ-2的模拟输出AO引脚内部是一个分压电路输出阻抗较高直接进STM32的ADC会影响采样精度。我加了一级RC低通滤波1kΩ电阻串联 0.1uF电容到地截止频率约1.6kHz有效滤除工频干扰和传感器本身的高频抖动。ADC采样率不需要很快20Hz就够了。继电器驱动电路继电器控制用的是S8050三极管驱动继电器的线圈端并联了一个1N4007续流二极管。这个二极管是必须的——继电器断电瞬间线圈会产生反向电动势如果不接续流二极管高压脉冲会沿着GPIO引脚打进去轻则单片机死机重则烧毁引脚。我见过不止一个新手在这个地方翻车原理图里已经加上了。OLED屏幕用的I2C接口SDA和SCL分别接PB7和PB6加了4.7kΩ上拉电阻。虽然STM32内部有上拉但OLED模块在长线连接时还是需要外部上拉保证信号质量。2.3 原理图复查清单个人经验所有IC的电源引脚都有0.1uF去耦电容复位引脚接了10kΩ上拉电阻和0.1uF电容到地BOOT0用10kΩ下拉到GND确保从Flash启动按键电路接了下拉电阻不是直接悬空配合软件内部上拉双保险蜂鸣器用的有源蜂鸣器加了三极管驱动没有直接用GPIO推3. 核心代码架构状态机驱动的安防逻辑代码是整个系统的大脑。我没有用简单的顺序轮询方式而是设计了一个轻量级状态机这样后期增加传感器或者修改报警逻辑时不用大改代码结构。3.1 工程文件组织SmartSecurity/ ├── Core/ │ ├── Inc/ │ └── Src/ ├── Drivers/ │ ├── BSP/ │ │ ├── bsp_adc.c // ADC采集与滤波 │ │ ├── bsp_oled.c // OLED显示驱动 │ │ ├── bsp_key.c // 按键扫描 │ │ ├── bsp_buzzer.c // 蜂鸣器控制 │ │ └── bsp_relay.c // 继电器控制 │ └── CMSIS/ ├── App/ │ ├── app_main.c // 主循环状态机 │ ├── app_gas_alarm.c // 燃气报警逻辑 │ └── app_intrusion_alarm.c // 入侵报警逻辑 └── MDK-ARM/分层的基本思路是BSP层只做寄存器操作不包含业务逻辑App层负责决策不直接操作硬件。这样以后想把系统迁移到其他STM32型号只需要改BSP层App层几乎不用动。3.2 燃气报警的核心逻辑燃气报警这部分的代码逻辑是这样的void Gas_Alarm_Process(void) { uint16_t adc_value ADC_GetValue(); float voltage adc_value * 3.3f / 4096.0f; float gas_concentration MQ2_Calibrate(voltage); if (gas_concentration GAS_ALARM_THRESHOLD) { if (system_state.buzzer_enable STATE_ON) { Buzzer_On(); Relay_Close(); // 关闭电磁阀 OLED_ShowGasAlarm(); } } else { Buzzer_Off(); Relay_Open(); } }关键点在于MQ2_Calibrate这个函数。MQ-2的浓度-电压曲线在双对数坐标上是近似线性的但精确标定需要多点校准。作为低成本方案我用了简化的经验公式float MQ2_Calibrate(float voltage) { // RL10kΩVCC5V根据厂商手册拟合曲线 float rs_ro (5.0f - voltage) / voltage; return pow(10.0f, (log10(rs_ro) - 1.02f) / -0.23f); }这个公式的系数来自MQ-2手册的典型曲线实测下来能区分“正常/疑似泄漏/严重泄漏”三个等级但精确到百分比浓度是不现实的。如果项目需要定量检测建议用MOX传感器专用的标定气体做多点标定。3.3 按键扫描与状态切换按键处理的坑在于误触发和卡键。我没有用最简单的延时消抖而是用定时器中断做10ms周期扫描连续3次读到相同电平才确认按键有效void Key_Scan(void) { static uint8_t stable_count 0; static GPIO_PinState last_state GPIO_PIN_SET; GPIO_PinState current_state HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin); if (current_state last_state) { stable_count; if (stable_count 3) { stable_count 0; if (current_state GPIO_PIN_RESET) { // 按键短按切换布防状态 System_ToggleArmState(); } } } else { last_state current_state; stable_count 0; } }布防状态切换时有一个细节如果当前正在燃气报警中不允许撤防。这个逻辑是必须的我在第一版代码里没加这个限制测试时发现燃气报警期间按键撤防蜂鸣器停了但燃气还在漏。后来改成布防状态与燃气报警状态互斥的判断才把这个问题堵住。3.4 定时器调度框架整个系统用了三个定时器TIM1做1ms时基是系统心跳TIM2做10ms周期扫描按键TIM3做OLED刷新节拍100ms。系统主循环里不做任何延时所有延时都用状态机加计数器实现。这样做的最大好处是燃气采样、按键响应、报警输出互不阻塞一个传感器的异常不会拖垮整个系统。4. Proteus仿真验证在上实物之前先把逻辑跑通仿真的价值不在于替代实物测试而在于把逻辑层的错误在几分钟内暴露出来。我现在每个项目都会先搭一个Proteus仿真环境把主流程跑通再画PCB去打样这样至少能把接线错误和逻辑错误这两类最耗时间的问题提前消灭掉。4.1 仿真环境搭建Proteus里需要准备的元件清单STM32F103C8Proteus 8.9以上版本自带MQ-2模型可以用电位器模拟气体浓度变化HC-SR501模型用按键模拟人体触发OLED 128x64 I2C蜂鸣器模型、LED、按键、电阻有个比较取巧的操作Proteus里没有现成的MQ-2模型我用一个电位器的输出模拟燃气传感器的模拟量信号。电位器输出电压从0V往上调ADC读数跟着变相当于燃气浓度在升高。这样可以验证整个ADC采集和阈值判断链路唯一的差别是没有真实的传感器非线性特性。4.2 仿真中发现的两个问题第一个问题是继电器状态反转。第一版代码里继电器高电平触发但在Proteus中继电器模型默认高电平断开导致报警时电磁阀反而打开了。这个问题在电路图上不容易发现仿真运行时一眼就能看出来逻辑反了改一条代码就能解决。第二个问题是I2C OLED在仿真环境下的时序问题。Proteus对I2C时序的模拟和真实硬件有差异OLED刷新时偶尔会卡死。后来把I2C速率从400kHz降到100kHz解决。实际硬件上100kHz也完全够用OLED显示文本信息不需要高速刷新。4.3 仿真与实物之间的预期管理要说清一件事Proteus仿真通过的代码不代表实物一定没问题。仿真让你验证的是“逻辑正确性”但ADC参考电压偏差、传感器的上电漂移、供电噪声、按键抖动这些都是仿真里不存在的。所以我的建议是仿真阶段把目标定在“主流程能跑通、状态切换符合预期”这个层面不要过度依赖仿真器去调ADC精度或者传感器阈值这些必须在实物上做。5. 实物调试踩坑实录实物调试阶段才是真正让人成长的地方。我把我实际踩过、并且确认能复现的几个坑列出来每个都附上排查过程和修复方案希望你能绕过去。5.1 MQ-2上电漂移一开机就报警刚焊好板子接通电源蜂鸣器立刻开始叫燃气浓度显示值飙得离谱。第一反应是传感器接线有问题拿万用表量了供电5V正常AO输出电压2.8V——按换算公式确实超标。后来查资料才明白MQ-2这类半导体传感器在刚上电的几分钟内内部加热丝还没到稳定工作温度气体敏感层的阻值会剧烈变化输出信号漂移非常大。解决方案分两步硬件上在传感器模块上电后延时30秒再启动ADC采样软件上上电后取前100次采样值的平均值作为基线校准值之后的所有采样都减去这个基线偏移量再和阈值比较。void MQ2_WarmUp(void) { uint32_t total 0; for (uint8_t i 0; i 100; i) { total ADC_GetValue(); HAL_Delay(300); // 100次 * 300ms 30秒 } mq2_baseline total / 100; }这个改动之后冷启动误报问题彻底解决。后续如果环境温湿度变化大还可以定期在确认无燃气泄漏时重新校准基线。5.2 继电器吸合瞬间单片机复位功能测试时发现一个诡异现象继电器每吸合一次OLED屏幕闪一下严重时整个系统重启。测量3.3V电压轨发现继电器吸合的瞬间电压跌落超过300mV持续时间约10ms。原因很简单继电器线圈是感性负载虽然已经加了续流二极管但5V电源轨上的瞬态电流冲击依然造成了压降。修复方案是继电器电路与逻辑电路分开供电用USB 5V直接给继电器供电经过AMS1117稳压后的3.3V只供给MCU和传感器逻辑部分。同时把继电器的GND和逻辑GND单点接地避免地环流串扰。改动之后复位问题完全消失。5.3 HC-SR501人感误触发入侵报警在晚上频繁误报日志显示传感器输出高电平持续几秒。排查后确定是传感器安装位置正对着空调出风口热风导致热释电探头误判。重新调整安装角度并降低灵敏度电位器后问题解决。这个坑提醒了我系统设计时不能只考虑电路和代码安装环境对传感器的影响同样重要。建议在项目文档里增加安装注意事项避免正对窗户/空调/暖气片传感器距地面2-2.5米避免阳光直射。5.4 OLED显示花屏OLED屏幕上电后显示一团乱码有时候重启一次又正常。排查发现是I2C总线上没有接上拉电阻第一版原理图遗漏内部上拉又不稳定导致通信时数据出错。补上4.7kΩ外部上拉后问题消失。如果你也遇到类似的花屏问题先检查I2C上拉和接线长度别急着怀疑代码。6. 开源资料的组织与使用方式开源项目最重要的是让别人能快速跑起来我花了不少心思整理目录和文档。6.1 仓库目录结构SmartSecurity_STM32/ ├── README.md // 项目介绍、功能说明、硬件清单 ├── Hardware/ │ ├── Schematic_PDF/ // 原理图PDF版本直接用阅读器打开 │ ├── Schematic_Source/ // 原理图源文件立创EDA/AD │ └── PCB/ // PCB文件 ├── Firmware/ │ ├── KEIL_Project/ // KEIL工程双击打开即可 │ ├── Src/ // 用户代码 │ └── Inc/ ├── Simulation/ │ └── Proteus/ // Proteus仿真文件 └── Docs/ ├── UserManual.md // 使用说明 └── TestReport.md // 测试记录每个源码文件顶部都加了注释说明函数功能、输入输出和修改注意事项。代码中的关键宏定义集中在app_conf.h中比如报警阈值、ADC采样周期、布防超时时间等改参数不需要翻源码。6.2 复现的最低配置如果你想复现这个项目最低需要以下核心器件器件型号/规格参考数量主控板STM32F103C8T6核心板1燃气传感器MQ-2模块1人体红外HC-SR501模块1显示0.96寸OLED I2C1继电器5V单路继电器模块1蜂鸣器5V有源蜂鸣器1按键轻触开关2稳压芯片AMS1117-3.31三极管S80502总成本控制在60元以内。所有模块都可以在淘宝买到现成的电子新手也能根据原理图自己焊接。6.3 常见问题索引README里我加了一个常见问题表现象可能原因解决方案上电OLED无显示I2C接线错/上拉电阻缺失检查SDA/SCL接线确认上拉报警一直触发传感器未完成预热等待30秒基线校准完成按键无反应按键引脚无上拉确认代码使能内部上拉手机充电宝供电自动重启继电器瞬间电流过大继电器独立供电或换大电流电源7. 如果你要在这个项目上继续扩展做完这个系统后我列了几个扩展方向都是接口设计阶段就预留好的对接WiFi模块在USART1上预留了ESP8266/ESP-01S的接口可以通过AT指令把燃气浓度和报警状态推送到MQTT服务器实现远程报警。参考代码我已经写好了只需要在App层加一个app_mqtt_report.c模块。接入蜂鸣器变音提示通过PWM控制有源蜂鸣器可以模拟消防车的变音告警比单音蜂鸣器更容易引起注意。TIM3的PWM输出通道已经预留。气体浓度历史曲线STM32内部Flash足够存储24小时的采样点数据按1Hz采样率每点4字节断点续传后可以在OLED上回放趋势图。多传感器融合增加DHT11温湿度传感器后可以对MQ-2的基线进行温湿度补偿减少环境变化带来的误报率。补偿公式是典型的多项式拟合我已经验证过效果。如果你有自己的扩展想法欢迎在开源仓库提PR。项目从设计到落地查了不少资料也推翻过一版方案第一版用了纯裸机轮询重构翻倍工作量现在分享出来的这版是整个流程走通后的精华版本。复制源码、打样、烧录、搭好面包板这套安防系统真的可以跑起来关键是你还能完全理解每一条代码和每一根线的来龙去脉。做嵌入式项目就是这样能画出原理图、写得动代码的人很多但能把从需求到仿真的整条链路吃透的人不多。希望这篇记录能帮你少走几个弯路。
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻