登录/注册

基于stm32F429的温湿度监测系统

基于stm32F429的温湿度监测系统

更多
我们计划使用STM32F429开发板,搭配温湿度传感器(例如DHT11或DHT22)来设计一个温湿度监测系统。系统将实时采集环境的温度和湿度,并通过显示屏(如LCD)显示,同时可以通过串口将数据发送到电脑。此外,我们还可以考虑添加报警功能,当温度或湿度超过设定阈值时,通过LED或蜂鸣器报警。 步骤: 1. 硬件选择: - 主控:STM32F429ZIT6(Discovery开发板自带) - 温湿度传感器:DHT11(数字输出,单总线协议) - 显示屏:STM32F429 Discovery板载LCD(240x320分辨率) - 串口:使用USART1通过USB转串口与PC通信 - 报警:板载LED和蜂鸣器(如果没有蜂鸣器,可以用LED代替) 2. 软件设计: - 开发环境:STM32CubeIDE - 使用HAL库进行开发 - 需要编写DHT11的驱动、LCD显示驱动、串口通信以及主程序逻辑 3. 功能实现: a. 初始化系统时钟、外设(GPIO、USART、LCD等) b. 初始化DHT11传感器(配置单总线GPIO) c. 循环读取DHT11的温湿度数据(注意DHT11的最小读取间隔为1秒) d. 将读取到的数据在LCD上实时显示 e. 同时通过串口发送到PC(可以使用串口助手查看) f. 设置阈值(例如温度上限30℃,湿度上限80%),当超过阈值时,触发报警(LED闪烁,蜂鸣器鸣叫) 4. 代码结构: - main.c:主循环,协调各个模块 - dht11.c / dht11.h:DHT11驱动 - lcd.c / lcd.h:LCD显示驱动(可以使用CubeMX生成的LCD驱动,并在此基础上修改) - uart.c / uart.h:串口初始化及发送函数 下面我们分别实现各个部分。 注意:由于DHT11是单总线协议,需要精确的时序,因此建议使用延时函数和状态机来读取数据。同时,由于DHT11对时序要求严格,在读取数据时最好关闭中断,或者使用硬件定时器来保证时序。 由于代码较长,我们将分模块编写。 首先,我们使用STM32CubeMX配置硬件: - 时钟配置:使用外部晶振,系统时钟180MHz - 配置一个GPIO作为DHT11的数据线(例如PG9,设置为输出模式,同时也可以读取输入) - 配置USART1:异步模式,波特率115200 - 配置LCD:STM32F429 Discovery板载LCD控制器(LTDC)和触摸屏(我们这里不用触摸),以及背光控制引脚。 - 配置报警LED(例如PG13, PG14)和蜂鸣器(如果板子上有,比如PB4) 然后生成代码。 由于CubeMX已经生成了LCD的初始化代码,我们只需要在生成的代码基础上添加显示内容的函数。 接下来,我们编写DHT11的驱动: 在dht11.h中: ```c #ifndef DHT11_H_ #define DHT11_H_ #include "stm32f4xx_hal.h" typedef struct { float temperature; float humidity; } DHT11_Data; void DHT11_Init(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); uint8_t DHT11_Read(DHT11_Data *data); #endif ``` 在dht11.c中: ```c #include "dht11.h" #include "main.h" #include "tim.h" // 可能需要使用定时器 #define DHT11_PIN_LOW() HAL_GPIO_WritePin(GPIOx, GPIO_Pin, GPIO_PIN_RESET) #define DHT11_PIN_HIGH() HAL_GPIO_WritePin(GPIOx, GPIO_Pin, GPIO_PIN_SET) #define DHT11_PIN_READ() HAL_GPIO_ReadPin(GPIOx, GPIO_Pin) static GPIO_TypeDef* GPIOx; static uint16_t GPIO_Pin; void DHT11_Init(GPIO_TypeDef* gpio, uint16_t pin) { GPIOx = gpio; GPIO_Pin = pin; // 初始化时先拉高 DHT11_PIN_HIGH(); } // 微秒级延时,使用HAL_Delay()只能到ms,所以需要自己实现一个微秒延时 // 由于系统时钟为180MHz,我们可以使用定时器或循环来实现 // 这里使用循环实现(不精确,但DHT11允许一定误差) static void delay_us(uint32_t us) { uint32_t delay = (HAL_RCC_GetHCLKFreq() / 8000000) * us; // 粗略估计,需要根据实际情况调整 while (delay--) { __NOP(); } } uint8_t DHT11_Read(DHT11_Data *data) { uint8_t bytes[5] = {0}; uint8_t i, j; // 主机发送开始信号:拉低至少18ms,然后拉高20-40us DHT11_PIN_LOW(); HAL_Delay(20); // 拉低20ms DHT11_PIN_HIGH(); delay_us(30); // 主机拉高20-40us // 配置为输入模式,等待DHT11响应 GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = GPIO_Pin; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(GPIOx, &GPIO_InitStruct); // 等待DHT11拉低(响应信号) delay_us(40); if (DHT11_PIN_READ() != GPIO_PIN_RESET) { return 1; // 第一步响应失败 } delay_us(80); if (DHT11_PIN_READ() != GPIO_PIN_SET) { return 2; // 第二步响应失败 } // 开始接收数据 for (i = 0; i < 5; i++) { for (j = 0; j < 8; j++) { // 等待低电平结束(每个位开始前有50us低电平) while (DHT11_PIN_READ() == GPIO_PIN_RESET); // 高电平持续26-28us表示0,70us表示1 delay_us(35); // 等待35us后判断 if (DHT11_PIN_READ() == GPIO_PIN_SET) { bytes[i] |= (1 << (7 - j)); // 等待高电平结束(如果是1,则高电平总共70us,已经过了35us,再等35us) while (DHT11_PIN_READ() == GPIO_PIN_SET); } } } // 恢复为输出模式 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; HAL_GPIO_Init(GPIOx, &GPIO_InitStruct); DHT11_PIN_HIGH(); // 校验和 if (bytes[4] != (bytes[0] + bytes[1] + bytes[2] + bytes[3])) { return 3; // 校验失败 } // 数据转换 data->humidity = bytes[0] + bytes[1] * 0.1; data->temperature = bytes[2] + bytes[3] * 0.1; return 0; // 成功 } ``` 注意:上面的微秒延时函数`delay_us`是粗略的,实际中可能需要根据系统时钟调整。更精确的做法是使用定时器。 然后,我们编写LCD显示部分。由于CubeMX已经生成了LCD的初始化代码,我们只需要在lcd.c和lcd.h中添加显示温湿度的函数。 在lcd.h中: ```c #ifndef LCD_H_ #define LCD_H_ #include "stm32f4xx_hal.h" #include "stm32f429i_discovery_lcd.h" void LCD_Init(void); void LCD_DisplayTemperatureHumidity(float temp, float hum); #endif ``` 在lcd.c中: ```c #include "lcd.h" void LCD_Init(void) { BSP_LCD_Init(); BSP_LCD_LayerDefaultInit(0, LCD_FB_START_ADDRESS); BSP_LCD_SelectLayer(0); BSP_LCD_Clear(LCD_COLOR_BLACK); BSP_LCD_SetFont(&Font16); BSP_LCD_SetBackColor(LCD_COLOR_BLACK); BSP_LCD_SetTextColor(LCD_COLOR_WHITE); } void LCD_DisplayTemperatureHumidity(float temp, float hum) { char str[40]; BSP_LCD_Clear(LCD_COLOR_BLACK); sprintf(str, "Temperature: %.1f C", temp); BSP_LCD_DisplayStringAt(0, LINE(1), (uint8_t *)str, CENTER_MODE); sprintf(str, "Humidity: %.1f %%", hum); BSP_LCD_DisplayStringAt(0, LINE(2), (uint8_t *)str, CENTER_MODE); } ``` 接下来,编写串口发送函数(在uart.c中): ```c #include "uart.h" #include UART_HandleTypeDef huart1; // 假设CubeMX生成的USART1句柄 void UART_Init(void) { // 在CubeMX中已经初始化,这里可以留空或添加其他配置 } void UART_SendString(char *str) { HAL_UART_Transmit(&huart1, (uint8_t *)str, strlen(str), HAL_MAX_DELAY); } void UART_SendTemperatureHumidity(float temp, float hum) { char buffer[50]; int len = sprintf(buffer, "Temperature: %.1f C, Humidity: %.1f %%\r\n", temp, hum); HAL_UART_Transmit(&huart1, (uint8_t *)buffer, len, HAL_MAX_DELAY); } ``` 在uart.h中: ```c #ifndef UART_H_ #define UART_H_ #include "stm32f4xx_hal.h" void UART_Init(void); void UART_SendString(char *str); void UART_SendTemperatureHumidity(float temp, float hum); #endif ``` 最后,在主函数中整合: ```c #include "main.h" #include "dht11.h" #include "lcd.h" #include "uart.h" // 定义阈值 #define TEMP_THRESHOLD 30.0 #define HUM_THRESHOLD 80.0 DHT11_Data dht11_data; uint8_t dht11_status; int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART1_UART_Init(); MX_LTDC_Init(); // 如果CubeMX生成了LTDC初始化 // 初始化外设 LCD_Init(); UART_Init(); DHT11_Init(GPIOG, GPIO_PIN_9); // 假设DHT11接在PG9 // 报警LED初始化(使用板载LED) // 在CubeMX中已经初始化,这里直接使用 // LED1: PG13, LED2: PG14 while (1) { dht11_status = DHT11_Read(&dht11_data); if (dht11_status == 0) { // 读取成功,显示并发送 LCD_DisplayTemperatureHumidity(dht11_data.temperature, dht11_data.humidity); UART_SendTemperatureHumidity(dht11_data.temperature, dht11_data.humidity); // 检查是否超过阈值 if (dht11_data.temperature > TEMP_THRESHOLD || dht11_data.humidity > HUM_THRESHOLD) { // 报警:LED1和LED2闪烁,蜂鸣器响(如果有) HAL_GPIO_WritePin(GPIOG, GPIO_PIN_13, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOG, GPIO_PIN_14, GPIO_PIN_SET); // 如果蜂鸣器,则打开蜂鸣器 // HAL_GPIO_WritePin(BUZZER_GPIO_Port, BUZZER_Pin, GPIO_PIN_SET); HAL_Delay(500); HAL_GPIO_WritePin(GPIOG, GPIO_PIN_13, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOG, GPIO_PIN_14, GPIO_PIN_RESET); // HAL_GPIO_WritePin(BUZZER_GPIO_Port, BUZZER_Pin, GPIO_PIN_RESET); } else { // 正常状态,关闭报警 HAL_GPIO_WritePin(GPIOG, GPIO_PIN_13, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOG, GPIO_PIN_14, GPIO_PIN_RESET); } } else { // 读取失败,显示错误 char str[30]; sprintf(str, "DHT11 Error: %d", dht11_status); BSP_LCD_Clear(LCD_COLOR_BLACK); BSP_LCD_DisplayStringAt(0, LINE(1), (uint8_t *)str, CENTER_MODE); } HAL_Delay(2000); // 每次读取间隔至少1秒,这里2秒 } } ``` 注意:以上代码是简化版,实际中需要根据硬件连接修改引脚,并且可能需要调整时序和延时。另外,报警部分可以根据实际硬件添加蜂鸣器控制。 由于DHT11读取对时序要求严格,如果发现读取不稳定,可以考虑使用定时器来精确控制时序,或者在读取期间关闭中断。 以上就是一个基于STM32F429的温湿度监测系统的基本框架。实际开发中可能需要调试和优化。

以下是一个基于STM32F429的温湿度监测系统的设计方案,包含硬件选型、软件实现和关键代码:

一、系统组成

  1. 核心控制器:STM32F429ZIT6(带FPU和DSP指令,内置LCD控制器)
  2. 温湿度传感器:DHT22(AM2302)
    • 测量范围:温度-40~80℃ ±0.5℃,湿度0~100%RH ±2%
    • 单总线数字接口
  3. 显示模块:2.4寸TFT LCD(320x240分辨率,通过FSMC接口驱动)
  4. 报警模块:LED指示灯 + 蜂鸣器
  5. 通信接口:USB转串口(用于PC数据监控)

二、硬件连接

外设 STM32F429引脚 功能说明
DHT22 PG9 单总线数据线
TFT LCD FSMC接口 使用Bank1区域
LED报警灯 PG13 温度超标指示
蜂鸣器 PG14 湿度超标报警
USB转串口 PA9/PA10 USART1通信

三、软件设计(使用HAL库)

1. DHT22驱动代码

// dht22.h
typedef struct {
  float temperature;
  float humidity;
} DHT22_Data;

void DHT22_Init(void);
uint8_t DHT22_Read(DHT22_Data *data);
// dht22.c
#include "dht22.h"
#include "tim.h"  // 使用TIM2做精确延时

#define DHT22_PIN  GPIO_PIN_9
#define DHT22_PORT GPIOG

void DHT22_Init() {
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  __HAL_RCC_GPIOG_CLK_ENABLE();
  GPIO_InitStruct.Pin = DHT22_PIN;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(DHT22_PORT, &GPIO_InitStruct);
  HAL_GPIO_WritePin(DHT22_PORT, DHT22_PIN, GPIO_PIN_SET);
}

uint8_t DHT22_Read(DHT22_Data *data) {
  uint8_t bytes[5] = {0};
  uint32_t timeout;

  // 主机启动信号
  HAL_GPIO_WritePin(DHT22_PORT, DHT22_PIN, GPIO_PIN_RESET);
  HAL_Delay(1);  // 至少1ms低电平
  HAL_GPIO_WritePin(DHT22_PORT, DHT22_PIN, GPIO_PIN_SET);

  // 切换输入模式
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  GPIO_InitStruct.Pin = DHT22_PIN;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(DHT22_PORT, &GPIO_InitStruct);

  // 等待响应
  timeout = 0;
  while (HAL_GPIO_ReadPin(DHT22_PORT, DHT22_PIN)) {
    if (++timeout > 100) return 1; // 超时
    HAL_Delay(1);
  }

  // 数据采集(省略具体时序代码)
  // ... 实现40位数据读取逻辑

  // 校验和验证
  if (bytes[4] != (bytes[0] + bytes[1] + bytes[2] + bytes[3])) 
    return 2;

  // 数据转换
  data->humidity = (bytes[0] << 8 | bytes[1]) / 10.0;
  data->temperature = (bytes[2] << 8 | bytes[3]) / 10.0;

  return 0;
}

2. 主程序逻辑

// main.c
#include "stm32f4xx_hal.h"
#include "lcd.h"
#include "dht22.h"
#include "usart.h"

#define TEMP_THRESHOLD 35.0   // 温度报警阈值
#define HUM_THRESHOLD  80.0   // 湿度报警阈值

int main(void) {
  HAL_Init();
  SystemClock_Config();
  MX_USART1_UART_Init();
  LCD_Init();
  DHT22_Init();

  // 报警灯初始化
  __HAL_RCC_GPIOG_CLK_ENABLE();
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  GPIO_InitStruct.Pin = GPIO_PIN_13 | GPIO_PIN_14;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

  DHT22_Data sensor_data;
  char disp_buf[40];

  while (1) {
    if (DHT22_Read(&sensor_data) == 0) {
      // LCD显示
      sprintf(disp_buf, "Temp: %.1fC", sensor_data.temperature);
      LCD_DisplayString(10, 50, (uint8_t *)disp_buf);
      sprintf(disp_buf, "Hum: %.1f%%", sensor_data.humidity);
      LCD_DisplayString(10, 70, (uint8_t *)disp_buf);

      // 串口输出
      printf("Temperature: %.1fC\tHumidity: %.1f%%\r\n", 
             sensor_data.temperature, sensor_data.humidity);

      // 报警判断
      HAL_GPIO_WritePin(GPIOG, GPIO_PIN_13, 
        (sensor_data.temperature > TEMP_THRESHOLD) ? GPIO_PIN_SET : GPIO_PIN_RESET);

      HAL_GPIO_WritePin(GPIOG, GPIO_PIN_14, 
        (sensor_data.humidity > HUM_THRESHOLD) ? GPIO_PIN_SET : GPIO_PIN_RESET);
    }
    HAL_Delay(2000);  // 每2秒采集一次
  }
}

四、关键实现要点

  1. 精确时序控制

    • 使用硬件定时器(TIM2)实现微秒级延时
    • 单总线通信期间关闭中断保证时序
  2. 数据显示优化

    // 在LCD上绘制温度曲线
    static int16_t temp_history[120];
    static uint8_t index = 0;
    
    // 存储并绘制
    temp_history[index] = (int16_t)(sensor_data.temperature * 10);
    LCD_DrawGraph(10, 100, temp_history, 120, LCD_COLOR_RED);
    index = (index + 1) % 120;
  3. 低功耗设计

    • 采集间隔期间进入STOP模式
    • 使用RTC唤醒功能
      HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);

五、系统功能扩展

  1. 添加SD卡存储:使用FATFS记录历史数据
  2. 网络传输:通过ESP8266模块上传云平台
  3. 手机APP监控:开发蓝牙/BLE连接应用
  4. 多节点组网:通过RS485构建分布式监测网络

六、调试建议

  1. 使用逻辑分析仪验证DHT22时序
  2. 通过STM32-STLINK实时监测变量
  3. 添加看门狗防止死机
    IWDG_HandleTypeDef hiwdg;
    void IWDG_Init(void) {
     hiwdg.Instance = IWDG;
     hiwdg.Init.Prescaler = IWDG_PRESCALER_256;
     hiwdg.Init.Reload = 4095;
     HAL_IWDG_Init(&hiwdg);
    }
    // 主循环中定期喂狗
    HAL_IWDG_Refresh(&hiwdg);

实际开发中需注意:

  1. DHT22需加10K上拉电阻
  2. 长距离传输时使用屏蔽线
  3. 避免阳光直射传感器
  4. LCD显示使用双缓冲防止闪烁

这个系统可实现高精度环境监测,采样率2秒/次,温度分辨率0.1℃,湿度分辨率0.1%RH,适合温室大棚、仓库、实验室等场景。

库房温湿度监测系统

不适宜的温湿度条件不仅影响货物品质,还可能引发安全事故。例如,湿度过高可能导致霉菌滋生,电路短路,或温度过低引起的液体冻结膨胀等,都可能对仓库设施及货物造成损害。库房

2025-01-06 16:37:32

LORA无线温湿度监测系统

LORA无线温湿度监测系统,作为现代环境监测技术的重要组成部分,正日益受

2024-11-07 16:57:40

温湿度监测系统应用

、可靠的温湿度监测系统显得尤为重要。 温湿度

2024-07-26 16:15:59

STM32F429参考手册中文版

STM32F429参考手册中文版

资料下载 ah此生不换 2022-01-26 13:48:08

STM32F429开发板用户手册】第14章 STM32F429的电源,复位和时钟系统

【STM32F429开发板用户手册】第14章 STM32F429的电源,复位和时钟系统

资料下载 佚名 2021-12-08 15:51:10

STM32F429开发板用户手册】第8章 STM32F429的终极调试组件Event Recorder

【STM32F429开发板用户手册】第8章 STM32F429的终极调试组件Event Recorder

资料下载 佚名 2021-12-04 14:06:04

STM32F429开发板用户手册】第1章 初学STM32F429的准备工作

【STM32F429开发板用户手册】第1章 初学STM32F429的准备工作

资料下载 麻酱 2021-12-04 13:51:04

STM32F429开发板底板的电路原理图免费下载

本文档的主要内容详细介绍的是STM32F429开发板底板的电路原理图免费下载。

资料下载 佚名 2020-08-29 15:40:42

库房温湿度自动监测系统

仓储、库房在管理上,环境控制都是重中之重。库房温湿度自动监测系统作为一种更为便捷的解决方案,已经得到广泛的应用。 库房

2024-07-09 18:00:43

温湿度监测系统解决方案应用场景

随着生活水平质量不断提高,因温度引发的各行业越来越重视产品生产、物品设备、存储等温湿度管理环境。科学应用温湿度监测

2024-01-24 16:21:34

大型冷库温湿度监测系统方案

这是一个无线WIFI遍布社会大小角落的时代,小到居民楼,大到工厂,甚至在公交上都有随时可连的WIFI。 大型冷库温湿度监测系统是一个专门用于保障

2023-09-14 16:22:00

基于单片机和LabVIEW的温湿度监测系统设计

利用单片机和虚拟仪器LabVIEW在PC端设计了温湿度测量及控制系统,用于温湿度数据监

2023-06-09 14:02:42

基于STM32温湿度采集系统设计

①利用stm32对DHT11模块进行数据采集②将采集到的温湿度数据上云(本次实验并未成功上云)二、实验环境硬件:STM32F407ZGT6、DH

2021-08-10 08:17:55

求一种温湿度监测系统的设计方案

温湿度监测系统的工作原理是什么?如何去设计温湿度

2021-05-13 06:23:37

库房无线温湿度监控方案 无线温湿度监控系统 仓储物流无线温湿度

数据传输得到广泛的应用,GPRS通信技术以其不需要架设通信线路、组网灵活方便、覆线数据传输系统中越来越被重视。为此,盛世科技提出了一种基于GPRS的环境温湿度

2021-03-01 10:15:19
7天热门专题 换一换
相关标签