一、项目概述

本文将详细解析一个基于 STM32L431VCTx 微控制器和 MQ-5 可燃气体传感器的检测实验项目。该项目实现了可燃气体的实时检测功能,并通过 LCD 显示屏和串口两种方式输出检测结果,是物联网嵌入式开发中非常经典的传感器应用案例。

项目亮点

  • 基于 STM32L4 系列低功耗微控制器
  • MQ-5 可燃气体传感器数字量输出检测
  • 240×320 TFT LCD 彩屏实时显示
  • UART 串口数据输出,便于调试
  • LED 状态指示,直观反馈系统运行状态

二、硬件架构

2.1 系统组成

整个系统由三大核心模块组成:主控单元、传感器单元和显示输出单元。

模块器件型号功能说明
主控单元STM32L431VCTxARM Cortex-M4 内核,80MHz 主频,低功耗
气体传感器MQ-5可燃气体检测,数字量输出
显示模块2.4寸 TFT LCD240×320 分辨率,SPI 接口
串口通信USART2115200 波特率,调试数据输出
状态指示LED系统运行状态指示

2.2 MQ-5 传感器简介

MQ-5 是一款常用的可燃气体传感器,对液化气、甲烷、丙烷、氢气等可燃气体具有较高的灵敏度。传感器内部由气敏元件和比较电路组成,当检测到可燃气体浓度超过阈值时,数字输出引脚(DO)会输出低电平信号。

⚠️ 注意事项

  • MQ-5 传感器需要预热 2-3 分钟才能稳定工作
  • 传感器灵敏度可通过板载电位器进行调节
  • 本实验使用数字量输出(DO),模拟量输出(AO)未使用

2.3 引脚连接

传感器与 STM32 的连接方式如下:

MQ-5 引脚STM32 引脚功能说明
VCC5V电源正极
GNDGND电源地
DO(数字输出)PD15气体检测信号输入,上拉输入模式

三、软件架构

3.1 项目目录结构

项目采用标准的 STM32 HAL 库工程结构,核心代码组织如下:

ZHIoT_Sensor_Gas/
├── Src/                  # 应用层源码
│   ├── main.c           # 主程序入口
│   ├── gpio.c           # GPIO 初始化
│   ├── spi.c            # SPI 初始化(LCD用)
│   ├── usart.c          # 串口初始化
│   └── stm32l4xx_it.c   # 中断处理
├── Inc/                  # 应用层头文件
├── Hardware/             # 硬件驱动层
│   ├── MQ_5/            # MQ-5 传感器驱动
│   │   ├── mq_5.c
│   │   └── mq_5.h
│   ├── LCD/             # LCD 显示屏驱动
│   │   ├── lcd.c
│   │   └── lcd.h
│   ├── GUI/             # 图形界面库
│   │   ├── GUI.c
│   │   └── GUI.h
│   ├── ICON/            # 图标资源
│   │   └── gas.h
│   └── HANDLE/          # 业务逻辑处理
│       ├── handle.c
│       └── handle.h
├── Drivers/              # HAL 库驱动
└── MDK-ARM/              # Keil 工程文件

3.2 主程序流程

系统主程序采用经典的初始化 + 超级循环(super loop)架构:

┌─────────────────────────┐
│        系统启动          │
└───────────┬─────────────┘
            │
            ▼
┌─────────────────────────┐
│      HAL_Init()         │
└───────────┬─────────────┘
            │
            ▼
┌─────────────────────────┐
│  SystemClock_Config()   │
└───────────┬─────────────┘
            │
            ▼
┌─────────────────────────┐
│    外设初始化            │
│  LCD / UART / GPIO / MQ5│
│  串口打印欢迎信息        │
└───────────┬─────────────┘
            │
            ▼
┌─────────────────────────┐
│   while(1) 主循环       │
│ MQ5_Handle() 每秒检测   │
└───────────┬─────────────┘
            │
            └───────┐
                    │ 循环
                    ▼
            (回到循环开始)

四、核心代码解析

4.1 MQ-5 传感器驱动

MQ-5 传感器驱动代码非常简洁,主要包含初始化和状态读取两个函数:

// mq_5.h
#ifndef __MQ_5_H
#define __MQ_5_H

#include "stm32l4xx_hal.h"

// 外部函数声明
extern void MQ5_Init(void);
extern uint8_t MQ5_Read_State(void);

#endif

初始化函数配置 PD15 为上拉输入模式:

// mq_5.c
#define MQ5_Pin         GPIO_PIN_15
#define MQ5_GPIO_Port   GPIOD

void MQ5_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;

    __HAL_RCC_GPIOD_CLK_ENABLE();    // 使能GPIOD时钟

    GPIO_InitStruct.Pin = MQ5_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_PULLUP;  // 上拉输入
    HAL_GPIO_Init(MQ5_GPIO_Port, &GPIO_InitStruct);
}

💡 设计要点

使用上拉输入模式的原因:当传感器未检测到气体时,DO 引脚输出高电平;检测到气体时,DO 引脚输出低电平。上拉电阻确保引脚在悬空状态下有确定的电平。返回值 1 表示无可燃气体,0 表示检测到可燃气体。

4.2 主函数实现

主函数完成系统初始化后,进入主循环持续检测气体状态:

// main.c
int main(void)
{
    HAL_Init();                     // HAL 库初始化
    SystemClock_Config();           // 系统时钟配置
    LCD_Display_Init();             // LCD 屏幕初始化显示
    gpio_module_open(LEDS);         // LED GPIO 初始化
    uart_open(uart2, 115200);       // 串口2初始化,波特率115200
    
    printf("\r\n        可燃气体检测实验        \r\n");
    printf("------------------------------\r\n");
    printf("实验开始:\r\n\r\n");
    
    MQ5_Init();                     // MQ-5 传感器初始化
    printf("** 气体传感器初始化\r\n");
    printf("** 读取气体传感器数据\r\n");    

    while(1)
    {      
        MQ5_Handle();               // 气体检测处理函数
    }
}

4.3 业务逻辑处理

MQ5_Handle() 函数是核心业务逻辑,每秒检测一次气体状态并更新显示:

// handle.c
void MQ5_Handle(void)
{
    uint8_t mq5_detect = 0;
    static uint8_t mq2_detect_rev = 3;  // 状态变化标记
    static uint32_t tickstart;
    
    // 每秒检测一次(非阻塞延时)
    if((HAL_GetTick() - tickstart) >= 1000)
    {
        tickstart = HAL_GetTick();  
       
        if(MQ5_Read_State() == 0)  // 检测到可燃气体
        {
            LCD_draw_bmp(96, 120, 48, gImage_yanwu);       // 显示报警图标
            LCD_Fill(85, 178, 140, 194, WHITE);            // 刷新背景
            Show_Str(85, 178, BLUE, WHITE, "有可燃气体", 16, 1);
        }
        else if(MQ5_Read_State() == 1)  // 无可燃气体
        {
            LCD_draw_bmp(96, 120, 48, gImage_yanwu_hui);   // 显示灰色图标
            LCD_Fill(85, 178, 140, 194, WHITE);            // 刷新背景
            Show_Str(85, 178, BLUE, WHITE, "无可燃气体", 16, 1);
        }
        
        mq5_detect = MQ5_Read_State();

        // 状态变化时才输出串口信息,减少串口数据量
        if((!mq5_detect) != mq2_detect_rev)
        {
            printf("** combustible gas detect:%d\r\n", !mq5_detect);
            mq2_detect_rev = !mq5_detect;
        }
        
        led_toggle(LED1_PORT);  // LED 闪烁,表示系统运行中
    }    
}

代码优化技巧

  • 非阻塞延时:使用 HAL_GetTick() 实现秒级定时,不阻塞主循环
  • 状态变化检测:只有当气体状态变化时才输出串口信息,避免冗余数据
  • LED 心跳:LED 每秒翻转一次,直观指示系统运行状态
  • 局部刷新:只刷新状态文本区域,提高显示效率

4.4 LCD 显示初始化

LCD 初始化界面采用蓝白配色,顶部和底部为蓝色标题栏:

// handle.c
void LCD_Display_Init(void)
{ 
    LCD_Init();                          // LCD 硬件初始化
    LCD_Fill(0, lcddev.height-20, lcddev.width, lcddev.height, BLUE);  // 底部蓝条
    LCD_Fill(0, 0, lcddev.width, 20, BLUE);                            // 顶部蓝条
    Gui_StrCenter(0, 2, BLUE, BLUE, " ", 16, 0);                       // 顶部占位
    Gui_StrCenter(0, 40, BLUE, WHITE, "可燃气体检测实验", 24, 1);      // 标题(居中)
    Gui_StrCenter(0, lcddev.height-18, BLUE, BLUE, " ", 16, 0);        // 底部占位
}

五、系统时钟配置

项目使用 STM32L4 的内部高速时钟(HSI)作为时钟源,通过 PLL 倍频到 80MHz 作为系统时钟。以下是关键的时钟配置参数:

时钟域频率说明
HSI16 MHz内部高速时钟,PLL 输入源
SYSCLK80 MHz系统时钟(PLL 输出:16 × 20 / 4 = 80MHz)
HCLK80 MHzAHB 总线时钟,1 分频
PCLK180 MHzAPB1 总线时钟,1 分频
PCLK280 MHzAPB2 总线时钟,1 分频
USART380 MHz串口3时钟源,来自 PCLK1

六、实验现象与调试

6.1 正常现象

  • 上电后 LCD 显示"可燃气体检测实验"标题
  • 传感器预热期间,显示"无可燃气体"
  • LED1 每秒闪烁一次,表示系统正常运行
  • 串口每秒输出一次检测结果(状态变化时)

6.2 测试方法

可以用以下方法测试传感器功能:

  1. 用打火机(不点火)释放少量丁烷气体靠近传感器
  2. 观察 LCD 是否从"无可燃气体"变为"有可燃气体"
  3. 观察串口是否输出检测状态变化
  4. 移开气源后,观察状态是否恢复正常

⚠️ 安全提示

测试时请注意通风,避免可燃气体积聚。不要使用高浓度可燃气体直接对着传感器喷射,以免损坏传感器或造成安全隐患。实验请在老师指导下进行。

6.3 常见问题排查

问题现象可能原因排查方法
LCD 无显示SPI 接线错误 / LCD 初始化失败检查 SPI 接线、确认 LCD 电源正常
传感器一直报警阈值过低 / 传感器损坏调节传感器板载电位器,提高阈值
传感器无反应接线错误 / 预热不足检查 DO 引脚接线,等待 2-3 分钟预热
串口无输出波特率不匹配 / TX/RX 接反确认 115200 波特率,检查串口接线

七、扩展与改进

7.1 功能扩展方向

基于现有框架,可以进一步扩展以下功能:

  • 模拟量采集:使用 ADC 采集 MQ-5 的 AO 引脚,获取气体浓度数值
  • 声光报警:添加蜂鸣器,检测到气体时发出报警声
  • 继电器控制:气体超标时自动启动排气扇或关闭燃气阀门
  • 数据记录:使用 Flash 或 SD 卡记录历史检测数据
  • 物联网上传:通过 WiFi 或 NB-IoT 将数据上传到云平台

7.2 代码优化建议

  • 引入实时操作系统(RTOS),实现多任务调度
  • 增加传感器滤波算法,提高检测稳定性
  • 添加低功耗模式,适合电池供电场景
  • 实现看门狗功能,提高系统可靠性

八、总结

本项目通过 STM32L431VCTx 微控制器和 MQ-5 可燃气体传感器,实现了一个完整的可燃气体检测系统。项目涵盖了 GPIO 输入、SPI 显示、UART 串口通信等多个 STM32 基础外设的使用,是学习嵌入式开发和物联网传感器应用的绝佳实践案例。

通过本实验,我们不仅掌握了 MQ-5 气体传感器的工作原理和使用方法,还学习了如何设计一个完整的嵌入式应用——从硬件连接、驱动编写到业务逻辑实现。希望本文能为你的物联网学习之路提供一些参考和帮助。


标签: #STM32 #MQ-5 #气体传感器 #物联网 #嵌入式开发 #HAL库 #传感器实验

更多推荐