STM32实战:基于STM32F103的智能消防报警联动系统

文章目录

一、前言

1.1 技术背景

火灾是威胁人民生命财产安全的重大隐患,早期预警和快速响应是减少火灾损失的关键。智能消防报警联动系统通过多种传感器实时监测环境参数,在火灾初期及时发出警报并联动相关设备,为人员疏散和火灾扑救争取宝贵时间。

本项目基于STM32F103微控制器,集成烟雾传感器、温度传感器、火焰传感器等多种探测手段,实现火灾检测、声光报警、联动控制等功能,适用于家庭、办公室、仓库等场所。

1.2 应用场景

  • 家庭住宅:厨房烟雾检测,卧室温度监测
  • 办公场所:公共区域火灾预警
  • 仓库厂房:大空间多点监测
  • 学校医院:人员密集场所安全监控

1.3 本文目标

通过本教程,你将学会:

  • MQ-2烟雾传感器数据采集与校准
  • 多传感器数据融合算法
  • 火灾检测算法与阈值判断
  • GSM模块实现短信和电话报警
  • 继电器控制联动设备(喷淋、排烟等)
  • TFT显示屏实时显示监控画面
  • 数据存储与历史记录查询

技术栈:

  • 硬件平台:STM32F103C8T6
  • 烟雾传感器:MQ-2(模拟输出)
  • 温度传感器:DS18B20 + LM35
  • 火焰传感器:红外火焰传感器
  • 声光报警:蜂鸣器 + RGB LED
  • 通信模块:SIM800L GSM模块
  • 显示模块:2.4寸TFT触摸屏
  • 存储:SD卡模块
  • 联动控制:继电器模块

二、环境准备

2.1 硬件清单

器件名称 型号/规格 数量 说明
主控芯片 STM32F103C8T6 1 Blue Pill开发板
烟雾传感器 MQ-2 2 烟雾/可燃气体
温度传感器 DS18B20 2 防水型
火焰传感器 红外型 2 火焰检测
GSM模块 SIM800L 1 短信/电话报警
TFT显示屏 2.4寸 1 ILI9341触摸屏
SD卡模块 SPI接口 1 数据存储
蜂鸣器 有源5V 1 声音报警
RGB LED 共阴极 2 状态指示
继电器 5V四路 1 联动控制
电源 5V/3A 1 系统供电

2.2 硬件连接图

PA0/PA1
PA2/PA3
PA4/PA5
PA9/PA10
PA5-PA7
PB12-PB15
PB0-PB3
STM32F103C8T6
MQ-2烟雾传感器
DS18B20温度
火焰传感器
SIM800L GSM
ILI9345 TFT
SD卡模块
继电器模块

引脚连接表:

STM32引脚 连接设备 功能说明
PA0 MQ-2 #1 ADC输入
PA1 MQ-2 #2 ADC输入
PA2 DS18B20 #1 单总线
PA3 DS18B20 #2 单总线
PA4 火焰传感器 #1 数字输入
PA5 火焰传感器 #2 数字输入
PA6 蜂鸣器 PWM输出
PA7 RGB LED PWM输出
PA9 SIM800L TX UART1 RX
PA10 SIM800L RX UART1 TX
PB0-PB3 继电器 输出控制
PB12 SD CS SPI片选
PB13 SD SCK SPI时钟
PB14 SD MISO SPI数据输入
PB15 SD MOSI SPI数据输出

三、核心实现

3.1 STM32CubeMX配置

时钟配置:

  • HSE Crystal/Ceramic Resonator
  • System Clock: 72MHz

外设配置:

  • ADC1:PA0, PA1,烟雾传感器
  • USART1:PA9(TX), PA10(RX),GSM通信
  • SPI2:PB13(SCK), PB14(MISO), PB15(MOSI),SD卡
  • TIM2:1s定时器,传感器采样
  • TIM3:PWM输出,蜂鸣器
  • GPIO
    • PA2, PA3:开漏输出,DS18B20
    • PA4, PA5:输入,火焰传感器
    • PA6, PA7:PWM输出
    • PB0-PB3:输出,继电器
    • PB12:输出,SD卡片选

3.2 主程序实现

📄 创建文件:Core/Src/main.c

c 复制代码
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Smart Fire Alarm Linkage System
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "usart.h"
#include "spi.h"
#include "tim.h"
#include "gpio.h"
#include "fatfs.h"

/* USER CODE BEGIN Includes */
#include "mq2_sensor.h"
#include "ds18b20.h"
#include "gsm_module.h"
#include "ili9341.h"
#include "sd_card.h"
#include "fire_detector.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/* USER CODE END Includes */

/* Private defines -----------------------------------------------------------*/
#define SENSOR_READ_INTERVAL    1000    // 传感器读取间隔(ms)
#define ALARM_THRESHOLD_SMOKE   300     // 烟雾报警阈值
#define ALARM_THRESHOLD_TEMP    60      // 温度报警阈值(°C)
#define ALARM_CONFIRM_COUNT     3       // 报警确认次数
#define GSM_ALERT_INTERVAL      30000   // GSM报警间隔(ms)
#define DATA_LOG_INTERVAL       60000   // 数据记录间隔(ms)

/* Private typedef -----------------------------------------------------------*/
typedef enum {
    STATUS_NORMAL = 0,
    STATUS_WARNING,
    STATUS_ALARM,
    STATUS_FAULT
} SystemStatus;

typedef enum {
    SENSOR_SMOKE_1 = 0,
    SENSOR_SMOKE_2,
    SENSOR_TEMP_1,
    SENSOR_TEMP_2,
    SENSOR_FLAME_1,
    SENSOR_FLAME_2,
    SENSOR_COUNT
} SensorType;

typedef struct {
    uint8_t type;
    uint16_t value;
    uint8_t alarm;
    uint32_t timestamp;
} SensorData;

/* Private variables ---------------------------------------------------------*/
volatile SystemStatus system_status = STATUS_NORMAL;
volatile SensorData sensors[SENSOR_COUNT];
volatile uint8_t alarm_confirmed = 0;
volatile uint8_t alarm_counter = 0;
volatile uint32_t last_sensor_read = 0;
volatile uint32_t last_gsm_alert = 0;
volatile uint32_t last_data_log = 0;
volatile uint8_t linkage_active = 0;

// 联动设备状态
volatile uint8_t sprinkler_on = 0;
volatile uint8_t exhaust_on = 0;
volatile uint8_t alarm_horn_on = 0;

/* USER CODE BEGIN PV */
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void Read_All_Sensors(void);
static void Process_Fire_Detection(void);
static void Control_Linkage(void);
static void Send_Alert(void);
static void Log_Data(void);
static void Update_Display(void);
static void Set_Alarm_Level(uint8_t level);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */

/**
  * @brief  主函数入口
  */
int main(void)
{
    HAL_Init();
    SystemClock_Config();
    
    MX_GPIO_Init();
    MX_ADC1_Init();
    MX_USART1_UART_Init();
    MX_SPI2_Init();
    MX_TIM2_Init();
    MX_TIM3_Init();
    MX_FATFS_Init();
    
    /* USER CODE BEGIN 2 */
    printf("\\r\\n===== Smart Fire Alarm System =====\\r\\n");
    
    // 初始化TFT显示屏
    printf("Initializing TFT...\\r\\n");
    ILI9341_Init();
    ILI9341_FillScreen(BLACK);
    ILI9341_DrawString(20, 20, "Fire Alarm System", WHITE, BLACK, 2);
    ILI9341_DrawString(20, 60, "Initializing...", WHITE, BLACK, 1);
    HAL_Delay(1000);
    
    // 初始化DS18B20
    printf("Initializing DS18B20...\\r\\n");
    DS18B20_Init();
    
    // 初始化GSM模块
    printf("Initializing GSM...\\r\\n");
    if (GSM_Init() == HAL_OK)
    {
        printf("GSM ready\\r\\n");
        ILI9341_DrawString(20, 80, "GSM: OK", GREEN, BLACK, 1);
    }
    else
    {
        printf("GSM init failed\\r\\n");
        ILI9341_DrawString(20, 80, "GSM: FAIL", RED, BLACK, 1);
    }
    
    // 初始化SD卡
    printf("Initializing SD card...\\r\\n");
    if (SD_Init() == FR_OK)
    {
        printf("SD card ready\\r\\n");
        ILI9341_DrawString(20, 100, "SD Card: OK", GREEN, BLACK, 1);
    }
    else
    {
        printf("SD card init failed\\r\\n");
        ILI9341_DrawString(20, 100, "SD Card: FAIL", RED, BLACK, 1);
    }
    
    // 初始化传感器数据结构
    for (int i = 0; i < SENSOR_COUNT; i++)
    {
        sensors[i].type = i;
        sensors[i].value = 0;
        sensors[i].alarm = 0;
        sensors[i].timestamp = 0;
    }
    
    // 启动定时器
    HAL_TIM_Base_Start_IT(&tim2);
    
    printf("System ready\\r\\n");
    ILI9341_FillScreen(BLACK);
    /* USER CODE END 2 */
    
    /* Infinite loop */
    while (1)
    {
        /* USER CODE BEGIN 3 */
        
        // 读取传感器
        if (HAL_GetTick() - last_sensor_read >= SENSOR_READ_INTERVAL)
        {
            last_sensor_read = HAL_GetTick();
            Read_All_Sensors();
        }
        
        // 火灾检测处理
        Process_Fire_Detection();
        
        // 联动控制
        Control_Linkage();
        
        // 发送报警
        if (system_status == STATUS_ALARM)
        {
            Send_Alert();
        }
        
        // 数据记录
        if (HAL_GetTick() - last_data_log >= DATA_LOG_INTERVAL)
        {
            last_data_log = HAL_GetTick();
            Log_Data();
        }
        
        // 更新显示
        Update_Display();
        
        HAL_Delay(100);
    }
    /* USER CODE END 3 */
}

/**
  * @brief  读取所有传感器数据
  */
static void Read_All_Sensors(void)
{
    // 读取烟雾传感器
    sensors[SENSOR_SMOKE_1].value = MQ2_Read(1);
    sensors[SENSOR_SMOKE_2].value = MQ2_Read(2);
    
    // 读取温度传感器
    sensors[SENSOR_TEMP_1].value = (uint16_t)(DS18B20_ReadTemp(1) * 10);
    sensors[SENSOR_TEMP_2].value = (uint16_t)(DS18B20_ReadTemp(2) * 10);
    
    // 读取火焰传感器
    sensors[SENSOR_FLAME_1].value = HAL_GPIO_ReadPin(FLAME1_GPIO_Port, FLAME1_Pin) == 0 ? 1 : 0;
    sensors[SENSOR_FLAME_2].value = HAL_GPIO_ReadPin(FLAME2_GPIO_Port, FLAME2_Pin) == 0 ? 1 : 0;
    
    // 更新时间戳
    for (int i = 0; i < SENSOR_COUNT; i++)
    {
        sensors[i].timestamp = HAL_GetTick();
    }
    
    printf("Sensors - Smoke1:%d Smoke2:%d Temp1:%.1f Temp2:%.1f Flame1:%d Flame2:%d\\r\\n",
           sensors[SENSOR_SMOKE_1].value,
           sensors[SENSOR_SMOKE_2].value,
           sensors[SENSOR_TEMP_1].value / 10.0,
           sensors[SENSOR_TEMP_2].value / 10.0,
           sensors[SENSOR_FLAME_1].value,
           sensors[SENSOR_FLAME_2].value);
}

/**
  * @brief  火灾检测处理
  */
static void Process_Fire_Detection(void)
{
    uint8_t smoke_alarm = 0;
    uint8_t temp_alarm = 0;
    uint8_t flame_alarm = 0;
    
    // 检查烟雾
    if (sensors[SENSOR_SMOKE_1].value > ALARM_THRESHOLD_SMOKE ||
        sensors[SENSOR_SMOKE_2].value > ALARM_THRESHOLD_SMOKE)
    {
        smoke_alarm = 1;
        sensors[SENSOR_SMOKE_1].alarm = 1;
        sensors[SENSOR_SMOKE_2].alarm = 1;
    }
    else
    {
        sensors[SENSOR_SMOKE_1].alarm = 0;
        sensors[SENSOR_SMOKE_2].alarm = 0;
    }
    
    // 检查温度
    if (sensors[SENSOR_TEMP_1].value > ALARM_THRESHOLD_TEMP * 10 ||
        sensors[SENSOR_TEMP_2].value > ALARM_THRESHOLD_TEMP * 10)
    {
        temp_alarm = 1;
        sensors[SENSOR_TEMP_1].alarm = 1;
        sensors[SENSOR_TEMP_2].alarm = 1;
    }
    else
    {
        sensors[SENSOR_TEMP_1].alarm = 0;
        sensors[SENSOR_TEMP_2].alarm = 0;
    }
    
    // 检查火焰
    if (sensors[SENSOR_FLAME_1].value || sensors[SENSOR_FLAME_2].value)
    {
        flame_alarm = 1;
        sensors[SENSOR_FLAME_1].alarm = 1;
        sensors[SENSOR_FLAME_2].alarm = 1;
    }
    else
    {
        sensors[SENSOR_FLAME_1].alarm = 0;
        sensors[SENSOR_FLAME_2].alarm = 0;
    }
    
    // 多传感器融合判断
    uint8_t alarm_triggered = 0;
    
    if (flame_alarm)
    {
        // 火焰检测直接报警
        alarm_triggered = 1;
    }
    else if (smoke_alarm && temp_alarm)
    {
        // 烟雾+温度双重确认
        alarm_triggered = 1;
    }
    else if (smoke_alarm || temp_alarm)
    {
        // 单一传感器触发,进入预警状态
        if (system_status == STATUS_NORMAL)
        {
            system_status = STATUS_WARNING;
            Set_Alarm_Level(1);
            printf("WARNING: Potential fire detected\\r\\n");
        }
    }
    
    // 报警确认计数
    if (alarm_triggered)
    {
        alarm_counter++;
        if (alarm_counter >= ALARM_CONFIRM_COUNT)
        {
            if (system_status != STATUS_ALARM)
            {
                system_status = STATUS_ALARM;
                alarm_confirmed = 1;
                linkage_active = 1;
                Set_Alarm_Level(3);
                printf("ALARM: Fire confirmed!\\r\\n");
            }
        }
    }
    else
    {
        alarm_counter = 0;
        if (system_status == STATUS_WARNING && !smoke_alarm && !temp_alarm)
        {
            system_status = STATUS_NORMAL;
            Set_Alarm_Level(0);
            printf("Status: Back to normal\\r\\n");
        }
    }
}

/**
  * @brief  联动控制
  */
static void Control_Linkage(void)
{
    if (!linkage_active)
    {
        return;
    }
    
    // 启动喷淋系统
    if (!sprinkler_on)
    {
        HAL_GPIO_WritePin(RELAY1_GPIO_Port, RELAY1_Pin, GPIO_PIN_SET);
        sprinkler_on = 1;
        printf("Linkage: Sprinkler ON\\r\\n");
    }
    
    // 启动排烟系统
    if (!exhaust_on)
    {
        HAL_GPIO_WritePin(RELAY2_GPIO_Port, RELAY2_Pin, GPIO_PIN_SET);
        exhaust_on = 1;
        printf("Linkage: Exhaust ON\\r\\n");
    }
    
    // 启动警报器
    if (!alarm_horn_on)
    {
        HAL_GPIO_WritePin(RELAY3_GPIO_Port, RELAY3_Pin, GPIO_PIN_SET);
        alarm_horn_on = 1;
        printf("Linkage: Alarm horn ON\\r\\n");
    }
}

/**
  * @brief  发送报警信息
  */
static void Send_Alert(void)
{
    if (HAL_GetTick() - last_gsm_alert < GSM_ALERT_INTERVAL)
    {
        return;
    }
    last_gsm_alert = HAL_GetTick();
    
    // 发送短信报警
    char sms_buffer[256];
    sprintf(sms_buffer, 
            "FIRE ALARM! Smoke1:%d Smoke2:%d Temp1:%.1fC Temp2:%.1fC Location:Building A",
            sensors[SENSOR_SMOKE_1].value,
            sensors[SENSOR_SMOKE_2].value,
            sensors[SENSOR_TEMP_1].value / 10.0,
            sensors[SENSOR_TEMP_2].value / 10.0);
    
    GSM_SendSMS("+86138xxxxxxxx", sms_buffer);
    GSM_SendSMS("+86139xxxxxxxx", sms_buffer);
    
    // 拨打电话
    GSM_MakeCall("+86138xxxxxxxx");
    
    printf("Alert sent via GSM\\r\\n");
}

/**
  * @brief  记录数据到SD卡
  */
static void Log_Data(void)
{
    FIL file;
    FRESULT res;
    char buffer[256];
    UINT bytes_written;
    
    // 打开日志文件
    res = f_open(&file, "fire_log.csv", FA_OPEN_APPEND | FA_WRITE);
    if (res != FR_OK)
    {
        printf("Failed to open log file\\r\\n");
        return;
    }
    
    // 写入数据
    sprintf(buffer, "%lu,%d,%d,%.1f,%.1f,%d,%d,%d\\r\\n",
            HAL_GetTick(),
            sensors[SENSOR_SMOKE_1].value,
            sensors[SENSOR_SMOKE_2].value,
            sensors[SENSOR_TEMP_1].value / 10.0,
            sensors[SENSOR_TEMP_2].value / 10.0,
            sensors[SENSOR_FLAME_1].value,
            sensors[SENSOR_FLAME_2].value,
            system_status);
    
    f_write(&file, buffer, strlen(buffer), &bytes_written);
    f_close(&file);
    
    printf("Data logged to SD card\\r\\n");
}

/**
  * @brief  更新TFT显示
  */
static void Update_Display(void)
{
    char buffer[32];
    
    // 根据状态设置背景色
    uint16_t bg_color = BLACK;
    if (system_status == STATUS_ALARM)
    {
        bg_color = (HAL_GetTick() / 500) % 2 == 0 ? RED : BLACK;
    }
    else if (system_status == STATUS_WARNING)
    {
        bg_color = YELLOW;
    }
    
    ILI9341_FillScreen(bg_color);
    
    // 标题
    ILI9341_DrawString(40, 10, "FIRE MONITOR", WHITE, bg_color, 2);
    
    // 状态
    const char* status_str;
    uint16_t status_color;
    switch (system_status)
    {
        case STATUS_NORMAL:
            status_str = "NORMAL";
            status_color = GREEN;
            break;
        case STATUS_WARNING:
            status_str = "WARNING";
            status_color = YELLOW;
            break;
        case STATUS_ALARM:
            status_str = "FIRE ALARM!";
            status_color = RED;
            break;
        default:
            status_str = "UNKNOWN";
            status_color = WHITE;
    }
    ILI9341_DrawString(60, 40, status_str, status_color, bg_color, 2);
    
    // 传感器数据
    sprintf(buffer, "Smoke1: %d", sensors[SENSOR_SMOKE_1].value);
    ILI9341_DrawString(20, 80, buffer, sensors[SENSOR_SMOKE_1].alarm ? RED : WHITE, bg_color, 1);
    
    sprintf(buffer, "Smoke2: %d", sensors[SENSOR_SMOKE_2].value);
    ILI9341_DrawString(20, 100, buffer, sensors[SENSOR_SMOKE_2].alarm ? RED : WHITE, bg_color, 1);
    
    sprintf(buffer, "Temp1: %.1fC", sensors[SENSOR_TEMP_1].value / 10.0);
    ILI9341_DrawString(20, 120, buffer, sensors[SENSOR_TEMP_1].alarm ? RED : WHITE, bg_color, 1);
    
    sprintf(buffer, "Temp2: %.1fC", sensors[SENSOR_TEMP_2].value / 10.0);
    ILI9341_DrawString(20, 140, buffer, sensors[SENSOR_TEMP_2].alarm ? RED : WHITE, bg_color, 1);
    
    sprintf(buffer, "Flame1: %s", sensors[SENSOR_FLAME_1].value ? "YES" : "NO");
    ILI9341_DrawString(140, 80, buffer, sensors[SENSOR_FLAME_1].alarm ? RED : WHITE, bg_color, 1);
    
    sprintf(buffer, "Flame2: %s", sensors[SENSOR_FLAME_2].value ? "YES" : "NO");
    ILI9341_DrawString(140, 100, buffer, sensors[SENSOR_FLAME_2].alarm ? RED : WHITE, bg_color, 1);
    
    // 联动状态
    sprintf(buffer, "Sprinkler: %s", sprinkler_on ? "ON" : "OFF");
    ILI9341_DrawString(20, 180, buffer, sprinkler_on ? GREEN : WHITE, bg_color, 1);
    
    sprintf(buffer, "Exhaust: %s", exhaust_on ? "ON" : "OFF");
    ILI9341_DrawString(20, 200, buffer, exhaust_on ? GREEN : WHITE, bg_color, 1);
}

/**
  * @brief  设置报警级别
  * @param  level: 0=关闭, 1=预警, 2=警告, 3=报警
  */
static void Set_Alarm_Level(uint8_t level)
{
    switch (level)
    {
        case 0:  // 关闭
            HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);
            HAL_GPIO_WritePin(LED_R_GPIO_Port, LED_R_Pin, GPIO_PIN_RESET);
            HAL_GPIO_WritePin(LED_G_GPIO_Port, LED_G_Pin, GPIO_PIN_SET);
            break;
            
        case 1:  // 预警
            HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
            __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 200);
            HAL_GPIO_WritePin(LED_R_GPIO_Port, LED_R_Pin, GPIO_PIN_SET);
            HAL_GPIO_WritePin(LED_G_GPIO_Port, LED_G_Pin, GPIO_PIN_SET);
            break;
            
        case 2:  // 警告
            HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
            __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 500);
            HAL_GPIO_WritePin(LED_R_GPIO_Port, LED_R_Pin, GPIO_PIN_SET);
            HAL_GPIO_WritePin(LED_G_GPIO_Port, LED_G_Pin, GPIO_PIN_RESET);
            break;
            
        case 3:  // 报警
            HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
            __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 800);
            HAL_GPIO_WritePin(LED_R_GPIO_Port, LED_R_Pin, GPIO_PIN_SET);
            HAL_GPIO_WritePin(LED_G_GPIO_Port, LED_G_Pin, GPIO_PIN_RESET);
            break;
    }
}

/**
  * @brief System Clock Configuration
  */
void SystemClock_Config(void)
{
    // 系统时钟配置(由CubeMX生成)
}

void Error_Handler(void)
{
    __disable_irq();
    while (1)
    {
        HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
        HAL_Delay(100);
    }
}

四、测试验证

4.1 传感器测试

测试1:烟雾传感器校准

c 复制代码
void Calibrate_MQ2(void)
{
    printf("MQ2 Calibration - Keep sensor in clean air\\r\\n");
    HAL_Delay(5000);
    
    uint32_t sum = 0;
    for (int i = 0; i < 50; i++)
    {
        sum += MQ2_Read(1);
        HAL_Delay(100);
    }
    
    uint16_t baseline = sum / 50;
    printf("MQ2 Baseline: %d\\r\\n", baseline);
}

测试2:火焰传感器测试

  • 使用打火机在传感器前测试
  • 验证检测距离和响应时间

4.2 报警联动测试

  • 模拟烟雾触发,验证报警流程
  • 检查GSM短信和电话是否正常
  • 验证联动设备是否正确启动

五、故障排查

5.1 常见问题

问题1:MQ-2传感器读数不稳定

解决方案:

  • 预热传感器5-10分钟
  • 添加软件滤波
  • 检查电源稳定性
问题2:GSM模块无法发送短信

解决方案:

  • 检查SIM卡是否欠费
  • 检查信号强度
  • 验证APN设置

六、总结

6.1 核心知识点

  1. 多传感器融合:烟雾+温度+火焰综合判断
  2. 火灾检测算法:阈值判断+确认机制
  3. 联动控制:继电器控制外部设备
  4. GSM通信:短信和电话报警
  5. 数据记录:SD卡存储历史数据

6.2 扩展方向

  • 联网功能:接入物联网平台,远程监控
  • 视频监控:添加摄像头记录现场
  • 语音报警:语音播报疏散提示
  • 消防联动:对接消防系统

6.3 学习资源

相关推荐
ivy159868377152 小时前
CH32V203G6U6 ‌沁恒32位 RISC-V 微控制器(MCU)‌
单片机·嵌入式硬件·risc-v
北山有鸟2 小时前
Linux第一宏:container_of
笔记·嵌入式硬件·学习
blevoice2 小时前
杰理蓝牙音箱开发板AC696N上演示降本设计:AC696N“省晶振”方案配置
单片机·嵌入式硬件·jl杰理蓝牙音频芯片·杰理ac696n开发板·ac6966b蓝牙音响芯片·蓝牙芯片ble透传·杰理蓝牙音箱方案开发
Ww.xh3 小时前
STM32+ESP8266智能农业系统开发指南
stm32·单片机·嵌入式硬件
charlie1145141913 小时前
嵌入式Linux驱动开发(3)——内核模块机制 - Linux 的插件系统
linux·运维·开发语言·驱动开发·嵌入式硬件·学习
yong99903 小时前
在 STC15W201S 上实现 MODBUS RTU 协议
stm32·单片机·嵌入式硬件
xzl043 小时前
瑞萨 FSP 和 STM32 HAL 库的启动流程核心差异
stm32·单片机·嵌入式硬件·rt-thread
芯希望4 小时前
XBLW芯伯乐XBL1507B系列3A 150kHz 40V DC-DC转换器,高效率宽输入电源解决方案
单片机·嵌入式硬件·dc-dc·工业控制·国产替代·电源管理·xblw芯伯乐
不做无法实现的梦~4 小时前
STM32 蜗轮蜗杆电机控制系统设计
stm32·单片机·嵌入式硬件