STM32的DH11温湿度模块和LED灯的综合实训

直接附上代码,里面有详细的解释

c 复制代码
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "esp_timer.h"
#include "esp_rom_sys.h"
#include <stdlib.h>
#include <time.h>

// DHT11温湿度传感器读取相关定义
#define DHT11_OK 0
#define DHT11_ERROR -1

// 温湿度数据结构
typedef struct {
    int temperature;
    int humidity;
} dht11_data_t;

// 硬件引脚定义
#define DHT_PIN GPIO_NUM_4      // DHT11数据引脚
#define LED1_PIN GPIO_NUM_1     // LED1引脚
#define LED2_PIN GPIO_NUM_2     // LED2引脚
#define LED3_PIN GPIO_NUM_6     // LED3引脚(顺序:1/2/6/5)
#define LED4_PIN GPIO_NUM_5     // LED4引脚(顺序:1/2/6/5)

static const char *TAG = "LEDControlSystem";

// LED控制模式枚举
typedef enum {
    LED_MODE_FLOW = 0,        // 流水灯模式(25度以下)
    LED_MODE_BLINK,           // 同时闪烁模式(25-27度)
    LED_MODE_RANDOM,          // 随机亮着模式(27-29度)
    LED_MODE_FAST_BLINK       // 快速闪烁模式(29度以上)
} led_control_mode_t;

// 温度阈值定义
#define TEMP_THRESHOLD_25 26  // 25度阈值
#define TEMP_THRESHOLD_27 28  // 27度阈值  
#define TEMP_THRESHOLD_29 30  // 29度阈值

// 当前控制模式
static led_control_mode_t current_mode = LED_MODE_FLOW;

// LED初始化函数
static void init_leds(void) {
    gpio_config_t io_conf = {};
    // 禁用中断
    io_conf.intr_type = GPIO_INTR_DISABLE;
    // 设置为输出模式
    io_conf.mode = GPIO_MODE_OUTPUT;
    // 设置引脚掩码(包含4个LED)
    io_conf.pin_bit_mask = (1ULL << LED1_PIN) | (1ULL << LED2_PIN) | 
                          (1ULL << LED3_PIN) | (1ULL << LED4_PIN);
    // 禁用下拉
    io_conf.pull_down_en = 0;
    // 禁用上拉
    io_conf.pull_up_en = 0;
    // 配置GPIO
    gpio_config(&io_conf);
    
    // 初始状态:所有LED熄灭
    gpio_set_level(LED1_PIN, 0);
    gpio_set_level(LED2_PIN, 0);
    gpio_set_level(LED3_PIN, 0);
    gpio_set_level(LED4_PIN, 0);
    
    ESP_LOGI(TAG, "4个LED初始化完成,引脚:GPIO%d, GPIO%d, GPIO%d, GPIO%d", 
             LED1_PIN, LED2_PIN, LED3_PIN, LED4_PIN);
}

// LED控制函数 - 实现三种模式
static void control_leds(led_control_mode_t mode) {
    static int flow_index = 0;  // 流水灯索引
    static int blink_state = 0; // 闪烁状态
    
    switch (mode) {
        case LED_MODE_FLOW:
            // 流水灯模式:LED依次点亮
            gpio_set_level(LED1_PIN, (flow_index == 0) ? 1 : 0);
            gpio_set_level(LED2_PIN, (flow_index == 1) ? 1 : 0);
            gpio_set_level(LED3_PIN, (flow_index == 2) ? 1 : 0);
            gpio_set_level(LED4_PIN, (flow_index == 3) ? 1 : 0);
            
            flow_index = (flow_index + 1) % 4;  // 循环索引
            vTaskDelay(pdMS_TO_TICKS(300));     // 300ms延时
            break;
            
        case LED_MODE_BLINK:
            // 同时闪烁模式:所有LED同时闪烁
            gpio_set_level(LED1_PIN, blink_state);
            gpio_set_level(LED2_PIN, blink_state);
            gpio_set_level(LED3_PIN, blink_state);
            gpio_set_level(LED4_PIN, blink_state);
            
            blink_state = !blink_state;         // 切换状态
            vTaskDelay(pdMS_TO_TICKS(500));     // 500ms延时
            break;
            
        case LED_MODE_RANDOM:
            // 随机亮着模式:随机点亮LED
            gpio_set_level(LED1_PIN, rand() % 2);
            gpio_set_level(LED2_PIN, rand() % 2);
            gpio_set_level(LED3_PIN, rand() % 2);
            gpio_set_level(LED4_PIN, rand() % 2);
            
            vTaskDelay(pdMS_TO_TICKS(400));     // 400ms延时
            break;
            
        case LED_MODE_FAST_BLINK:
            // 快速闪烁模式:所有LED快速闪烁
            gpio_set_level(LED1_PIN, blink_state);
            gpio_set_level(LED2_PIN, blink_state);
            gpio_set_level(LED3_PIN, blink_state);
            gpio_set_level(LED4_PIN, blink_state);
            
            blink_state = !blink_state;         // 切换状态
            vTaskDelay(pdMS_TO_TICKS(100));     // 100ms延时(快速闪烁)
            break;
    }
}

// DHT11温湿度传感器读取函数
static int read_dht11(dht11_data_t *data) {
    uint8_t bits[5] = {0};
    uint8_t cnt = 7;
    uint8_t idx = 0;
    
    // 主机发送开始信号
    gpio_set_direction(DHT_PIN, GPIO_MODE_OUTPUT);
    gpio_set_level(DHT_PIN, 0);
    esp_rom_delay_us(18000);  // 至少18ms低电平
    gpio_set_level(DHT_PIN, 1);
    esp_rom_delay_us(40);     // 20-40us高电平
    
    // 切换到输入模式等待DHT11响应
    gpio_set_direction(DHT_PIN, GPIO_MODE_INPUT);
    
    // 等待DHT11响应信号
    while (gpio_get_level(DHT_PIN) == 1) {
        esp_rom_delay_us(1);
    }
    while (gpio_get_level(DHT_PIN) == 0) {
        esp_rom_delay_us(1);
    }
    while (gpio_get_level(DHT_PIN) == 1) {
        esp_rom_delay_us(1);
    }
    
    // 读取40位数据
    for (int i = 0; i < 40; i++) {
        while (gpio_get_level(DHT_PIN) == 0) {
            esp_rom_delay_us(1);
        }
        
        uint32_t time = 0;
        while (gpio_get_level(DHT_PIN) == 1) {
            esp_rom_delay_us(1);
            time++;
            if (time > 100) break;
        }
        
        if (time > 28) {  // 高电平时间大于28us表示数据位1
            bits[idx] |= (1 << cnt);
        }
        
        if (cnt == 0) {
            cnt = 7;
            idx++;
        } else {
            cnt--;
        }
    }
    
    // 校验数据
    uint8_t sum = bits[0] + bits[1] + bits[2] + bits[3];
    if (sum != bits[4]) {
        return DHT11_ERROR;
    }
    
    data->humidity = bits[0];
    data->temperature = bits[2];
    
    return DHT11_OK;
}

// 根据温度切换LED模式
static void switch_mode_by_temperature(int temperature) {
    led_control_mode_t new_mode;
    
    // 根据温度阈值选择模式
    if (temperature < TEMP_THRESHOLD_25) {
        new_mode = LED_MODE_FLOW;        // 25度以下:流水灯
    } else if (temperature < TEMP_THRESHOLD_27) {
        new_mode = LED_MODE_BLINK;       // 25-27度:同时闪烁
    } else if (temperature < TEMP_THRESHOLD_29) {
        new_mode = LED_MODE_RANDOM;      // 27-29度:随机亮
    } else {
        new_mode = LED_MODE_FAST_BLINK;  // 29度以上:快速闪烁
    }
    
    // 如果模式发生变化,则更新并显示信息
    if (new_mode != current_mode) {
        current_mode = new_mode;
        
        // 显示当前模式信息
        switch (current_mode) {
            case LED_MODE_FLOW:
                ESP_LOGI(TAG, "🌡️ 温度 %d°C → 🎯 流水灯模式", temperature);
                break;
            case LED_MODE_BLINK:
                ESP_LOGI(TAG, "🌡️ 温度 %d°C → ✨ 同时闪烁模式", temperature);
                break;
            case LED_MODE_RANDOM:
                ESP_LOGI(TAG, "🌡️ 温度 %d°C → 🎲 随机亮着模式", temperature);
                break;
            case LED_MODE_FAST_BLINK:
                ESP_LOGI(TAG, "🌡️ 温度 %d°C → ⚡ 快速闪烁模式", temperature);
                break;
        }
    }
}

void app_main(void) {
    ESP_LOGI(TAG, "四路LED温度控制系统启动");
    ESP_LOGI(TAG, "LED引脚:GPIO%d, GPIO%d, GPIO%d, GPIO%d", 
             LED1_PIN, LED2_PIN, LED3_PIN, LED4_PIN);
    ESP_LOGI(TAG, "DHT11引脚:GPIO%d", DHT_PIN);
    ESP_LOGI(TAG, "温度控制模式:");
    ESP_LOGI(TAG, "  <25°C: 🎯 流水灯模式");
    ESP_LOGI(TAG, "25-27°C: ✨ 同时闪烁模式");
    ESP_LOGI(TAG, "27-29°C: 🎲 随机亮着模式");
    ESP_LOGI(TAG, " >29°C: ⚡ 快速闪烁模式");
    
    // 初始化随机数种子
    srand((unsigned int)esp_timer_get_time());
    
    // 初始化LED
    init_leds();
    
    // 温湿度读取和显示控制变量
    static int temp_humid_counter = 0;
    static int last_temperature = -1;  // 上次温度值,初始为-1表示未读取
    static int last_humidity = -1;     // 上次湿度值
    
    while (1) {
        // 每半秒(5次循环)读取一次温湿度
        if (temp_humid_counter >= 5) {  // 5次循环约0.5秒
            dht11_data_t data;
            if (read_dht11(&data) == DHT11_OK) {
                // 只有当温度或湿度发生变化时才更新显示
                if (data.temperature != last_temperature || data.humidity != last_humidity) {
                    ESP_LOGI(TAG, "🌡️ 温度: %d°C, 💧 湿度: %d%%", 
                             data.temperature, data.humidity);
                    
                    // 更新上次值
                    last_temperature = data.temperature;
                    last_humidity = data.humidity;
                }
                
                // 根据温度切换LED模式
                switch_mode_by_temperature(data.temperature);
            } else {
                ESP_LOGW(TAG, "❌ DHT11读取失败");
            }
            temp_humid_counter = 0;
        }
        temp_humid_counter++;
        
        // 控制LED显示当前模式
        control_leds(current_mode);
    }
}
相关推荐
普中科技3 小时前
【普中Hi3861开发攻略--基于鸿蒙OS】-- 第 31 章 WIFI 实验-华为 IoTDA 设备接入
单片机·嵌入式硬件·华为云·鸿蒙·liteos·hi3861·普中科技
酷飞飞5 小时前
GD32F407VE天空星开发板的188数码管
stm32·单片机·嵌入式硬件·mcu·arm
GilgameshJSS6 小时前
STM32H743-ARM例程35-DHCP
c语言·arm开发·stm32·单片机·嵌入式硬件
GilgameshJSS6 小时前
STM32H743-ARM例程34-BootROM
c语言·arm开发·stm32·单片机·嵌入式硬件
robin8611096 小时前
Keil(MDK-ARM)和 STM32CubeIDE对比
arm开发·stm32·嵌入式硬件
烟雨彷徨~~Xun6 小时前
esp8266+dht11传感器实时上报温湿度
单片机·mcu·物联网
La Pulga6 小时前
【STM32】FLASH闪存
android·c语言·javascript·stm32·单片机·嵌入式硬件·mcu
sheepwjl7 小时前
《嵌入式硬件(十九):基于IMX6ULL的SPI操作》
单片机·嵌入式硬件·spi·adxl345
GalaxySpaceX7 小时前
STM32-音频播放
stm32·嵌入式硬件·音视频