51单片机智能加湿器控制系统proteus仿真(仿真+源码+原理图) 仿真图proteus 7.8/protues 8.9 程序编译器:keil 4/keil 5 主要功能: 本设计由STC89C52单片机+温湿度传感器电路+按键电路+液位传感器电路+液晶1602显示电路+LED指示灯电路+蜂鸣器报警电路+电源电路组成。 1、液晶实时显示湿度值(湿度范围10%-95%)和湿度阈值。 2、有2个按键,可通过按键设置湿度阈值范围。 3、当湿度值小于阈值,绿灯亮,否则绿灯不亮。 4、通过液位传感器检测液位,液位有3种状态:低(L)、高(H)、正常(N),并在液晶实时显示。 并用3个指示灯模拟显示。 低液位时黄灯亮,正常液位蓝灯亮,高液位是红灯亮(仿真时液位用按键模拟)。 5、当液位低于低液位时,停止加湿即绿灯灭,同时蜂鸣器报警。 否则蜂鸣器不报警。

潮湿的南方人永远不懂北方干到流鼻血的痛,这不,折腾了个51单片机智能加湿器。咱们先从Proteus仿真里扒开它的五脏六腑看看——主控用老熟人STC89C52,配个DHT11温湿度传感器,1602液晶当显示屏,三个LED灯玩红绿灯游戏,还有个蜂鸣器负责当气氛组。

硬件框架说白了就是传感器全家桶:DHT11负责湿度检测,三个按键调阈值,液位检测用按键模拟低中高三种状态。重点在于怎么让这些硬件在代码里活起来。上主菜——主控制逻辑:

void main() {
    LCD_Init();
    DHT11_Init();
    while(1) {
        read_humidity();  //湿度数据抓取
        check_water_level(); //液位检测
        key_scan();       //按键处理
        lcd_display();    //刷新屏幕
        led_control();    //LED状态控制
        alarm_check();    //蜂鸣器叫不叫
    }
}

这段代码像食堂打饭大妈的手——根本停不下来。循环里六个函数轮番上阵,特别是key_scan()函数藏着玄机。长按阈值调整键时,代码里用了这个骚操作:

if(KEY_SET == 0) {
    delay_ms(10);  //经典消抖
    if(KEY_SET == 0) {
        while(!KEY_SET); //死等松手
        threshold += 5;  //步进5%
        if(threshold > 95) threshold = 10;
    }
}

注意那个while(!KEY_SET),这玩意能把CPU卡死在这直到按键松开。实际项目可别这么玩,最好用状态机或者中断来搞,但仿真嘛...凑合用了。

51单片机智能加湿器控制系统proteus仿真(仿真+源码+原理图) 仿真图proteus 7.8/protues 8.9 程序编译器:keil 4/keil 5 主要功能: 本设计由STC89C52单片机+温湿度传感器电路+按键电路+液位传感器电路+液晶1602显示电路+LED指示灯电路+蜂鸣器报警电路+电源电路组成。 1、液晶实时显示湿度值(湿度范围10%-95%)和湿度阈值。 2、有2个按键,可通过按键设置湿度阈值范围。 3、当湿度值小于阈值,绿灯亮,否则绿灯不亮。 4、通过液位传感器检测液位,液位有3种状态:低(L)、高(H)、正常(N),并在液晶实时显示。 并用3个指示灯模拟显示。 低液位时黄灯亮,正常液位蓝灯亮,高液位是红灯亮(仿真时液位用按键模拟)。 5、当液位低于低液位时,停止加湿即绿灯灭,同时蜂鸣器报警。 否则蜂鸣器不报警。

液位检测部分最戏剧化,三个状态对应三个灯。看这段暴力判断:

void check_water_level() {
    if(water_level == LOW) {
        YELLOW = 0; BLUE=1; RED=1;
        BUZZER = 0;  //蜂鸣器尖叫
    } else if(water_level == HIGH) {
        RED = 0; YELLOW=1; BLUE=1;
    } else {
        BLUE = 0; YELLOW=1; RED=1;
    }
}

仿真时得用三个按键模拟水位变化,这里有个坑:Proteus里的按键默认是点动模式,要长按得在元件属性里把"Switch Type"改成"Level"。

最后看蜂鸣器报警逻辑,当水位低于阈值时直接切断加湿器电源:

void alarm_check() {
    if(current_hum < threshold && water_level > LOW) {
        GREEN = 0;  //绿灯亮开始加湿
    } else {
        GREEN = 1;  //熄灭
        if(water_level == LOW) BUZZER = 0; //持续报警
    }
}

这里有个细节——当水位过低时无论湿度是否达标都强制停止加湿。代码里用water_level > LOW这个判断,把枚举值当数字用,虽然不严谨但跑仿真够用了。

仿真调试时最容易翻车的是DHT11时序,示波器抓波形发现读数据时的微秒级延时必须精确。后来发现用Keil的nop函数直接怼汇编更靠谱:

#define DHT11_DQ P2_0

uchar DHT11_ReadByte(){
    uchar i, dat=0;
    for(i=0;i<8;i++){
        while(!DHT11_DQ); //等低电平结束
        delay_40us();      //关键延时!
        dat <<= 1;
        if(DHT11_DQ) dat |= 1;
        while(DHT11_DQ);  //等高点平结束
    }
    return dat;
}

那个delay_40us()要是偏差超过10us,DHT11立马摆烂给你返回255。后来用示波器校准,发现得写成:

void delay_40us() {
    _nop_();_nop_();_nop_();_nop_();_nop_();
    _nop_();_nop_();_nop_();_nop_();_nop_();
} //11.0592MHz下的精确延时

最后说个骚操作:在Proteus里给DHT11元件右键添加"Digital Stimulus",直接模拟湿度值变化,比苦哈哈等传感器反应快多了。毕竟仿真不是真刀真枪,怎么方便怎么来呗。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐