#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
//--------LCD1602-------------------
//P10-17==== D0-7
sbit rs=P3^0; //指令or数据
sbit wela=P3^1; //读or写
sbit lcden=P3^2; //使能信号
uchar dispaly[10]; //显示缓冲
uchar Temp; //温度
uchar Hum; //湿度
sbit P20 = P2^7; //dht11
//-----------DHT11------------------------------
uchar U8FLAG,k;
uchar U8count,U8temp;
uchar U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata;
uchar U8T_data_H_temp,U8T_data_L_temp,U8RH_data_H_temp,U8RH_data_L_temp,U8checkdata_temp;
uchar U8comdata;
//-----------DHT11------------------------------
//************************************************************************/
// 描述: 延时t us函数
//************************************************************************/
void LCD_Delay_us(unsigned int t)
{
while(t--); //t=0,退出
}
//************************************************************************/
// 描述: 延时t ms函数
//************************************************************************/
void LCD_Delay_ms(unsigned int t)
{
unsigned int i,j;
for(i=0;i<t;i++) //执行t次循环
for(j=0;j<113;j++) //执行113次循环
;
}
//************************************************************************/
// 描述: 1602液晶写指令
//************************************************************************/
void write_com(uchar com) //1602液晶写指令
{
rs=0; //写指令
lcden=0; //使能1602
P1=com; //写入指令com
LCD_Delay_ms(1); //延时1ms
lcden=1; //使能1602
LCD_Delay_ms(5); //延时5ms
lcden=0; //使能1602
}
//************************************************************************/
// 描述:1602液晶写数据
//************************************************************************/
void write_date(uchar date) //1602液晶写数据
{
rs=1; //写数据
lcden=0; //使能1602
P1=date; //写入数据date
LCD_Delay_ms(1); //延时1ms
lcden=1; //使能1602
LCD_Delay_ms(5); //延时5ms
lcden=0; //使能1602
}
//************************************************************************/
// 描述:指定x,y写入字符函数
//************************************************************************/
void W_lcd(unsigned char x,unsigned char y,unsigned char Data)
{
if (y == 0){write_com(0x80 + x);} //第一行
else{write_com(0xc0 + x);} //第二行
write_date( Data); //写入数据
}
//指定x,y写入字符串函数
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
{
if (y == 0){write_com(0x80 + x);} //第一行
else{write_com(0xC0 + x);} //第二行
while (*s) //
{write_date( *s); s++;} //写入数据
}
//************************************************************************/
// 描述:初始化液晶,及画面初始化
//************************************************************************/
void init_lcd(void) //初始化液晶,及画面初始化
{
wela=0; //写液晶
lcden=0; //使能1602
write_com(0x38); //8 位总线,双行显示,5X7 的点阵字符
LCD_Delay_us(100); //延时100us
write_com(0x0c); //开显示,无光标,光标不闪烁
write_com(0x06); //光标右移动
write_com(0x01); //清屏
write_com(0x80); //DDRAM 地址归0
}
void display(void)
{
dispaly[0]=Temp%100/10; //十
dispaly[1]=Temp%10; //个
write_com(0x80+7); //第1行
write_date('0'+dispaly[0]); //显示万万
write_date('0'+dispaly[1]); //千万
dispaly[2]=Hum%100/10; //十
dispaly[3]=Hum%10; //个
write_com(0x80+11+0x40); //第2行
write_date('0'+dispaly[2]); //显示万万
write_date('0'+dispaly[3]); //千万
}
/////////////////////////////////////////////////
//-----------DHT11------------------------------
void Delaynus(unsigned int j)
{ unsigned char i;
for(;j>0;j--)
{
for(i=0;i<27;i++);
}
}
void Delay_10us(void)
{ unsigned char i;
i--;i--;i--;i--;i--;i--;
}
void COM(void)
{ unsigned char i;
for(i=0;i<8;i++)
{ U8FLAG=2; //判断是否到达1um ,2到255是1Um
while((!P20)&&U8FLAG++); //判断是否到达1um
Delay_10us();Delay_10us();
Delay_10us();Delay_10us();
Delay_10us();Delay_10us();
U8temp=0;
if(P20)U8temp=1;
U8FLAG=2;
while((P20)&&U8FLAG++);
//超时则跳出for循环
if(U8FLAG==1)break;
//判断数据位是0还是1
// 如果高电平高过预定0高电平值则数据位为 1
U8comdata<<=1;
U8comdata|=U8temp; //0
}//rof
}
//--------------------------------
//-----湿度读取子程序 ------------
//--------------------------------
//----以下变量均为全局变量--------
//----温度高8位== U8T_data_H------
//----温度低8位== U8T_data_L------
//----湿度高8位== U8RH_data_H-----
//----湿度低8位== U8RH_data_L-----
//----校验 8位 == U8checkdata-----
//----调用相关子程序如下----------
//---- Delay();, Delay_10us();,COM();
//--------------------------------
void DHT11(void)
{
//主机拉低18ms
P20=0;
Delaynus(180);Delaynus(180);
P20=1;
//总线由上拉电阻拉高 主机延时20us
Delay_10us();Delay_10us();
Delay_10us();Delay_10us();
Delay_10us();Delay_10us();
Delay_10us();Delay_10us();
//主机设为输入 判断从机响应信号
P20=1;
//判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行
if(!P20) //T !
{
U8FLAG=2;
//判断从机是否发出 80us 的低电平响应信号是否结束
while((!P20)&&U8FLAG++);
U8FLAG=2;
//判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
while((P20)&&U8FLAG++);
//数据接收状态
COM();
U8RH_data_H_temp=U8comdata;
COM();
U8RH_data_L_temp=U8comdata;
COM();
U8T_data_H_temp=U8comdata;
COM();
U8T_data_L_temp=U8comdata;
COM();
U8checkdata_temp=U8comdata;
P20=1;
//数据校验
U8temp=(U8T_data_H_temp+U8T_data_L_temp+U8RH_data_H_temp+U8RH_data_L_temp);
if(U8temp==U8checkdata_temp)
{
U8RH_data_H=U8RH_data_H_temp;
U8RH_data_L=U8RH_data_L_temp;
U8T_data_H=U8T_data_H_temp;
U8T_data_L=U8T_data_L_temp;
U8checkdata=U8checkdata_temp;
}//fi
}//fi
}
//-----------DHT11------------------------------
/////////////////////////////////////////////////
void main()
{
Temp=10; //温度
Hum=68; //湿度
LCD_Delay_ms(1000);
DHT11(); //调用温湿度读取子程序
init_lcd(); //1602液晶初始化
LCD_Write_String(0,0," Temp: C "); //显示" Temp:10 C "
W_lcd(9,0,223); //.符号
LCD_Write_String(0,1," Humidity: % "); //显示" Humidity:68% "
while(1)
{
DHT11(); //调用温湿度读取子程序
Hum=U8RH_data_H; //湿度
Temp=U8T_data_H; //温度
display(); //显示数据
LCD_Delay_ms(1000); //1S采集一次
}
}