用STC89C51和DHT11做个温湿度报警器,附Keil5代码和Proteus8.7仿真文件

张开发
2026/4/17 20:52:54 15 分钟阅读

分享文章

用STC89C51和DHT11做个温湿度报警器,附Keil5代码和Proteus8.7仿真文件
从零搭建51单片机温湿度报警系统手把手教你玩转DHT11与LCD1602最近在整理工作室时翻出一堆闲置的STC89C51开发板正好赶上梅雨季节想着做个能监测环境温湿度的小装置应该挺实用。这个项目特别适合刚接触单片机的朋友练手用到的DHT11传感器和LCD1602显示屏都是入门级器件成本不到30元就能搞定。下面我就把整个实现过程拆解成可落地的步骤包括硬件连接、Keil5环境配置、代码逐行解析以及Proteus仿真技巧最后还会分享调试时遇到的几个坑和解决方案。1. 硬件准备与电路搭建1.1 元器件选型清单先来看需要哪些硬件设备所有元件都能在淘宝以单片机套件关键词搜到核心控制器STC89C51RC兼容传统8051架构温湿度传感器DHT11数字信号输出免校准显示模块LCD1602液晶屏蓝底白字款可视度更佳报警装置有源蜂鸣器LED指示灯红绿双色输入设备4*6mm轻触按键设置阈值用其他10K电位器调节LCD对比度、1K电阻、杜邦线若干注意DHT11的测量范围是0-50℃±2℃精度和20-90%RH±5%RH精度如果需要更高精度建议换用DHT22但代码需要相应调整。1.2 电路连接示意图用表格更直观展示各模块连接方式元器件引脚单片机引脚说明DHT11 DATAP2.0需接上拉电阻(4.7K-10K)LCD1602 RSP1.0寄存器选择信号LCD1602 RWP1.1读写控制(接地为写模式)LCD1602 ENP1.2使能信号LCD1604 D4-D7P1.4-P1.74位数据线蜂鸣器正极P3.7通过三极管驱动LED1-LED4P3.0-P3.3状态指示灯KEY1-KEY4P3.4-P3.6矩阵按键输入// 硬件引脚定义示例Keil中需声明 sbit DHT11 P2^0; sbit BUZZER P3^7; sbit LED_HOT P3^0; // 高温指示灯2. 开发环境配置2.1 Keil5工程设置很多初学者第一次用Keil时会遇到编译报错重点检查这几个配置新建工程时选择STC MCU Database中的STC89C51RC在Options for Target→Output勾选Create HEX File在C51标签页设置Memory Model为Small,Code Rom Size为Large如果遇到头文件缺失错误需要手动添加STC89C51的寄存器定义文件通常命名为STC89C5xRC.H这个文件在STC-ISP下载工具安装目录可以找到。2.2 Proteus8.7仿真要点仿真时特别注意这些元件参数设置DHT11模型需要加载正确的.DLL文件可在官网下载LCD1602的电源电压设为5V单片机时钟频率默认11.0592MHz添加Virtual Terminal方便调试串口信息# 推荐元件搜索关键词 DHT11 → DHT11 Module LCD → LM016L (Proteus中1602的型号)3. 核心代码解析3.1 DHT11驱动实现这个传感器采用单总线协议时序要求严格下面是关键代码段// DHT11读取函数 uint8 RH(void) { uint8 i, j; DHT11 0; // 主机拉低至少18ms Delay_ms(20); DHT11 1; // 释放总线 Delay_us(30); if(!DHT11) { // 等待DHT11响应 while(!DHT11); // 等待80us低电平 while(DHT11); // 等待80us高电平 // 开始接收40位数据(5字节) for(i0; i5; i) { for(j0; j8; j) { while(!DHT11); // 等待50us低电平 Delay_us(40); // 判断高电平持续时间 U8FLAG DHT11; U8temp 1; if(U8FLAG) U8temp | 1; while(DHT11); // 等待高电平结束 } U8RH_data_H U8temp; } } return U8temp; }常见问题如果读取总是失败检查硬件连接是否接触不良或者尝试增加延时时间。DHT11两次读取间隔需大于1秒。3.2 报警逻辑处理阈值判断部分采用状态机设计避免频繁触发报警if(FlagStartRH 1) { // 获取最新温湿度数据 temperature GetTemperature(); humidity GetHumidity(); // 温度状态判断 if(temperature TEMP_HIGH) { SetAlarm(HOT_ALARM); } else if(temperature TEMP_LOW) { SetAlarm(COLD_ALARM); } else { ClearAlarm(TEMP_ALARM); } // 湿度状态判断逻辑类似温度 ... }4. 功能扩展与优化建议4.1 增加蓝牙模块传输数据可以添加HC-05模块实现手机监控硬件连接只需四根线模块VCC接5VGND接地TXD接单片机RXD(P3.0)RXD接单片机TXD(P3.1)在代码中初始化串口后添加数据发送函数void SendToBluetooth() { printf(T:%dC H:%d%%\r\n, temperature, humidity); if(hot) printf(Status: HOT!\r\n); else if(cold) printf(Status: COLD!\r\n); ... }4.2 低功耗优化方案如果采用电池供电可以通过这些方式降低功耗设置单片机进入空闲模式IDLE Mode降低采集频率如每5分钟采样一次用MOS管控制外围器件电源关闭LED显示仅保留蜂鸣器报警// 进入低功耗模式示例 PCON | 0x01; // 设置IDL位进入空闲模式 // 通过外部中断唤醒5. 调试经验分享去年带学生做这个项目时最常遇到的三个问题LCD显示乱码80%的情况是电位器没调好对比度15%是初始化时序不对剩下5%可能是电压不稳DHT11无响应一定要检查上拉电阻是否接好我习惯用4.7K电阻接在DATA和VCC之间按键抖动软件消抖最简单的方式是检测到按键按下后延时10-20ms再次检测有个特别有意思的案例有位同学的报警器在温度达到阈值时不触发排查半天发现是他把蜂鸣器的正负极接反了——虽然看起来是个低级错误但实际开发中这类问题反而最常见。

更多文章