基于51单片机实现温湿度采样 使用DHT11温湿度传感器,LCD1602做显示

最近在做大创,要用到DHT11温湿度传感器,发现有点问题解决不了。可以使用。写的程序(主要是DHT11部分)发到网上供大家参考一下,抛砖引玉看看大家有没有什么好的思路。

启动一次DHT11温湿度采集

/*****************************************************************
函数名称:static void DHT11_Init()
函数功能:启动一次温湿度采集
输入参数:无
返回值  :无
*****************************************************************/
static void DHT11_Start()
{
	DHT11_DQ = LOW;			// 主机把总线拉低等待DHT11响应
	DHT11_Delayms(18);		// 主机把总线拉低必须大于18ms
	DHT11_DQ = HIGH;		// 主机开始信号结束
	DHT11_Delayus(40);		// 主机把总线拉高等待20-40us
	while(!DHT11_DQ);		// DHT11响应输出 (低电平,80us)
	while(DHT11_DQ);		// DHT11拉高延时准备输出 (高电平,80us)
	while(!DHT11_DQ);		// DHT11开始传输数据 (低电平,50us)
}

 开始读取温湿度数据并保存,最后进行校验。有中断参与时,在读取温度时一定要关闭中断,不然会出错。

/*****************************************************************
函数名称:static void DHT11_Read(Dht_t* dht11)
函数功能:温湿度读取
输入参数:dht11:DHT11结构体变量
返回值  :无
*****************************************************************/
static void DHT11_Read(Dht_t* dht11)
{
	uint8_t i, mask;
	static uint8_t Data_Ori_t[5];
	
	EA = 0;											// 在读取温湿度数据时关闭中断
	for(i = 0; i < 5; i ++)							// 高位在前,逐位读取,将DHT11的数据读取到dht11.Check数组上
	{
		for(mask =  0X80; mask != 0x00;	mask >>= 1)
		{
			DHT11_Delayus(28);						// 延时28us
			if(DHT11_DQ == 1)						// 看DHT11_DQ是否还输出高电平
			{
				Data_Ori_t[i] |= mask;				// 还是高电平的话则此位为高
				while(DHT11_DQ);					// 等待DHT11输出完此次高电平 (70us - 28us)
			}
			
			while(!DHT11_DQ);						// 准备发送数据,每一bit数据都以50us低电平时隙开始
		}
	}
	EA = 1;											// 在读取温湿度数据时关闭中断
	
	// 校验数据,8bit校验和 = 8bit湿度整数数据 + 8bit湿度小数数据 + 8bi温度整数数据 + 8bit温度小数数据
	if(Data_Ori_t[4] == Data_Ori_t[0] + Data_Ori_t[1] + Data_Ori_t[2] + Data_Ori_t[3])
	{
		dht11->humidity    = Data_Ori_t[0] + Data_Ori_t[1]/256.0;	// 湿度值保存,整数加小数
		dht11->temperature = Data_Ori_t[2] + Data_Ori_t[3]/256.0;	// 温度值保存,整数加小数
		for(i = 0; i < 5; i ++)
		{
			dht11->Data_Ori[i] = Data_Ori_t[i];		// 原始数据保存
			Data_Ori_t[i] = 0;						// 原数据临时变量复位
		}
	}
}

整合为DHT11_Acqu函数

/*****************************************************************
函数名称:void DHT11_Acqu(Dht_t* dht11)
函数功能:温湿度采集
输入参数:dht11:DHT11结构体变量
返回值  :无
*****************************************************************/
void DHT11_Acqu(Dht_t* dht11)
{
	DHT11_Start();			// 启动一次温湿度采集
	DHT11_Read(dht11);		// DHT11读取温湿度
}

 dht11结构体类型及变量定义

/****结构体定义****/
typedef struct
{
	float humidity;
	float temperature;
	uint8_t Data_Ori[5];
}Dht_t;
// 定义DHT11结构体变量
Dht_t dht11 = 
{
	0.0,   		// 湿度
	0.0,   		// 温度
	{0},		// 5个字节的源数据(湿度高8位+湿度低8位+温度高8位+温度低8位+校验位)
};

主函数,将采集的温湿度数据显示到LCD1602上

#include 
#include 
#include 

void main()
{
	// 变量声明/定义
	extern Dht_t dht11;
	uint8_t Dis[30];
	uint16_t count = 0;
	
	// LCD1602初始化
	LCD1602_Init();
	
//	// 提前进行一次转换
//	DHT11_Acqu(&dht11);
//	sprintf(s, "%2.0f %2.2f", dht11.humidity, dht11.temperature);
	
	// LOOP
	while(1)
	{
		count --;
		
		if(!count)		// 每隔一段时间采样一次
		{
			count --;
			DHT11_Acqu(&dht11);				// 更新温湿度
			
			// 将湿度信息格式化输出到数组Dis
			sprintf(Dis, "HUMI: %2.0f%%", dht11.humidity);
			LCD1602_Print(0, 0, Dis);		// 第一行显示湿度
			
			// 将温度信息格式化输出到数组Dis,0XDF为"°"的ASCII码值
			sprintf(Dis, "TEMP: %2.2f%cC", dht11.temperature, (uint8_t)(0xDF));
			LCD1602_Print(1, 0, Dis);		// 第二行显示温度
		}
	}
}

关于函数前面加static修饰词:C语言中的静态(static)函数_yubinghang93的博客-CSDN博客

主要是这一点:“静态函数会被自动分配在一个一直使用的存储区,直到程序结束才从内存消失,避免调用函数时压栈出栈,速度快很多。”

实际效果

基于51单片机实现温湿度采样 使用DHT11温湿度传感器,LCD1602做显示_第1张图片

源程序

链接:百度网盘 请输入提取码
提取码:gfjk

 现在不知道要怎么改能在读取温湿度时不关闭中断,也就是去掉DHT11_Read函数里的EA = 0;、EA = 1;这两条语句。大家有什么思路吗?

基于51单片机实现温湿度采样 使用DHT11温湿度传感器,LCD1602做显示_第2张图片

你可能感兴趣的:(单片机)