www.pudn.com > DHT11.rar > DHT11.c, change:2014-04-02,size:5056b


# include<reg52.h> 
# include<intrins.h> 
typedef unsigned char unint8; 
typedef unsigned char unint16; 
unsigned char str1[]={" "}; 
unsigned char str2[]={" "}; 
unsigned char code dis1[]={"TRH RH:"}; 
unsigned char code dis2[]={"TRH T:"}; 
sbit TRH = P3^2;//温湿度传感器DHT11数据接入 
sbit ST = P3^3;	//状态显示,是为了方便调试,具体使用时可以不要 
sbit LCD_RS = P3^5; 
sbit LCD_RW = P3^6; 
sbit LCD_EN = P3^7; 
unint8 TH_data,TL_data,RH_data,RL_data,CK_data; 
unint8 TH_temp,TL_temp,RH_temp,RL_temp,CK_temp; 
unint8 com_data,untemp,temp; 
unint8 respond; 
/*==============================*/ 
void delayNOP() 
{ 
	_nop_(); 
	_nop_(); 
	_nop_(); 
	_nop_(); 
} 
//毫秒级延时子程序 
void delay_ms(unsigned char ms) 
{ 
	unsigned char i; 
	while(ms--) 
	{ 
		for(i=0;i<150;i++) 
		{ 
			_nop_(); 
			_nop_(); 
			_nop_(); 
			_nop_(); 
		} 
	} 
} 
/*===========================*/ 
//5us级延时函数 
void delay_us() 
{ 
	unint8 i; 
	i--; 
	i--; 
	i--; 
	i--; 
	i--; 
	i--; 
} 
/*============================*/ 
//测试LCD忙碌状态 
//lcd_busy()为1时,忙,等待。lcd_busy()为0时,闲,可写指令与数据。 
/*=============================*/ 
bit lcd_busy() 
{ 
	bit result; 
	LCD_RS = 0; 
	LCD_RW = 1; 
	LCD_EN = 1; 
	delayNOP(); 
	result = (bit)(P0&0x80); 
	LCD_EN = 0; 
	return(result); 
} 
/*================================*/ 
//写入指令数据到LCD 
/*================================*/ 
void lcd_wcmd(unsigned char cmd) 
{ 
	while(lcd_busy()); 
	LCD_RS = 0; 
	LCD_RW = 0; 
	LCD_EN = 0; 
	_nop_(); 
	_nop_(); 
	P2 = cmd; 
	delayNOP(); 
	LCD_EN = 1; 
	delayNOP(); 
	LCD_EN = 0; 
} 
/*============================*/ 
//写显示数据到LCD 
//RS=高电平,RW=低电平,E=高脉冲,D0-D7=数据。 
/*=================================*/ 
void lcd_wdata(unsigned char dat) 
{ 
	while(lcd_busy()); 
	LCD_RS = 1; 
	LCD_RW = 0; 
	LCD_EN = 0; 
	P2 = dat; 
	delayNOP(); 
	LCD_EN = 1; 
	delayNOP(); 
	LCD_EN = 0; 
} 
/*==================================*/ 
//LCD初始化设定 
/*==================================*/ 
void lcd_init() 
{ 
	delay_ms(15); 
	lcd_wcmd(0x38);	//1602显示 
	delay_ms(5); 
	lcd_wcmd(0x38); 
	delay_ms(5); 
	lcd_wcmd(0x38); 
	delay_ms(5); 
	lcd_wcmd(0x0c);//显示开,关光标。 
	delay_ms(5); 
	lcd_wcmd(0x06);//移动光标 
	delay_ms(5); 
	lcd_wcmd(0x01);//清除LCD的显示内容,如果屏幕过暗,可将这两句删除 
	delay_ms(5); 
} 
/*=======================*/ 
//设定LCD显示位置 
/*=======================*/ 
void lcd_dis_pos(unsigned char pos) 
{ 
	lcd_wcmd(pos|0x80);//数据指针=80+地址变量 
} 
/*========================*/ 
//收发信号检测,数据读取 
/*========================*/ 
char receive() 
{ 
	unint8 i; 
	ST = 0; 
	com_data = 0; 
	for(i=0;i<=7;i++) 
	{ 
		respond = 2; 
		while((!TRH)&&respond++); 
		delay_us(); 
		delay_us(); 
		delay_us(); 
		if(TRH) 
		{ 
			temp = 1; 
			respond = 2; 
			while((TRH)&&respond++); 
		} 
		else 
		{ 
			temp = 0; 
		} 
		com_data<<=1; 
		com_data|=temp; 
	} 
	return(com_data); 
} 
/*================================*/ 
//湿度读取子程序 
//温度高8位==TH_data 
//温度低8位==TL_data 
//湿度高8位==RH_data 
//湿度低8位==RL_data 
//校验8位==CK_data 
//调用的程序有delay();Delay_5us();RECEIVE(); 
/*====================================*/ 
void read_TRH() 
{ 
	//主机拉低18ms 
	TRH = 0; 
	delay_ms(18); 
	TRH = 1; 
	//DATA总线由上拉电阻拉高 主机延时20us 
	delay_us(); 
	delay_us(); 
	delay_us(); 
	delay_us(); 
	//主机设为输入 判断从机响应信号 
	TRH = 1; 
	//判断DHT11是否有低电平响应信号 如不响应则跳出,响应则向下运行 
	if(!TRH) 
	{ 
		respond = 2; 
		//判断DHT11发出80us的低电平响应信号是否结束 
		while((!TRH)&&respond++); 
		respond = 2; 
		//判断从机是否发出80us的高电平,如发出则进入数据接收状态 
		while(TRH&&respond++); 
		//数据接收状态 
		RH_temp = receive(); 
		RL_temp = receive(); 
		TH_temp = receive(); 
		TL_temp = receive(); 
		CK_temp = receive(); 
		TRH = 1; 
		ST = 1; 
		//数据校验 
		untemp = (RH_temp+RL_temp+TH_temp+TL_temp); 
		if(untemp==CK_temp) 
		{ 
			RH_data = RH_temp; 
			RL_data = RL_temp; 
			TH_data = TH_temp; 
			TL_data = TL_temp;			 
			CK_data = CK_temp; 
		} 
	} 
	//湿度整数部分 
	str1[0] = (char)(0x30+RH_data/10); 
	str1[1] = (char)(0x30+RH_data%10); 
	str1[2] = 0x2e;//小数点 
	//湿度小数部分 
	str1[3] = (char)(0x30+RL_data/10); 
	str1[5] = 0x25; 
	str1[6] = 0x52; 
	str1[7] = 0x48; 
	//温度整数部分 
	str2[0]	= (char)(0x30+TH_data/10); 
	str2[1] = (char)(0x30+TH_data%10); 
	str2[2] = 0x20; 
	//温度小数部分 
	str2[3]	= (char)(0x30+TL_data/10); 
	str2[5] = 0x27; 
	str2[6] = 0x43; 
} 
/*==============================*/ 
//主函数 
//TH,TL,RH,RL分别代表温湿度的整数部分和小数部分 
/*==============================*/ 
void main() 
{ 
	unsigned char i,n = 0x40,m; 
	lcd_init(); 
	delay_us(); 
	while(1) 
	{ 
		read_TRH(); 
		for(i=0;i<=7;i++) 
		{ 
			lcd_dis_pos(i); 
			lcd_wdata(dis1[i]); 
			lcd_dis_pos(n+1); 
			lcd_wdata(dis2[i]);			 
		} 
		//写湿度数据 
		m = 0x08; 
		for(i=0;i<=7;i++) 
		{ 
			lcd_dis_pos(m); 
			lcd_wdata(str1[i]); 
			m++; 
		} 
		//写温度数据 
		m = 0x48; 
		for(i=0;i<=7;i++) 
		{ 
			lcd_dis_pos(m); 
			lcd_wdata(str2[i]); 
			m++; 
		} 
		delay_ms(1000); 
	} 
}