|
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit Data=P2^0; //定義數(shù)據(jù)線
uchar rec_dat[9]; //用于顯示的接收數(shù)據(jù)數(shù)組
sbit lcdrs = P2^3; //寄存器選擇輸入
sbit lcdrw = P2^4; //液晶讀/寫控制
sbit lcden = P2^5; //液晶使能控制
sbit wela = P2^7;
sbit dula = P2^6;
void DHT11_delay_us(uchar n)
{
while(--n);
}
void DHT11_delay_ms(uint z)
{
uint i,j;
for(i=z;i>0;i--)
for(j=110;j>0;j--);
}
void DHT11_start()
{
Data=1;
DHT11_delay_us(2);
Data=0;
DHT11_delay_ms(20); //延時(shí)18ms以上
Data=1;
DHT11_delay_us(30);
}
uchar DHT11_rec_byte() //接收一個(gè)字節(jié)
{
uchar i,dat=0;
for(i=0;i<8;i++) //從高到低依次接收8位數(shù)據(jù)
{
while(!Data); ////等待50us低電平過去
DHT11_delay_us(8); //延時(shí)60us,如果還為高則數(shù)據(jù)為1,否則為0
dat<<=1; //移位使正確接收8位數(shù)據(jù),數(shù)據(jù)為0時(shí)直接移位
if(Data==1) //數(shù)據(jù)為1時(shí),使dat加1來接收數(shù)據(jù)1
dat+=1;
while(Data); //等待數(shù)據(jù)線拉低
}
return dat;
}
void DHT11_receive() //接收40位的數(shù)據(jù)
{
uchar R_H,R_L,T_H,T_L,RH,RL,TH,TL,revise;
DHT11_start();
if(Data==0)
{
while(Data==0); //等待拉高
DHT11_delay_us(40); //拉高后延時(shí)80us
R_H=DHT11_rec_byte(); //接收濕度高八位
R_L=DHT11_rec_byte(); //接收濕度低八位
T_H=DHT11_rec_byte(); //接收溫度高八位
T_L=DHT11_rec_byte(); //接收溫度低八位
revise=DHT11_rec_byte(); //接收校正位
DHT11_delay_us(25); //結(jié)束
if((R_H+R_L+T_H+T_L)==revise) //校正
{
RH=R_H;
RL=R_L;
TH=T_H;
TL=T_L;
}
/*數(shù)據(jù)處理,方便顯示*/
rec_dat[0]='0'+(RH/10);
rec_dat[1]='0'+(RH%10);
rec_dat[2]='R';
rec_dat[3]='H';
rec_dat[4]=' ';
rec_dat[5]=' ';
rec_dat[6]='0'+(TH/10);
rec_dat[7]='0'+(TH%10);
rec_dat[8]='C';
}
}
void write_com(uchar com)
{
lcdrw= 0;
lcdrs= 0;
P0 = com;
DHT11_delay_ms(5);
lcden=1 ;
DHT11_delay_ms(5);
lcden =0;
}
void write_date(uchar date)
{
lcdrw =0;
lcdrs=1;
P0 =date;
DHT11_delay_ms(5);
lcden =1;
DHT11_delay_ms(5);
lcden =0;
}
void init()
{
dula =0;
wela =0;
lcden=0;
lcdrw=0;
write_com(0x38);//初始化液晶
write_com(0x0f); //不顯示顯示光標(biāo)
write_com(0x0c); //當(dāng)讀或?qū)懸粋(gè)字符后地址指針加一,且光標(biāo)加一
write_com(0x06);// 整屏不左移
write_com(0x01);//刷新一次使其全部清零
//如果指針不賦值,指針默認(rèn)80h
write_com(0x80);//寫指針地址
}
void main()
{
uchar i;
init(); //lcd1602初始化
while(1)
{
DHT11_delay_ms(1500); //DHT11上電后要等待1S以越過不穩(wěn)定狀態(tài)在此期間不能發(fā)送任何指令
DHT11_receive();
write_com(0x80); //從lcd1602第一行第一個(gè)位置開始顯示
for(i=0;i<9;i++)
write_date(rec_dat[i]); //顯示數(shù)據(jù)
}
}
|
|