写点什么

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

作者:DS小龙哥
  • 2023-06-27
    重庆
  • 本文字数:3919 字

    阅读完需:约 13 分钟

一、项目背景

本项目基于 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 温湿度数据读取代码示例,通过串口调试助手将读取到的数据打印出来:


#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 驱动芯片)显示屏显示一个数字的详细代码:


#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。

发布于: 刚刚阅读数: 4
用户头像

DS小龙哥

关注

之所以觉得累,是因为说的比做的多。 2022-01-06 加入

熟悉C/C++、51单片机、STM32、Linux应用开发、Linux驱动开发、音视频开发、QT开发. 目前已经完成的项目涉及音视频、物联网、智能家居、工业控制领域

评论

发布
暂无评论
STC89C52+DHT20设计的环境温湿度检测仪_6 月 优质更文活动_DS小龙哥_InfoQ写作社区