基于STM32的冷库智能监控与预警系统设计

举报
DS小龙哥 发表于 2025/06/22 18:35:31 2025/06/22
【摘要】 基于STM32的冷库智能监控与预警系统设计 项目开发背景冷链物流在食品、医药等领域至关重要,冷库作为核心存储节点,其内部温湿度稳定性直接关系产品质量与安全。传统冷库监控多依赖人工巡检或简易仪表,存在响应滞后、数据缺失、无法远程预警等问题。一旦温湿度失控,易导致货物腐败、疫苗失效等重大损失,亟需智能化、实时化的监控手段。随着物联网技术发展,基于嵌入式系统的远程监控方案成为行业趋势。STM32...

基于STM32的冷库智能监控与预警系统设计

项目开发背景

冷链物流在食品、医药等领域至关重要,冷库作为核心存储节点,其内部温湿度稳定性直接关系产品质量与安全。传统冷库监控多依赖人工巡检或简易仪表,存在响应滞后、数据缺失、无法远程预警等问题。一旦温湿度失控,易导致货物腐败、疫苗失效等重大损失,亟需智能化、实时化的监控手段。

随着物联网技术发展,基于嵌入式系统的远程监控方案成为行业趋势。STM32微控制器凭借低功耗、高可靠性及丰富外设接口,为冷库监控终端提供了理想的硬件平台。结合高精度温湿度传感器、无线通信模块与云平台,可构建全天候自动化监控网络,实现从本地预警到远程管理的闭环控制。

本项目旨在设计一套集成环境感知、实时显示、云端交互及智能预警的冷库监控系统,通过华为云物联网平台实现数据汇聚与分析,并借助移动终端进行远程管理。系统将显著提升冷库运维效率,降低人工成本,为易腐物品存储提供精准可靠的技术保障,有效防范质量风险。

设计实现的功能

(1)实时检测冷库内部温湿度:通过SHT30传感器(I2C接口)持续采集温湿度数据。
(2)异常温湿度触发蜂鸣器报警:当温湿度超出预设阈值时,STM32驱动有源蜂鸣器(高电平触发)发出声光警报。
(3)数据上传至华为云物联网平台:通过ESP8266 WiFi模块(MQTT协议)将温湿度数据实时传输至华为云。
(4)OLED实时显示当前环境参数:0.96寸SPI OLED屏动态展示温度、湿度及报警状态。
(5)支持远程查看与报警提示推送:Qt开发手机APP可远程查看实时数据,并在云平台触发异常时接收推送告警。

项目硬件模块组成

(1)主控芯片:STM32F103C8T6
(2)温湿度检测模块:SHT30(I2C接口)
(3)显示模块:0.96寸SPI OLED显示屏
(4)联网模块:ESP8266 WiFi模块(支持MQTT协议)
(5)报警模块:高电平触发有源蜂鸣器
(6)供电模块:DC 5V电源 + AMS1117稳压芯片

设计意义

该冷库智能监控与预警系统的设计意义主要体现在以下几个方面:

该系统通过高精度SHT30传感器实时采集冷库温湿度数据,结合STM32主控芯片的稳定处理能力,实现了对储藏环境关键参数的精准监测。当温湿度超出预设安全阈值时,系统立即触发蜂鸣器本地声光报警,同时通过ESP8266模块将异常数据经MQTT协议上传至华为云物联网平台。这种双重响应机制大幅降低了因环境失控导致货物变质的风险,尤其对食品、药品等温敏物资的保质存储具有核心保障价值。

系统显著提升了冷库管理效率与响应速度。传统人工巡检方式存在监测盲区和时效滞后问题,而本设计通过OLED屏本地实时显示参数,结合华为云平台的远程数据同步功能,使管理人员可通过Qt开发的手机APP随时随地掌握冷库状态。自动化监控替代了高频次人工巡检,在降低人力成本的同时实现了24小时无间断监管,确保异常情况能在第一时间被发现和处理。

基于物联网架构的数据积累为优化运营提供了决策支持。系统持续上传至云端的历史温湿度数据,可通过华为云平台进行深度分析与可视化呈现。这些数据有助于管理人员识别冷库运行规律,优化制冷设备启停策略以降低能耗,同时为库存周转计划、设备维护周期等关键决策提供数据依据,从而实现冷库的精细化、智能化管理。

系统采用高性价比硬件方案增强了实用性与普适性。以广泛应用的STM32F103C8T6作为核心控制器,搭配成熟稳定的SPI OLED、I2C传感器和WiFi通信模块,在保证功能完整性的同时有效控制了硬件成本。本地报警与云端推送的双重保障机制显著提升了系统可靠性,其模块化设计也便于维护升级,特别适合中小型冷库的智能化改造需求,具有较高的工程推广价值。

设计思路

整个系统的设计思路围绕STM32F103C8T6主控芯片展开,通过模块化协作实现冷库环境监控。首先,系统通过I2C总线驱动SHT30温湿度传感器,实时采集冷库内部环境数据。采集频率设置为每2秒一次,确保数据的时效性,同时避免频繁操作导致的资源浪费。

采集到的温湿度数据通过SPI接口传输至0.96寸OLED显示屏,动态刷新显示当前参数值、系统状态及报警提示。显示内容采用分层设计,主界面展示实时温湿度,次级界面可查看历史报警记录。若温湿度超出预设安全阈值,STM32立即通过GPIO引脚输出高电平触发有源蜂鸣器,发出持续声光报警直至参数恢复正常。

为实现云端交互,STM32通过UART串口与ESP8266 WiFi模块通信。采用AT指令集建立WiFi连接后,系统将温湿度数据封装为JSON格式,基于MQTT协议定时上传至华为云物联网平台。平台预设规则引擎,当检测到异常数据时自动向远程APP推送报警信息,同时STM32本地记录异常事件时间戳。

远程监控功能由Qt开发的手机APP实现,APP订阅华为云MQTT主题,实时接收环境参数更新和报警推送。用户可通过APP界面查看冷库当前状态、历史数据曲线及报警日志,形成完整的远程监控闭环。

供电部分采用DC 5V输入,经AMS1117稳压芯片转换为3.3V系统电压,为STM32、传感器、OLED及ESP8266提供稳定电源。蜂鸣器单独由GPIO直接驱动,确保报警响应优先级。所有硬件模块通过PCB集成,布局时隔离数字与模拟电路,降低信号干扰风险。

框架图

系统框架图

+-----------------------------------------------------------------------------------------+
|                                   冷库智能监控与预警系统                                  |
|                                                                                         |
|  +---------------------+     +-------------------+     +-----------------------------+  |
|  |                     |     |                   |     |                             |  |
|  |    STM32F103C8T6    |<----|   SHT30传感器     |     |  华为云物联网平台            |  |
|  |    (主控制器)        | I2C | (温湿度检测)       |     |  (MQTT协议)                 |  |
|  |                     |---->|                   |     |                             |  |
|  +----------+----------+     +-------------------+     +-------------+---------------+  |
|             ||
|  +----------v----------+     +-------------------+                | MQTT              |
|  |                     | SPI |                   |                | 数据上传           |
|  |   0.96OLED|<----|   显示模块        |                |                    |
|  |  (实时数据显示)      |---->|                   |     +----------+---------------+  |
|  +---------------------+     +-------------------+     |                          |  |
|             |                                          |    Qt开发手机APP          |  |
|  +----------v----------+     +-------------------+     |  (远程查看/报警推送)      |  |
|  |                     | GPIO|                   |     |                          |  |
|  |  有源蜂鸣器          |<----|   报警模块        |     +--------------------------+  |
|  | (高电平触发报警)     |---->|                   |                                |  |
|  +---------------------+     +-------------------+                                |  |
||  |
|  +----------+----------+     +-------------------+     +---------------------+    |  |
|  |                     | UART|                   |     |                     |    |  |
|  |   ESP8266 WiFi模块  |<----|   联网模块        |---->|  互联网              |----+  |
|  | (MQTT连接华为云)    |---->|                   |     |                     |        |
|  +---------------------+     +-------------------+     +---------------------+        |
|                                                                                         |
|  +-----------------------------------+                                                  |
|  |           供电模块                |                                                  |
|  |  DC 5V电源 → AMS1117稳压(3.3V)   |                                                  |
|  |  (供电: STM32/传感器/模块)        |                                                  |
|  +-----------------------------------+                                                  |
+-----------------------------------------------------------------------------------------+

核心交互说明:

  1. 主控中心

    • STM32F103C8T6:协调所有模块,处理数据逻辑与报警判断。
  2. 数据采集与执行

    • SHT30:通过I2C向STM32发送实时温湿度数据。
    • 蜂鸣器:当温湿度异常时,STM32通过GPIO输出高电平触发报警。
    • OLED屏:STM32通过SPI协议驱动,显示温湿度/报警状态。
  3. 云端通信

    • ESP8266:通过UART接收STM32指令,以MQTT协议将数据上传至华为云。
    • 华为云:存储数据并推送报警至手机APP。
  4. 远程交互

    • Qt手机APP:订阅华为云数据,实时查看参数并接收报警推送。
  5. 供电系统

    • 5V电源经AMS1117稳压至3.3V,为所有模块供电。

系统总体设计

系统总体设计

系统以STM32F103C8T6微控制器为核心,通过其丰富的外设接口协调各模块工作。温湿度检测由SHT30传感器实现,采用I2C通信协议与主控芯片连接,实时采集冷库环境数据。采集到的数据通过SPI接口驱动的0.96寸OLED显示屏进行本地可视化显示,直观呈现当前温湿度数值及系统状态。

异常处理机制通过GPIO控制实现:当温湿度超出预设阈值时,STM32触发高电平信号驱动有源蜂鸣器发出声光报警。数据上传功能依托ESP8266 WiFi模块完成,该模块通过UART串口与主控通信,基于MQTT协议将温湿度数据实时传输至华为云物联网平台,确保远程可访问性。

远程监控由Qt开发的手机APP实现,该APP对接华为云平台接口,可实时查看冷库环境参数。当云平台检测到异常数据时,主动向APP推送报警通知,实现跨地域预警。系统供电采用DC 5V外部电源输入,经AMS1117稳压芯片转换为3.3V稳定电压,为所有模块提供可靠电力支持。

系统功能总结

功能描述 实现方式(硬件/软件)
实时检测冷库内部温湿度 SHT30传感器(I2C通信)采集数据,STM32F103C8T6主控处理
异常温湿度触发蜂鸣器报警 STM32控制高电平触发有源蜂鸣器,设定阈值自动响应
数据上传至华为云物联网平台 ESP8266 WiFi模块通过MQTT协议与华为云平台通信
OLED实时显示当前环境参数 0.96寸SPI OLED屏动态刷新温湿度等数据
支持远程查看与报警提示推送 Qt开发手机APP接收华为云数据,实时监控并推送告警消息

设计的各个功能模块描述

主控芯片采用STM32F103C8T6微控制器,作为系统的核心处理单元,负责协调各模块的数据采集、逻辑控制和通信调度。通过其丰富的外设接口实现与其他功能模块的高效交互。

温湿度检测模块使用SHT30传感器,通过I2C总线与主控芯片连接。该传感器实时采集冷库内的温度和湿度数据,具有高精度和快速响应特性,为系统提供准确的环境参数监测基础。

显示模块采用0.96寸SPI接口OLED屏幕,直接与主控芯片连接。该模块实时显示当前温湿度数值、系统状态及报警信息,提供直观的本地监控界面,支持在低温环境下稳定工作。

联网模块基于ESP8266 WiFi模组,通过串口UART与主控芯片通信。该模块运行MQTT协议客户端,实现与华为云物联网平台的安全连接,定时上传温湿度数据并接收云端指令,同时支持远程报警状态推送。

报警模块采用高电平触发的有源蜂鸣器,由主控芯片的GPIO引脚直接驱动。当检测到温湿度超过预设阈值时,主控芯片输出高电平信号触发蜂鸣器鸣响,实现现场声光报警提示。

远程监控功能通过Qt开发的手机APP实现,该APP接入华为云物联网平台,可实时查看冷库温湿度数据曲线。当云端接收到异常报警信号时,APP自动弹出推送通知,确保管理人员及时获知告警信息。

供电模块由DC 5V外部电源输入,经AMS1117-3.3V稳压芯片转换后,为STM32主控芯片、传感器、显示屏及外围电路提供稳定的3.3V工作电压,保证系统在冷库环境中的持续可靠运行。

上位机代码设计

以下是一个基于Qt开发的冷库监控系统上位机代码设计,实现远程数据查看和报警推送功能:

#include <QApplication>
#include <QMainWindow>
#include <QChart>
#include <QChartView>
#include <QLineSeries>
#include <QValueAxis>
#include <QMqttClient>
#include <QLabel>
#include <QPushButton>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QStatusBar>
#include <QMessageBox>
#include <QDateTime>
#include <QSystemTrayIcon>

using namespace QtCharts;

class MainWindow : public QMainWindow {
    Q_OBJECT
public:
    MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) {
        // MQTT客户端配置
        m_client = new QMqttClient(this);
        m_client->setHostname("你的华为云地址");  // 替换实际地址
        m_client->setPort(1883);
        m_client->setClientId("ColdStorageMonitor");
        m_client->setUsername("用户名");         // 华为云用户名
        m_client->setPassword("密码");           // 华为云密码

        // UI初始化
        initUI();
        setupConnections();

        // 系统托盘图标
        m_trayIcon = new QSystemTrayIcon(QIcon(":/icons/app.png"), this);
        m_trayIcon->show();
    }

private slots:
    void connectToBroker() {
        if (m_client->state() == QMqttClient::Disconnected) {
            m_client->connectToHost();
            m_statusLabel->setText("正在连接云平台...");
        } else {
            m_client->disconnectFromHost();
        }
    }

    void updateConnectionStatus() {
        if (m_client->state() == QMqttClient::Connected) {
            m_connectBtn->setText("断开连接");
            m_statusLabel->setText("已连接 | 监听中");
            subscribeTopics();
        } else {
            m_connectBtn->setText("连接云平台");
            m_statusLabel->setText("连接已断开");
        }
    }

    void messageReceived(const QByteArray &message, const QMqttTopicName &topic) {
        const QString content = QString::fromUtf8(message);
        const QString topicName = topic.name();

        if (topicName.endsWith("/sensor/data")) {
            updateSensorData(content);
        } else if (topicName.endsWith("/alarm")) {
            showAlarm(content);
        }
    }

private:
    void initUI() {
        // 主布局
        QWidget *centralWidget = new QWidget(this);
        QVBoxLayout *mainLayout = new QVBoxLayout(centralWidget);

        // 传感器数据显示区
        QHBoxLayout *dataLayout = new QHBoxLayout();
        m_tempLabel = createDataLabel("温度: --°C");
        m_humiLabel = createDataLabel("湿度: --%");
        dataLayout->addWidget(m_tempLabel);
        dataLayout->addWidget(m_humiLabel);

        // 图表初始化
        initChart();

        // 控制按钮
        m_connectBtn = new QPushButton("连接云平台", this);
        QPushButton *historyBtn = new QPushButton("查看历史数据", this);

        // 状态栏
        m_statusLabel = new QLabel("未连接", this);
        statusBar()->addPermanentWidget(m_statusLabel);

        // 布局组装
        mainLayout->addLayout(dataLayout);
        mainLayout->addWidget(new QLabel("温湿度趋势图", this));
        mainLayout->addWidget(m_chartView);
        
        QHBoxLayout *btnLayout = new QHBoxLayout();
        btnLayout->addWidget(m_connectBtn);
        btnLayout->addWidget(historyBtn);
        mainLayout->addLayout(btnLayout);

        setCentralWidget(centralWidget);
        resize(800, 600);
        setWindowTitle("冷库智能监控系统");
    }

    void setupConnections() {
        connect(m_connectBtn, &QPushButton::clicked, this, &MainWindow::connectToBroker);
        connect(m_client, &QMqttClient::stateChanged, this, &MainWindow::updateConnectionStatus);
        connect(m_client, &QMqttClient::messageReceived, this, &MainWindow::messageReceived);
    }

    void subscribeTopics() {
        auto subscription = m_client->subscribe("cold_storage/sensor/data");
        if (!subscription) {
            QMessageBox::critical(this, "错误", "订阅传感器数据失败!");
            return;
        }
        
        subscription = m_client->subscribe("cold_storage/alarm");
        if (!subscription) {
            QMessageBox::critical(this, "错误", "订阅报警信息失败!");
        }
    }

    void initChart() {
        m_chart = new QChart();
        m_tempSeries = new QLineSeries();
        m_humiSeries = new QLineSeries();
        
        m_tempSeries->setName("温度(°C)");
        m_humiSeries->setName("湿度(%)");
        
        m_chart->addSeries(m_tempSeries);
        m_chart->addSeries(m_humiSeries);
        
        QValueAxis *axisX = new QValueAxis();
        axisX->setRange(0, 60);
        axisX->setLabelFormat("%d");
        axisX->setTitleText("时间(分钟)");
        
        QValueAxis *axisY = new QValueAxis();
        axisY->setRange(-20, 30);
        axisY->setTitleText("数值");
        
        m_chart->addAxis(axisX, Qt::AlignBottom);
        m_chart->addAxis(axisY, Qt::AlignLeft);
        
        m_tempSeries->attachAxis(axisX);
        m_tempSeries->attachAxis(axisY);
        m_humiSeries->attachAxis(axisX);
        m_humiSeries->attachAxis(axisY);
        
        m_chartView = new QChartView(m_chart);
        m_chartView->setRenderHint(QPainter::Antialiasing);
    }

    QLabel* createDataLabel(const QString &text) {
        QLabel *label = new QLabel(text, this);
        label->setAlignment(Qt::AlignCenter);
        label->setStyleSheet("font-size: 24px; font-weight: bold;");
        label->setMinimumHeight(60);
        return label;
    }

    void updateSensorData(const QString &data) {
        // 数据格式: "23.5,45.2"
        QStringList values = data.split(',');
        if (values.size() == 2) {
            float temp = values[0].toFloat();
            float humi = values[1].toFloat();
            
            m_tempLabel->setText(QString("温度: %1°C").arg(temp));
            m_humiLabel->setText(QString("湿度: %1%").arg(humi));
            
            // 更新图表
            QDateTime now = QDateTime::currentDateTime();
            qint64 secs = now.toSecsSinceEpoch();
            m_tempSeries->append(secs, temp);
            m_humiSeries->append(secs, humi);
            
            // 保持最近60个数据点
            if (m_tempSeries->count() > 60) {
                m_tempSeries->removePoints(0, m_tempSeries->count() - 60);
                m_humiSeries->removePoints(0, m_humiSeries->count() - 60);
            }
        }
    }

    void showAlarm(const QString &msg) {
        QMessageBox::critical(this, "冷库异常报警", msg);
        
        // 系统托盘通知
        m_trayIcon->showMessage("冷库告警", 
                                msg,
                                QSystemTrayIcon::Critical, 
                                5000);
    }

private:
    QMqttClient *m_client;
    QChart *m_chart;
    QChartView *m_chartView;
    QLineSeries *m_tempSeries;
    QLineSeries *m_humiSeries;
    QLabel *m_tempLabel;
    QLabel *m_humiLabel;
    QLabel *m_statusLabel;
    QPushButton *m_connectBtn;
    QSystemTrayIcon *m_trayIcon;
};

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    
    // 设置应用样式
    a.setStyle("Fusion");
    QPalette palette;
    palette.setColor(QPalette::Window, QColor(240, 240, 240));
    a.setPalette(palette);
    
    MainWindow w;
    w.show();
    return a.exec();
}

#include "main.moc"

关键功能说明:

  1. MQTT通信

    • 使用QtMqtt模块连接华为云物联网平台
    • 订阅传感器数据主题(cold_storage/sensor/data)和报警主题(cold_storage/alarm
  2. 数据可视化

    • 实时显示温湿度数值(大字体标签)
    • 动态折线图展示历史趋势(自动保留最近60个数据点)
  3. 报警处理

    • 弹出警告对话框显示报警详情
    • 系统托盘通知(后台运行时仍可提醒)
  4. 用户界面

    • 连接状态实时显示
    • 响应式布局适配移动设备
    • 历史数据查看入口

使用说明:

  1. 配置华为云参数

    m_client->setHostname("your_iotda_instance_url"); // 华为云地址
    m_client->setUsername("device_id");              // 设备ID
    m_client->setPassword("device_secret");          // 设备密钥
    
  2. 数据格式约定

    • 传感器数据:"温度值,湿度值"(如"-18.5,75.2"
    • 报警信息:纯文本报警描述(如"温度异常! 当前:-2.5°C 阈值:-18°C"
  3. 编译依赖

    • Qt 5.15+ (Core, MQTT, Charts)
    • QtMqtt模块
    • QtCharts模块
  4. 移动端适配

    • 使用响应式布局自动适应屏幕尺寸
    • 触摸友好的控件尺寸
    • 系统通知兼容Android/iOS

模块代码设计

STM32F103C8T6 设备端模块代码设计

#include "stm32f10x.h"
#include <string.h>
#include <math.h>

// OLED引脚定义 (SPI软件模拟)
#define OLED_SCK_PIN   GPIO_Pin_13
#define OLED_SCK_PORT  GPIOC
#define OLED_SDA_PIN   GPIO_Pin_15
#define OLED_SDA_PORT  GPIOC
#define OLED_RST_PIN   GPIO_Pin_14
#define OLED_RST_PORT  GPIOC
#define OLED_DC_PIN    GPIO_Pin_12
#define OLED_DC_PORT   GPIOC

// SHT30引脚定义 (I2C1)
#define SHT30_SCL_PIN  GPIO_Pin_6
#define SHT30_SDA_PIN  GPIO_Pin_7
#define SHT30_PORT     GPIOB
#define SHT30_ADDR     0x44<<1

// 蜂鸣器引脚
#define BUZZER_PIN     GPIO_Pin_0
#define BUZZER_PORT    GPIOA

// ESP8266串口 (USART2)
#define ESP8266_USART  USART2

// 温湿度阈值
#define TEMP_HIGH_ALARM  8.0f
#define TEMP_LOW_ALARM   -5.0f
#define HUMI_HIGH_ALARM  90.0f
#define HUMI_LOW_ALARM   30.0f

// 函数声明
void SystemClock_Config(void);
void GPIO_Config(void);
void I2C_Config(void);
void USART_Config(void);
void OLED_Init(void);
void OLED_WriteCmd(uint8_t cmd);
void OLED_WriteData(uint8_t data);
void OLED_DisplayString(uint8_t x, uint8_t y, char *str);
void SHT30_Init(void);
uint8_t SHT30_ReadData(float *temp, float *humi);
void ESP8266_SendData(float temp, float humi);
void Buzzer_Alert(uint8_t state);

// OLED字体
const uint8_t OLED_FONT[][16] = {/* 字库数据省略 */};

int main(void) {
    SystemClock_Config();
    GPIO_Config();
    I2C_Config();
    USART_Config();
    OLED_Init();
    SHT30_Init();
    
    float temperature, humidity;
    char disp_buf[20];
    
    while (1) {
        if (SHT30_ReadData(&temperature, &humidity) == 0) {
            // OLED显示
            sprintf(disp_buf, "Temp:%.1fC", temperature);
            OLED_DisplayString(0, 0, disp_buf);
            sprintf(disp_buf, "Humi:%.1f%%", humidity);
            OLED_DisplayString(0, 2, disp_buf);
            
            // 异常报警判断
            if (temperature > TEMP_HIGH_ALARM || temperature < TEMP_LOW_ALARM || 
                humidity > HUMI_HIGH_ALARM || humidity < HUMI_LOW_ALARM) {
                Buzzer_Alert(1);  // 触发蜂鸣器
                OLED_DisplayString(0, 4, "ALARM!!!");
            } else {
                Buzzer_Alert(0);
                OLED_DisplayString(0, 4, "Normal   ");
            }
            
            // 数据上传云端
            ESP8266_SendData(temperature, humidity);
        }
        Delay(3000);  // 3秒更新周期
    }
}

// 系统时钟配置 (72MHz HSE)
void SystemClock_Config(void) {
    RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN;
    RCC->CR |= RCC_CR_HSEON;
    while (!(RCC->CR & RCC_CR_HSERDY));
    FLASH->ACR |= FLASH_ACR_LATENCY_2;
    RCC->CFGR |= RCC_CFGR_PLLMULL9 | RCC_CFGR_PLLSRC_HSE;
    RCC->CR |= RCC_CR_PLLON;
    while (!(RCC->CR & RCC_CR_PLLRDY));
    RCC->CFGR |= RCC_CFGR_SW_PLL;
    while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);
}

// GPIO初始化
void GPIO_Config(void) {
    // 蜂鸣器(PA0)
    GPIOA->CRL &= ~(0x0F << 0);
    GPIOA->CRL |= 0x02 << 0;  // 推挽输出
    
    // OLED引脚(PC12-PC15)
    GPIOC->CRH &= ~(0xFFFF << 0);
    GPIOC->CRH |= 0x2222 << 0;  // 推挽输出
    
    // SHT30引脚(PB6/PB7)
    GPIOB->CRL &= ~(0xFF << 24);
    GPIOB->CRL |= 0x77 << 24;  // 复用开漏
}

// I2C1初始化
void I2C_Config(void) {
    RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
    I2C1->CR1 &= ~I2C_CR1_PE;  // 禁用I2C
    
    I2C1->CR2 = 36;  // APB1时钟36MHz
    I2C1->CCR = 180; // 100kHz: 36M/(2*100k)=180
    I2C1->TRISE = 37; // 1000ns/28ns=35.7->37
    
    I2C1->CR1 |= I2C_CR1_ACK;
    I2C1->CR1 |= I2C_CR1_PE;  // 启用I2C
}

// USART2初始化 (ESP8266)
void USART_Config(void) {
    RCC->APB1ENR |= RCC_APB1ENR_USART2EN;
    GPIOA->CRL |= 0x4B0;  // PA2(TX)复用推挽, PA3(RX)浮空输入
    
    USART2->BRR = 72000000 / 115200;  // 波特率
    USART2->CR1 = USART_CR1_UE | USART_CR1_TE | USART_CR1_RE;
}

// SHT30初始化
void SHT30_Init(void) {
    uint8_t cmd[2] = {0x24, 0x00}; // 高精度测量命令
    while (I2C1->SR2 & I2C_SR2_BUSY);
    
    // 发送起始条件
    I2C1->CR1 |= I2C_CR1_START;
    while (!(I2C1->SR1 & I2C_SR1_SB));
    I2C1->DR = SHT30_ADDR;
    while (!(I2C1->SR1 & I2C_SR1_ADDR));
    (void)I2C1->SR2; // 清除ADDR标志
    
    // 发送命令
    I2C1->DR = cmd[0];
    while (!(I2C1->SR1 & I2C_SR1_TXE));
    I2C1->DR = cmd[1];
    while (!(I2C1->SR1 & I2C_SR1_BTF));
    
    // 停止条件
    I2C1->CR1 |= I2C_CR1_STOP;
}

// 读取SHT30数据
uint8_t SHT30_ReadData(float *temp, float *humi) {
    uint8_t data[6];
    uint16_t raw_temp, raw_humi;
    
    // 发送读取请求
    I2C1->CR1 |= I2C_CR1_START;
    while (!(I2C1->SR1 & I2C_SR1_SB));
    I2C1->DR = SHT30_ADDR | 0x01;
    while (!(I2C1->SR1 & I2C_SR1_ADDR));
    (void)I2C1->SR2;
    
    // 接收数据
    for (uint8_t i = 0; i < 5; i++) {
        while (!(I2C1->SR1 & I2C_SR1_RXNE));
        data[i] = I2C1->DR;
        if (i < 4) I2C1->CR1 |= I2C_CR1_ACK;
        else I2C1->CR1 &= ~I2C_CR1_ACK;
    }
    I2C1->CR1 |= I2C_CR1_STOP;
    while (!(I2C1->SR1 & I2C_SR1_RXNE));
    data[5] = I2C1->DR;
    
    // 数据转换
    raw_temp = (data[0] << 8) | data[1];
    raw_humi = (data[3] << 8) | data[4];
    *temp = -45.0f + 175.0f * (raw_temp / 65535.0f);
    *humi = 100.0f * (raw_humi / 65535.0f);
    
    // CRC校验省略
    return 0;
}

// OLED写命令
void OLED_WriteCmd(uint8_t cmd) {
    OLED_DC_PORT->BRR = OLED_DC_PIN;  // DC=0
    OLED_SDA_PORT->BRR = OLED_SDA_PIN;
    for (uint8_t i = 0; i < 8; i++) {
        OLED_SCK_PORT->BRR = OLED_SCK_PIN;
        if (cmd & 0x80) OLED_SDA_PORT->BSRR = OLED_SDA_PIN;
        else OLED_SDA_PORT->BRR = OLED_SDA_PIN;
        OLED_SCK_PORT->BSRR = OLED_SCK_PIN;
        cmd <<= 1;
    }
}

// OLED显示字符串
void OLED_DisplayString(uint8_t x, uint8_t y, char *str) {
    // 定位显示位置
    OLED_WriteCmd(0xB0 + y);
    OLED_WriteCmd(((x & 0xF0) >> 4) | 0x10);
    OLED_WriteCmd(x & 0x0F);
    
    while (*str) {
        for (uint8_t i = 0; i < 16; i++) {
            OLED_WriteData(OLED_FONT[*str - 32][i]);
        }
        str++;
    }
}

// ESP8266发送数据到华为云
void ESP8266_SendData(float temp, float humi) {
    char mqttMsg[50];
    sprintf(mqttMsg, "AT+MQTTPUB=0,\"dev/data\",\"{temp:%.1f,humi:%.1f}\",0,0\r\n", temp, humi);
    
    for (char *p = mqttMsg; *p; p++) {
        while (!(USART2->SR & USART_SR_TXE));
        USART2->DR = *p;
    }
}

// 蜂鸣器控制
void Buzzer_Alert(uint8_t state) {
    if (state) BUZZER_PORT->BSRR = BUZZER_PIN;
    else BUZZER_PORT->BRR = BUZZER_PIN;
}

代码说明

  1. 系统架构

    • 主控:STM32F103C8T6(72MHz主频)
    • 外设初始化:系统时钟、GPIO、I2C、USART
    • 主循环:3秒采集周期
  2. 关键模块

    • 温湿度采集:SHT30通过I2C通信,高精度模式(0x2400命令)
    • OLED显示:软件SPI驱动,支持ASCII字符显示
    • 报警控制:蜂鸣器高电平触发
    • 云通信:ESP8266通过USART2发送MQTT指令到华为云
    • 数据处理:CRC校验简化处理,实际应用需补全
  3. 通信协议

    • I2C时序:标准模式(100kHz)
    • MQTT消息格式:AT+MQTTPUB=0,"dev/data","{temp:25.5,humi:60.2}",0,0
    • 数据格式:JSON字符串包含温湿度值
  4. 异常处理

    • 温度阈值:-5℃~8℃
    • 湿度阈值:30%~90%
    • 越限时触发蜂鸣器并在OLED显示"ALARM!!!"

注意:实际部署需补充功能

  1. OLED字库完整实现
  2. ESP8266的AT指令响应处理
  3. CRC校验算法(SHT30)
  4. 看门狗和异常复位机制

项目核心代码

#include "stm32f10x.h"
#include "sht30.h"
#include "oled.h"
#include "esp8266_mqtt.h"
#include "buzzer.h"

// 报警阈值定义
#define TEMP_HIGH_ALARM  8.0f
#define TEMP_LOW_ALARM   -5.0f
#define HUMI_HIGH_ALARM  90.0f
#define HUMI_LOW_ALARM   30.0f

// 系统时钟初始化
void RCC_Configuration(void) {
    RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | 
                   RCC_APB2ENR_AFIOEN | RCC_APB2ENR_USART1EN;
    RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
}

// GPIO初始化
void GPIO_Configuration(void) {
    // I2C1 (PB6-SCL, PB7-SDA)
    GPIOB->CRL &= ~(GPIO_CRL_CNF6 | GPIO_CRL_CNF7);
    GPIOB->CRL |= GPIO_CRL_CNF6_1 | GPIO_CRL_CNF7_1;
    GPIOB->CRL |= GPIO_CRL_MODE6 | GPIO_CRL_MODE7;
    
    // USART1 (PA9-TX, PA10-RX)
    GPIOA->CRH &= ~(GPIO_CRH_CNF9 | GPIO_CRH_CNF10);
    GPIOA->CRH |= GPIO_CRH_CNF9_1 | GPIO_CRH_CNF10_0;
    GPIOA->CRH |= GPIO_CRH_MODE9 | GPIO_CRH_MODE10;
    
    // Buzzer (PB8)
    GPIOB->CRH &= ~GPIO_CRH_CNF8;
    GPIOB->CRH |= GPIO_CRH_MODE8;
    GPIOB->ODR &= ~GPIO_ODR_ODR8;
}

// 延时函数
void Delay_ms(uint32_t ms) {
    for(uint32_t i = 0; i < ms * 1000; i++);
}

int main(void) {
    // 初始化系统
    RCC_Configuration();
    GPIO_Configuration();
    SHT30_Init();
    OLED_Init();
    Buzzer_Init();
    ESP8266_Init();
    
    float temperature = 0, humidity = 0;
    uint32_t upload_counter = 0;
    uint8_t alarm_flag = 0;
    
    while(1) {
        // 读取温湿度数据
        if(SHT30_Read(&temperature, &humidity) == 0) {
            // OLED显示
            OLED_Clear();
            OLED_ShowString(0, 0, "Temp:");
            OLED_ShowFloat(40, 0, temperature);
            OLED_ShowString(0, 2, "Humi:");
            OLED_ShowFloat(40, 2, humidity);
            
            // 异常检测
            if(temperature > TEMP_HIGH_ALARM || temperature < TEMP_LOW_ALARM || 
               humidity > HUMI_HIGH_ALARM || humidity < HUMI_LOW_ALARM) {
                Buzzer_On();
                alarm_flag = 1;
                // 发送报警到云平台
                char alarm_msg[50];
                sprintf(alarm_msg, "ALARM! Temp:%.1fC Humi:%.1f%%", temperature, humidity);
                MQTT_Publish("alarm_topic", alarm_msg);
            } else {
                Buzzer_Off();
                alarm_flag = 0;
            }
            
            // 定时上传数据到云平台 (每5秒)
            if(++upload_counter >= 50) {
                char data_msg[50];
                sprintf(data_msg, "Temp:%.1fC,Humi:%.1f%%", temperature, humidity);
                MQTT_Publish("data_topic", data_msg);
                upload_counter = 0;
            }
        }
        
        // 处理云端消息
        if(ESP8266_ReceiveReady()) {
            char cmd[32];
            ESP8266_ReceiveData(cmd, sizeof(cmd));
            if(strstr(cmd, "BUZZER_OFF")) {
                Buzzer_Off();
            }
        }
        
        Delay_ms(100);  // 100ms延时
    }
}

代码说明:

  1. 系统初始化:

    • 配置系统时钟和必要外设时钟(I2C、USART、GPIO)
    • 初始化I2C接口(SHT30传感器)
    • 配置USART串口(ESP8266通信)
    • 设置蜂鸣器控制引脚(PB8)
  2. 主循环功能:

    • 温湿度采集:每100ms通过SHT30获取数据
    • OLED显示:实时显示温湿度数值
    • 异常检测:温度超出[-5°C, 8°C]或湿度超出[30%, 90%]范围时:
      • 触发蜂鸣器报警
      • 立即向华为云发送报警信息
    • 定时上报:每5秒上传一次数据到云端
    • 指令处理:接收云端下发的命令(如"BUZZER_OFF"关闭蜂鸣器)
  3. 关键参数:

    • 使用PB8控制高电平触发蜂鸣器
    • USART1(PA9/PA10)连接ESP8266
    • I2C1(PB6/PB7)连接SHT30
    • 报警阈值通过宏定义可修改
  4. 数据格式:

    • 常规数据:“Temp:XX.XC,Humi:XX.X%”
    • 报警数据:“ALARM! Temp:XX.XC Humi:XX.X%”

注意:实际开发需确保以下驱动文件已实现:

  • sht30.h/c:SHT30传感器驱动
  • oled.h/c:OLED显示驱动
  • esp8266_mqtt.h/c:ESP8266通信及MQTT协议栈
  • buzzer.h/c:蜂鸣器控制驱动

总结

本设计成功构建了一套基于STM32的冷库智能监控与预警系统。系统以STM32F103C8T6为核心控制器,通过SHT30温湿度传感器实现冷库环境参数的精准采集,确保数据实时性与可靠性。异常状态触发有源蜂鸣器本地报警,同时通过ESP8266模块以MQTT协议将数据实时上传至华为云物联网平台,实现云端数据持久化与分析。

OLED显示屏提供本地化人机交互界面,直观展示当前温湿度及系统状态。远程监控功能通过Qt开发的手机APP实现,支持用户随时随地查看冷库状态并接收即时报警推送,大幅提升管理效率。供电模块采用DC 5V电源配合AMS1117稳压芯片,为系统提供稳定高效的能源支持。

整体设计融合了传感技术、物联网通信与移动终端应用,实现了冷库环境的全链路智能化管理。系统具备响应迅速、扩展性强、操作便捷等特点,为冷链仓储安全提供了可靠的技术保障,具有显著的实用价值和推广前景。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。