找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 109|回复: 2
打印 上一主题 下一主题
收起左侧

stm32温湿度检测dht11检测不到温湿度,蜂鸣器不响

[复制链接]
跳转到指定楼层
楼主
ID:1152570 发表于 2025-12-26 09:56 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
50黑币
功能:
基于STM32的简易户外计时系统1硬件组成
1) 核心控制器:STM32F103C6
2) 提醒模块:蜂鸣器 LED
3) 显示模块:LCD1602显示屏
4) 输入模块:按键
5) 温湿度模块:DHT11
2核心功能
1)计时功能:使用TIM来实现精确的计时与倒计时。
2)提醒功能:在倒计时结束的时候,LED与蜂鸣器同时启动提醒倒计时结束。
3)控制功能:一个按键控制正计时功能的启停,一个按键设置倒计时时间与控制倒计时开始。
4)启停功能:启动按键实现系统的一键启停。
5)探测户外环境功能:使用DHT11获取环境的温湿度,在LCD上显示,为户外活动提供参考。

main.c
#include "stm32f10x.h"
#include "stdio.h"
#include "led.h"
#include "key.h"
#include "LCD1602.h"
#include "tim.h"
#include "delay.h"
#include "dht11.h"
#include "buzzer.h"
#include "main.h"
#include "usart.h"
#include "stm32f1xx_hal_msp.h"

// 全局变量
int time_able=0;          // 系统总控制,0-停止 1-运行
int time_set = 10;        // 倒计时默认设定值(秒)
int time_ing_down = 10;    // 倒计时剩余值(秒)
int time_ing_up = 0;      // 正计时累计值(秒)
int time_lms = 0;         // 毫秒累计,1ms+1次
int time_led = 0;         // LED闪烁定时(毫秒)
int up_run_flag = 0;      // 正计时启停标志,0-停止 1-运行
int down_run_flag = 0;    // 倒计时启停标志,0-停止 1-运行

// 温湿度相关变量
u8 temperature = 0;                 // 温度值(℃)
u8 humidity = 0;                    // 湿度值(%)
u32 dht11_read_timer = 0;           // DHT11读取计时器(1ms递增)
u32 dht11_last_read_time = 0;       // 上次读取DHT11的时间戳
char display_buffer[17];            // 显示缓冲区

// 中断测试变量
volatile u32 interrupt_count = 0;  // 中断计数器

// LED和蜂鸣器控制变量
volatile u32 alarm_countdown = 0;  // 蜂鸣器倒计时
volatile u8 alarm_triggered = 0;   // 蜂鸣器触发标志

// 按键3相关变量
volatile u8 key3_pressed = 0;       // 按键3按下标志
volatile u32 key3_hold_time = 0;     // 按键3按住时间(ms)
volatile u32 key3_last_change = 0;   // 上次改变倒计时值的时间(ms)

// 定时器2中断服务函数,1ms执行一次
void tim2_IRQ(void)
{
    // 清除并检查定时器2更新中断标志,继续
  //  if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
   // {
        time_lms++;
                        //        dht11_read_timer++;
        // 系统总控制启动时的计时逻辑
        if(time_able == 1)
        {
            // ---------------- 倒计时逻辑 ----------------
            if(down_run_flag == 1 && time_ing_down > 0)
            {
                if(time_lms >= 10) // 累计1000ms=1秒
                {
                    time_lms = 0;
                    time_ing_down--;
                                                                          dht11_read_timer--;
                    // 倒计时结束,启动LED和蜂鸣器提醒
                    if(time_ing_down == 0)
                    {
                        time_led = 10; // LED亮100ms(0.1秒)
                        alarm_triggered = 1; // 触发蜂鸣器标志
                        alarm_countdown = 14; // 蜂鸣器响1.4秒(3次)
                        down_run_flag = 0; // 倒计时停止
                        time_ing_down=10;
                    }
                }
            }
                                                         

            // ---------------- 正计时逻辑 ----------------
            if(up_run_flag == 1)
            {
                if(time_lms >= 10) // 累计1000ms=1秒
                {
                    time_lms = 0;
                    time_ing_up++;
                                                                          dht11_read_timer++;
                    if(time_ing_up >= 10) time_ing_up = 99; // 上限保护
                }
            }
        }
        else
        {
            // 系统停止时,毫秒计数器清零,防止残留
            time_lms = 0;
                                          up_run_flag = 0;
            down_run_flag = 0;
            time_ing_up = 0;
            time_ing_down = 10;
            time_led = 0;
            LED_OFF();
        }

        // LED闪烁逻辑
        if(time_led > 0)
        {
            LED_ON();  // time_led>0时LED亮
            time_led--;
        }
        else
        {
            LED_OFF(); // time_led=0时LED灭
        }

        // 蜂鸣器提醒逻辑(非阻塞)
        if(alarm_countdown > 0)
        {
            alarm_countdown--;
            // 每40ms为一个周期:前20ms响,后20ms停
            if(alarm_countdown % 4 < 2)
            {
                BUZZER_ON();
            }
            else
            {
                BUZZER_OFF();
            }
        }
        else
        {
            BUZZER_OFF();
            // 重置标志
            if(time_led == 0)
            {
                alarm_triggered = 0;
            }
        }

        // 清除中断标志,继续
      //  TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
  //  }
}

int main(void)
{

    // 外设初始化
    delay_init();              // 延时函数初始化
    KEY_Init();                // 按键初始化
    LED_Init();                // LED初始化
    Buzzer_Init();             // 蜂鸣器初始化
    LCD_init();                // LCD初始化
    DHT11_Init();              // DHT11初始化
    tim2_init(100, 7200-1);       // 定时器2初始化,1ms中断

    // LCD初始化显示

    LCD1602_showstring(0, 0, "UP:000s DN:010s"); // 第一行:计时
  //  LCD1602_showstring(0, 1, "T:00 C H:00 %");  // 第二行:温湿度
    while (1)
    {
        // ---------------- 按键处理逻辑 ----------------
        // 按键1:系统全局启停控制,启停
        if(KEY1 == 0)
        {
            Delay_ms(20); // 消抖
            if(KEY1 == 0)
            {
                time_able = !time_able; // 切换启停状态
                if(time_able == 0) // 停止时,清零所有状态
                {
                    up_run_flag = 0;
                    down_run_flag = 0;
                    time_ing_up = 0;
                    time_ing_down = 10;
                    time_led = 0;
                    LED_OFF();
                }
                while(KEY1 == 0); // 等待按键释放
            }
        }

        // 按键2:正计时启停,系统运行时才有效
        if(KEY2 == 0 && time_able == 1)
        {
            Delay_ms(20); // 消抖
            if(KEY2 == 0)
            {
                up_run_flag = !up_run_flag; // 切换正计时启停
                if(up_run_flag == 1 && time_ing_up == 0)
                {
                    time_ing_up = 0; // 正计时重置为0
                }
                while(KEY2 == 0); // 等待按键释放
            }
        }

        // 按键3:长按调节倒计时时间,松开开始倒计时,系统运行时才有效
        if(KEY3 == 0 && time_able == 1)
        {
            Delay_ms(20); // 消抖
            if(KEY3 == 0)
            {
                if(key3_pressed == 0) // 刚按下
                {
                    key3_pressed = 1;
                    key3_hold_time = 0;
                    key3_last_change = 0;
                    down_run_flag = 0; // 暂停倒计时
                }
            }
        }

        // 按键3处理逻辑
        if(key3_pressed == 1)
        {
            // 在主循环中按键按住时间每10ms增加一次
            key3_hold_time += 10;

            // 长按每秒增加倒计时时间
            if(key3_hold_time - key3_last_change >= 100) // 每秒增加
            {
                key3_last_change = key3_hold_time;
                time_set++;
                if(time_set > 99) time_set = 99; // 上限999秒
                time_ing_down = time_set; // 更新显示值
            }

            // 按键释放检测
            if(KEY3 == 1)
            {
                if(key3_hold_time < 50) // 短按(小于500ms)
                {
                    // 如果倒计时正在运行,则暂停;如果暂停,则开始
                    if(down_run_flag == 1)
                    {
                        down_run_flag = 0; // 暂停倒计时
                    }
                    else
                    {
                        down_run_flag = 1; // 开始倒计时
                        time_ing_down = time_set; // 使用当前设定值
                    }
                }
                else // 长按(大于500ms),松开开始倒计时
                {
                    down_run_flag = 1; // 开始倒计时
                    time_ing_down = time_set; // 使用当前设定值
                }

                // 重置按键状态
                key3_pressed = 0;
                key3_hold_time = 0;
                key3_last_change = 0;
            }
        }


        // ---------------- LCD显示逻辑 ----------------
        if(time_able == 1)
        {
            // 正计时显示,第一行,列3
            LCD1602_shownum(3, 0, time_ing_up, 3);
            // 倒计时显示,第一行,列11
            LCD1602_shownum(11, 0, time_ing_down, 3);
        }

        // ---------------- DHT11温湿度读取逻辑(每2秒读取一次)----------------
        if(dht11_read_timer - dht11_last_read_time >= 20) // 2000ms = 2秒
        {

            uint8_t temp, humi;
                                          DHT11_Read_Data(&temp, &humi);
            if(1) //DHT11_Read_Data(&temp, &humi) 读取成功
            {
                                                         
                temperature = temp;
                humidity = humi;
                // 使用sprintf格式化显示字符串
                sprintf(display_buffer, "T:%2d C H:%2d%%", temperature, humidity);
                                                                LCD1602_showstring(0, 1, display_buffer);
                                                        //  LCD1602_shownum(2, 1, temperature, 2);
                                           //   LCD1602_shownum(8, 1, humidity, 2);
            }
            // 如果读取失败,保留上次的值,不更新显示
                                                dht11_last_read_time = dht11_read_timer;
        }
        // 同时在time_able==1时也更新温湿度显示(确保显示不消失)
        if(time_able == 1)
        {
            sprintf(display_buffer, "T:%2d C H:%2d%%", temperature, humidity);
            LCD1602_showstring(0, 1, display_buffer);
                                        //  LCD1602_shownum(2, 1, temperature, 2);
                                        //  LCD1602_shownum(9, 1, humidity, 2);
        }

        Delay_ms(5); // 减少CPU占用,提高响应速度


    }
}


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:469589 发表于 2026-1-2 08:29 | 只看该作者
从简单的功能,一个一个的试,不要直接作最终功能加测!
从简单的输出开始,例如采用定时循环或开机响一声检查报警声音,。。。。
DHT11最后检查!!!!
回复

使用道具 举报

板凳
ID:123289 发表于 2026-1-7 10:18 | 只看该作者
听从楼上的建议。要点是学会走单步调试,
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表