STC89C52+DHT20设计的环境温湿度检测仪

一、项目背景

本项目基于STC89C52单片机和DHT20温湿度传感器,实现了一款环境温湿度检测仪。通过传感器采集环境的温度和湿度数据,利用IIC接口的OLED显示屏显示出来,便于用户实时监测环境温湿度状态。

在现代社会,人们对环境温湿度的要求越来越高。无论是工作场所还是居住环境,都需要维持一个舒适的温湿度状态,以保证身体的健康和工作效率的提高。随着科技的不断进步和物联网技术的广泛应用,环境温湿度检测仪被广泛运用于各种领域,如制造业、医疗、农业等等,成为了一种重要的环境检测设备。

而本项目所涉及的STC89C52单片机和DHT20温湿度传感器作为传统的嵌入式开发技术,在实现物联网设备方面有着广泛的应用前景。通过本项目的学习和实践,可以深入了解传感器技术的原理和应用,并掌握基于单片机的嵌入式开发技术,为实现更多物联网设备的开发和应用打下基础。

二、设计思路

本项目的设计思路主要包括硬件和软件两个方面。

【1】硬件设计思路

本项目的硬件设计主要涉及到STC89C52单片机、DHT20温湿度传感器和OLED显示屏三个模块。其中,STC89C52单片机负责控制整个系统的运行,DHT20温湿度传感器用于采集环境的温湿度数据,OLED显示屏则负责将温湿度数据实时展示出来。

具体的硬件设计流程如下:

(1)选择合适的STC89C52单片机开发板,并根据需要添加外部电源、复位电路、晶振等元件。

(2)选择合适的DHT20温湿度传感器,并根据其引脚定义将其连接到单片机的I/O口。

(3)选择合适的OLED显示屏,并根据其接口定义将其连接到单片机的IIC总线上。

(4)在单片机开发环境中编写程序,实现对DHT20传感器的温湿度数据读取和对OLED显示屏的控制。

【2】软件设计思路

本项目的软件设计主要涉及到单片机程序的编写和调试。根据硬件设计的思路,将实现对DHT20传感器的温湿度数据读取和对OLED显示屏的控制。

具体的软件设计流程如下:

(1)在单片机开发环境中编写程序,实现DHT20传感器的初始化、温湿度数据的读取和对OLED显示屏的控制。

(2)通过串口调试助手,将DHT20传感器采集到的温湿度数据打印出来,检查程序是否正常运行。

(3)连接OLED显示屏,并调试程序,实现温湿度数据的实时显示。

三、设计代码

【1】DHT20温湿度读取

DHT20是一款数字式温湿度传感器,其采用了广受欢迎的I2C总线进行数据通信,可以方便地与各种微控制器和单片机进行连接和使用。该传感器具有高精度、低功耗、稳定性好等特点,被广泛应用于气象站、冷库、温室、恒温箱、智能家居等领域。

DHT20的工作电压范围为2.1V至5.5V,并且其在测量过程中的功耗非常低,最大电流为1.3mA,平时仅需要几微安的待机电流,从而节省了能源并延长了电池寿命。该传感器采用了独特的校准技术,能够实现高精度的测量,温度测量精度为±0.2℃,湿度测量精度为±2%RH。

DHT20是一款数字式温湿度传感器,其通过内部的ADC将模拟信号转换成数字信号,并使用CRC校验保证数据传输的可靠性。此外,该传感器还具有单次测量和连续测量两种模式,可以满足不同场景下的需求。

DHT20传感器采用单线数字信号传输,读取数据过程中需要按照协议进行时序控制。

下面是基于STC89C52单片机的DHT20温湿度数据读取代码示例,通过串口调试助手将读取到的数据打印出来:

cpp 复制代码
 #include <reg52.h>
 #include <intrins.h>
 ​
 sbit DHT20 = P1^0;  //定义DHT20连接的IO口
 ​
 void delay_us(unsigned int us) //us级延时函数
 {
     while(us--)
     {
         _nop_();
     }
 }
 ​
 void DHT20_start(void) //开始信号
 {
     DHT20 = 1; //先将数据线置高
     delay_us(30); //延时30us
     DHT20 = 0; //拉低数据线
     delay_us(25); //持续拉低25us
     DHT20 = 1; //释放数据线
     delay_us(5); //延时5us
 }
 ​
 unsigned char DHT20_read(void) //读取一个字节的数据
 {
     unsigned char i, dat = 0;
     for(i=0; i<8; i++)
     {
         while(!DHT20); //等待数据线变高
         delay_us(4); //延时4us
         dat <<= 1; //左移一位
         if(DHT20) //如果数据线为高
         {
             dat |= 1; //在最低位写入1
             while(DHT20); //等待数据线变低
         }
     }
     return dat;
 }
 ​
 void main()
 {
     unsigned char humi_H, humi_L, temp_H, temp_L, check_sum;
     while(1)
     {
         DHT20_start(); //发送开始信号
         if(!DHT20) //等待DHT20响应
         {
             delay_us(80);
             if(DHT20)
             {
                 delay_us(80);
                 humi_H = DHT20_read(); //读取湿度高8位
                 humi_L = DHT20_read(); //读取湿度低8位
                 temp_H = DHT20_read(); //读取温度高8位
                 temp_L = DHT20_read(); //读取温度低8位
                 check_sum = DHT20_read(); //读取校验和
                 if((humi_H + humi_L + temp_H + temp_L) == check_sum) //校验和正确
                 {
                     printf("湿度:%d.%d %%\r\n", humi_H, humi_L);
                     printf("温度:%d.%d ℃\r\n", temp_H, temp_L);
                 }
             }
         }
         delay_ms(5000); //延时5s再读取
     }
 }

【2】IIC接口的OLED显示屏的驱动代码

0.96寸OLED(SSD1306驱动芯片)显示屏是一款常见的小型显示器件,具有高对比度、低功耗、快速响应等特点。其主要由OLED芯片和玻璃基板组成,可通过IIC或SPI接口控制,实现图形、文字、数字等内容的显示。

SSD1306驱动芯片是最常用的OLED显示器驱动芯片之一,具有低功耗、高对比度、高分辨率等优点。它支持点阵图像显示、字符显示、图形显示等多种显示模式,可通过IIC/SPI接口进行通信控制,支持控制字体大小、显示位置、亮度等参数,且内置显存,方便多屏幕拼接显示。

0.96寸OLED(SSD1306驱动芯片)显示屏通常采用128x64或者128x32的分辨率,显示效果清晰,可显示4行16列的字体信息。其内置控制器,占用极少的CPU资源和存储空间,适合于嵌入式系统、智能家居、手持设备等场景中使用。

下面是基于STC89C52单片机控制IIC接口的0.96寸OLED(SSD1306驱动芯片)显示屏显示一个数字的详细代码:

cpp 复制代码
 #include <reg52.h>
 #include <intrins.h>
 ​
 #define uchar unsigned char
 #define uint unsigned int
 ​
 /* 定义IIC总线的SDA和SCL引脚 */
 sbit SDA = P1^0;
 sbit SCL = P1^1;
 ​
 /* 定义OLED显示屏的地址,一般为0x78 */
 #define OLED_ADDRESS 0x78
 ​
 /* OLED显示屏的初始化命令 */
 uchar init_cmd[] = {
     0xAE, /* 关闭OLED显示 */
     0x00, /* 设置列地址低位 */
     0x10, /* 设置列地址高位 */
     0x40, /* 设置起始行 */
     0xB0, /* 设置页地址 */
     0x81, /* 设置对比度 */
     0xFF, /* 对比度值 */
     0xA1, /* 水平翻转 */
     0xA6, /* 正常显示 */
     0xA8, /* 设置多路复用率 */
     0x3F, /* 值越大,显示点越多,亮度越高 */
     0xC8, /* 垂直翻转 */
     0xD3, /* 设置显示偏移 */
     0x00, /* 偏移量为0 */
     0xD5, /* 设置时钟分频 */
     0x80, /* 分频值为80 */
     0xD9, /* 设置预充电周期 */
     0xF1, /* 默认值 */
     0xDA, /* 设置COM硬件配置 */
     0x12, /* 默认值 */
     0xDB, /* 设置VCOMH电压 */
     0x40, /* 默认值 */
     0x20, /* 设置内存地址模式 */
     0x00, /* 水平地址模式 */
     0xAF  /* 打开OLED显示 */
 };
 ​
 /* IIC总线的延时函数 */
 void Delay5ms()
 {
     uint i, j;
 ​
     for (i = 0; i < 5; i++) {
         for (j = 0; j < 110; j++);
     }
 }
 ​
 /* IIC总线的启动信号,SDA从高到低,SCL为高电平 */
 void I2C_Start()
 {
     SDA = 1;
     SCL = 1;
     Delay5ms();
     SDA = 0;
     Delay5ms();
     SCL = 0;
 }
 ​
 /* IIC总线的停止信号,SDA从低到高,SCL为高电平 */
 void I2C_Stop()
 {
     SDA = 0;
     SCL = 1;
     Delay5ms();
     SDA = 1;
     Delay5ms();
 }
 ​
 /* IIC总线的写数据函数 */
 void I2C_Write(uchar dat)
 {
     uchar i;
 ​
     for (i = 0; i < 8; i++) {
         SDA = dat & 0x80;
         SCL = 1;
         Delay5ms();
         SCL = 0;
         dat <<= 1;
     }
 }
 ​
 /* OLED显示屏的初始化函数 */
 void OLED_Init()
 {
     uchar i;
 ​
     I2C_Start();
     I2C_Write(OLED_ADDRESS);
     for (i = 0; i < sizeof(init_cmd); i++) {
         I2C_Write(init_cmd[i]);
     }
     I2C_Stop();
 }
 ​
 /* OLED显示屏的写数据函数 */
 void OLED_Write_Data(uchar dat)
 {
     I2C_Start();
     I2C_Write(OLED_ADDRESS);
     I2C_Write(0x40); /* 写数据标志 */
     I2C_Write(dat);
     I2C_Stop();
 }
 ​
 /* OLED显示屏显示数字的函数 */
 void OLED_Show_Number(uchar num)
 {
     uchar i;
     uint j;
 ​
     /* 在第1页、第5列显示数字 */
     OLED_Write_Data(0xB0);
     OLED_Write_Data(0x00);
     OLED_Write_Data(0x10);
     for (i = 0; i < 8; i++) {
         OLED_Write_Data(0x00);
     }
     for (i = 0; i < 3; i++) {
         OLED_Write_Data(0xFF);
     }
     for (i = 0; i < 5; i++) {
         OLED_Write_Data(0x00);
     }
     for (i = 0; i < 3; i++) {
         OLED_Write_Data(0xFF);
     }
     for (j = 0; j < 5000; j++); /* 延时一段时间,让数字停留在屏幕上 */
 }
 ​
 /* 主函数 */
 void main()
 {
     /* 初始化OLED显示屏 */
     OLED_Init();
 ​
     /* 显示数字 */
     OLED_Show_Number(5);
 }

代码定义了IIC总线的SDA和SCL引脚,以及OLED显示屏的地址。然后定义了OLED显示屏的初始化命令和显示数字的函数。在主函数中调用初始化函数,并在OLED显示屏上显示数字5。

相关推荐
devlei1 小时前
从源码泄露看AI Agent未来:深度对比Claude Code原生实现与OpenClaw开源方案
android·前端·后端
努力的小郑3 小时前
Canal 不难,难的是用好:从接入到治理
后端·mysql·性能优化
Victor3563 小时前
MongoDB(87)如何使用GridFS?
后端
Victor3564 小时前
MongoDB(88)如何进行数据迁移?
后端
小红的布丁4 小时前
单线程 Redis 的高性能之道
redis·后端
GetcharZp4 小时前
Go 语言只能写后端?这款 2D 游戏引擎刷新你的认知!
后端
宁瑶琴5 小时前
COBOL语言的云计算
开发语言·后端·golang
普通网友6 小时前
阿里云国际版服务器,真的是学生党的性价比之选吗?
后端·python·阿里云·flask·云计算
IT_陈寒6 小时前
Vue的这个响应式问题,坑了我整整两小时
前端·人工智能·后端
Soofjan7 小时前
Go 内存回收-GC 源码1-触发与阶段
后端