|
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define SIZE 5//用來標(biāo)識數(shù)組元素個(gè)數(shù)
sbit dht11=P2^1;//dht11為dht模塊數(shù)據(jù)位
sbit lcden =P3^4;//1602使能
sbit lcdrs =P3^5;//1602數(shù)據(jù)or命令寫選擇口
sbit dula = P2^6;
sbit wela = P2^7;
uchar code table[]={'0','1','2','3','4','5','6','7','8','9'};
uchar datas[SIZE];//存放值的數(shù)組
uchar temp_hvalue,temp_lvalue,humi_hvalue,humi_lvalue,FLAG,RTFLAG;
void delay(uint z)//1ms延時(shí)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void Delay10us() //@11.0592MHz
{
uchar i;
i--;
i--;
i--;
i--;
i--;
i--;
}
uchar dht11_readvalue()//讀一個(gè)字節(jié)
{
uchar value,temp1,i;
for(i=0;i<8;i++)
{
temp1=0;
FLAG=2;
while((!dht11)&&FLAG++);//等待50us的低電平結(jié)束,若超時(shí)間,F(xiàn)LAG溢出后自加1,變?yōu)?
Delay10us();
Delay10us();
Delay10us(); //延時(shí)30us后判斷是高電平還是低電平,以此判斷該位數(shù)據(jù)是0還是1
if(dht11)
temp1=1; // 如果dht11為1,則代表為高電平,則該位數(shù)據(jù)為1
while((dht11)&&FLAG++);//等待該次高電平剩余50us結(jié)束,變?yōu)?后跳出循環(huán),若超時(shí),F(xiàn)LAG變?yōu)?
if(FLAG==1)
break;
value<<=1;
value|=temp1;
}
return(value);//八次循環(huán)結(jié)束后,返回value的八位數(shù)據(jù)
}
uchar dht11_readtempandhumi()//讀一次的數(shù)據(jù),共五個(gè)字節(jié),溫濕度和校驗(yàn)
{
uchar i,temp;//temp用來檢測前四byte之和是否為第五byte
dht11=0;//拉低數(shù)據(jù)線大于18ms,主機(jī)發(fā)送開始信號
delay(25);
dht11=1;//釋放數(shù)據(jù)線,用于檢測之后的從機(jī)80us低電平應(yīng)答信號
Delay10us();
Delay10us();
Delay10us();
Delay10us();//延時(shí)40us檢測應(yīng)答信號
dht11=1;//主機(jī)設(shè)為輸入,判斷從機(jī)響應(yīng)信號,響應(yīng)信號為80us低電平
if(!dht11)//檢測到低電平,若沒有,則不執(zhí)行if
{
FLAG=2;
while((!dht11)&&FLAG++);//判斷從機(jī)是否發(fā)出 80us 的低電平響應(yīng)信號是否結(jié)束
if(FLAG==1)
return 0;
FLAG=2;
while((dht11)&&FLAG++);//判斷從機(jī)是否發(fā)出 80us 的高電平信號是否結(jié)束
if(FLAG==1)
return 0;
for(i=0;i<SIZE;i++)//數(shù)據(jù)接收狀態(tài)
{
datas[i]=dht11_readvalue();
}
dht11=1; //釋放數(shù)據(jù)總線,為下一次傳輸做準(zhǔn)備
temp=(datas[0]+datas[1]+datas[2]+datas[3]);//temp為檢測
if(temp==datas[4]) //數(shù)據(jù)校驗(yàn)
{
RTFLAG=1;
}
if(RTFLAG==1)
{
RTFLAG=0;
humi_hvalue=datas[0];
humi_lvalue=datas[1];
temp_hvalue=datas[2];
temp_lvalue=datas[3];
}
}
}
void write_com(uchar com)//1602寫命令
{
lcdrs=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_data(uchar date)//1602寫數(shù)據(jù)
{
lcdrs=1;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init()//1602初始化
{
dula=0;
wela=0;
lcden=0;
write_com(0x38);
delay(1);
write_com(0x0c);
delay(1);
write_com(0x06);
delay(1);
write_com(0x01);
delay(1);
}
void LCD_Display()
{
//液晶顯示第一行:溫度顯示;
write_com(0x0c);
write_com(0x80+0x01);delay(5);
write_data('T');delay(5);
write_data('e');delay(5);
write_data('m');delay(5);
write_data(':');delay(5);
write_com(0x86);delay(5);
write_data(table[(temp_hvalue/10)]);delay(5); //輸出溫度的十位
write_data(table[(temp_hvalue%10)]);delay(5); //輸出溫度的個(gè)位
write_data('.');delay(5);
write_data(table[(temp_lvalue/10)]);delay(5);
write_data(table[(temp_lvalue%10)]);delay(5);
write_com(0x8c);delay(5);
write_data(0xdf);delay(5); //輸出℃
write_data(0x43);delay(5);
//液晶第二行:濕度顯示;
write_com(0x80+0x41);delay(5);
write_data('H');delay(5);
write_data('u');delay(5);
write_data('m');delay(5);
write_data(':');delay(5);
write_com(0xc6);delay(5);
write_data(table[(humi_hvalue/10)]);delay(5); //輸出濕度的十位
write_data(table[(humi_hvalue%10)]);delay(5); //輸出濕度的個(gè)位
write_data('.');delay(5);
write_data(table[(humi_lvalue/10)]);delay(5);
write_data(table[(humi_lvalue%10)]);delay(5);
write_com(0xcc);delay(5);
write_data('%');delay(5);
}
void main()
{
init();
delay(1000);
while(1)
{
delay(1000);
dht11_readvalue();
dht11_readtempandhumi();
delay(1000);
LCD_Display();
}
}
|
評分
-
查看全部評分
|