温湿度检测器DHT11程序及显示程序.docx
《温湿度检测器DHT11程序及显示程序.docx》由会员分享,可在线阅读,更多相关《温湿度检测器DHT11程序及显示程序.docx(15页珍藏版)》请在冰豆网上搜索。
![温湿度检测器DHT11程序及显示程序.docx](https://file1.bdocx.com/fileroot1/2023-1/22/9fcca983-e383-4be1-9627-d81f01206865/9fcca983-e383-4be1-9627-d81f012068651.gif)
温湿度检测器DHT11程序及显示程序
附录1:
#include
#include
#include"DHT11.H"
#include"DHT11.C"
unsignedcharrange[4]={55,75,10,30};//温湿度上下限初值
unsignedcharHumi_Temp_Tab[8]={6,9,0,0,7,8,0,0};//数码管显示初值
unsignedcharnumt1=0;//T1中断计数标志
unsignedcharnumt0=0;
unsignedcharcodeTab_Seg[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//数码管段码0-9
unsignedcharcodeTab_Dig[8]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
//位选第一位到第八位
unsignedcharcodeunits[4]={0x39,0x71,0x77,0x76};//单位C/F/RH
/**********************************************/
/*温湿度采集函数*/
/**********************************************/
voidgetdata()
{
if(start_DHT11())
{
read_DHT11();
}
if(check_sum())
{
Humi_Temp_Tab[0]=DHT_data.DH_H/10;
Humi_Temp_Tab[1]=DHT_data.DH_H%10;
Humi_Temp_Tab[2]=DHT_data.DH_L/10;//存储湿度数据
if(flag==0)
{
Humi_Temp_Tab[4]=DHT_data.T_H/10;
Humi_Temp_Tab[5]=DHT_data.T_H%10;
Humi_Temp_Tab[6]=DHT_data.T_L/10;
//存储摄氏温度数据
}
else
{
Humi_Temp_Tab[4]=(9*DHT_data.T_H/5+32)/10;
Humi_Temp_Tab[5]=(9*DHT_data.T_H/5+32)%10;
Humi_Temp_Tab[6]=(18*DHT_data.T_H+320)%100%10;//存储华氏温度数据
}
}
}
/**********************************************/
/*主函数*/
/**********************************************/
voidmain()
{
delay_ms(500);//先进行延时等待进入稳定状态
P0=0;
P1=0x0C;//初始化P1口
EA=0;
TR1=0;
TR0=0;
TMOD=0x11;//设置定时器T0和T1,且工作方式都为方式1
TH1=(65536-5000)/256;
TL1=(65536-5000)%256;
TH0=(65536-2000)/256;
TL0=(65536-2000)%256;//设定初值2ms
TR1=1;
TR0=1;
EA=1;
ET0=1;
ET1=1;//打开中断定时器T0和T1
PT1=0;
PT0=1;//强制设置优先级
delay_ms(1000);
while
(1)
{
if(DHT_data.DH_H{
bee=0;
delay_ms(100);
bee=1;
delay_ms(100);
}
if(DHT_data.DH_H>range[1])//湿度大于上限
{
bee=0;
delay_ms(100);
bee=1;
delay_ms(100);
}
if(DHT_data.T_H{
bee=0;
delay_ms(10);
bee=1;
delay_ms(10);
}
if(DHT_data.T_H>range[3])//温度大于上限
{
bee=0;
delay_ms(10);
bee=1;
delay_ms(10);
}
}
}
/**********************************************/
/*定时器T0中断*/
/**********************************************/
voidT0_timer()interrupt1
{
unsignedcharKData=0x00;
TR0=0;//进入T0后将T0中断关闭
TH0=(65536-2000)/256;
TL0=(65536-2000)%256;
switch(numt0)
{
case0:
P0=0;Seg_ce=1;Seg_ce=0;//段选开关
if(flag2==1)
P0=Tab_Seg[range[0]/10];
//显示湿度下限的十位
else
P0=Tab_Seg[Humi_Temp_Tab[0]];
//显示读取的湿度的十位
Seg_ce=1;Seg_ce=0;
P0=Tab_Dig[0];//位选第一位
Dig_ce=1;Dig_ce=0;
numt0++;break;
case1:
P0=0;Seg_ce=1;Seg_ce=0;
if(flag2==1)
P0=Tab_Seg[range[0]%10];
//显示湿度下限的个位
else
P0=Tab_Seg[Humi_Temp_Tab[1]];
//显示读取的湿度的个位
Seg_ce=1;Seg_ce=0;
P0=Tab_Dig[1];//位选第二位
Dig_ce=1;Dig_ce=0;
numt0++;break;
case2:
P0=0;Seg_ce=1;Seg_ce=0;
if(flag2==1)
P0=Tab_Seg[range[1]/10];
//显示湿度上限的十位
else
P0=units[2];
//显示单位R
Seg_ce=1;Seg_ce=0;
P0=Tab_Dig[2];//位选第三位
Dig_ce=1;Dig_ce=0;
numt0++;break;
case3:
P0=0;Seg_ce=1;Seg_ce=0;
if(flag2==1)
P0=Tab_Seg[range[1]%10];
//显示湿度上限的个位
else
P0=units[3];//显示单位H
Seg_ce=1;Seg_ce=0;
P0=Tab_Dig[3];//位选第四位
Dig_ce=1;Dig_ce=0;
numt0++;break;
case4:
P0=0;Seg_ce=1;Seg_ce=0;
P0=Tab_Dig[4];
//位选第五位,且同时拉低键盘第四行
Dig_ce=1;Dig_ce=0;
Key_ce=0;
KData=P0;//扫描键盘第四行
switch(KData)
{
case0xfe:
case0xfd:
case0xfb:
case0xf7:
default:
break;
}
while(KData!
=0xff)
{
KData=P0;
}
Key_ce=1;
if(flag2==1)
P0=Tab_Seg[range[2]/10];
//显示温度下限的十位
else
P0=Tab_Seg[Humi_Temp_Tab[4]];//显示读取的温度的十位
Seg_ce=1;Seg_ce=0;
numt0++;break;
case5:
P0=0;Seg_ce=1;Seg_ce=0;
P0=Tab_Dig[5];
//位选第六位,且同时拉低键盘第三行
Dig_ce=1;Dig_ce=0;
Key_ce=0;
KData=P0;
//扫描键盘第三行
switch(KData)
{
case0xfe:
if(range[0]range[0]++;break;//湿度下限加
case0xfd:
if(range[1]<90&&flag2==1)range[1]++;break;//湿度上限加
case0xfb:
if(range[2]range[2]++;break;//温度下限加
case0xf7:
if(range[3]<50&&flag2==1)range[3]++;break;//温度上限加
default:
break;
}
while(KData!
=0xff)
{
KData=P0;
}
Key_ce=1;
if(flag2==1)
P0=Tab_Seg[range[2]%10];//显示温度下限的个位
else
P0=Tab_Seg[Humi_Temp_Tab[5]]-0x80;
//显示读取温度的个位(带小数点的)
Seg_ce=1;Seg_ce=0;
numt0++;break;
case6:
P0=0;Seg_ce=1;Seg_ce=0;
P0=Tab_Dig[6];
//位选第七位,且同时拉低键盘第二行
Dig_ce=1;Dig_ce=0;
Key_ce=0;
KData=P0;//扫描键盘第二行
switch(KData)
{
case0xfe:
if(range[0]>20&&flag2==1)
range[0]--;break;//湿度下限减
case0xfd:
if(range[0]range[1]--;break;//湿度上限减
case0xfb:
if(range[2]>0&&flag2==1)
range[2]--;break;//温度下限减
case0xf7:
if(range[2]range[3]--;break;//温度上限减
default:
break;
}
while(KData!
=0xff)
{
KData=P0;
}
Key_ce=1;
if(flag2==1)
P0=Tab_Seg[range[3]/10];
//显示温度上限的十位
else
P0=Tab_Seg[Humi_Temp_Tab[6]];//显示读取温度的小数位的十位
Seg_ce=1;Seg_ce=0;
numt0++;break;
case7:
P0=0;Seg_ce=1;Seg_ce=0;
P0=Tab_Dig[7];
//位选第八位,且同时拉低键盘第一行
Dig_ce=1;Dig_ce=0;
Key_ce=0;
KData=P0;//扫描键盘第一行
switch(KData)
{
case0xfe:
flag2=~flag2;TR1=~TR1;break;//进入和退出限制调整模式
case0xfd:
flag=~flag;break;
//进行华氏摄氏温度的转换设置
case0xfb:
case0xf7:
default:
break;
}
while(KData!
=0xff)
{
KData=P0;
}
Key_ce=1;
if(flag==0&&flag2==0)
P0=units[0];//显示单位C
elseif(flag==1&&flag2==0)
P0=units[1];//显示单位F
elseif(flag2==1)
P0=Tab_Seg[range[3]%10];//显示温度上限的个位
Seg_ce=1;Seg_ce=0;
numt0=0;break;
default:
numt0=0;break;
}
TR0=1;//打开T0
}
/**********************************************/
/*定时器T1中断*/
/**********************************************/
voidT1_timer()interrupt3
{
TR1=0;//关闭T0
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
if(numt1==25)
{
getdata();//采集数据
numt1=0;
}
else
numt1++;
TR1=1;//打开T0
}
#ifndef__DHT11_h__
#define__DHT11_h__
#include
/**********************************************/
/*引脚定义*/
/**********************************************/
sbitDHT_bus=P2^0;//DHT11数据传输口
sbitKey_ce=P1^3;//按键输出使能
sbitSeg_ce=P1^0;//段选位
sbitDig_ce=P1^1;//位选位
sbitbee=P2^1;//蜂鸣器控制口
/**********************************************/
/*函数声明*/
/**********************************************/
bitstart_DHT11(void);//开始
voidread_DHT11(void);//读取
voiddelay_20us(void);//20us延时
voiddelay_ms(unsignedcharm);//Nms延时
bitcheck_sum(void);//和校验
/**********************************************/
/*宏定义*/
/**********************************************/
#defineHIGH1
#defineLOW0
/**********************************************/
/*变量定义*/
/**********************************************/
#defineDHT_timeover5//高电平维持时间,用于识别“数据0”和“数据1”
bitflag2=0;//设置调节上下限模式转换标志
bitflag=0;//设置摄氏和华氏温度模式转换标志
/**********************************************/
/*结构体*/
/**********************************************/
structDHT_data
{
unsignedcharDH_H;//湿度整数
unsignedcharDH_L;//湿度小数
unsignedcharT_H;//温度整数
unsignedcharT_L;//温度小数
unsignedcharChecksum;//校验和
}DHT_data;
#endif
#include"DHT11.h"
#include
/**********************************************/
/*开始DHT11温湿度计*/
/*输入:
无*/
/*输出:
应答标志0:
应答失败1:
应答成功*/
/**********************************************/
bitstart_DHT11(void)
{
bitDHT_start;
DHT_start=0;
DHT_bus=HIGH;
DHT_bus=LOW;//拉低18ms以上
delay_ms(18);
TR0=0;
DHT_bus=HIGH;
delay_20us();
delay_20us();//拉高20~40us
while(!
DHT_bus)
{
DHT_start=1;
}//DHT应答,DHT拉低80us后拉高80us,然后开始传输数据
//数据(40bit)=8bit湿度整数+8bit湿度小数+8bit温度整数+8bit
温度小数+8bit校验和
while(DHT_bus){};
return(DHT_start);//应答成功返回1
}
/**********************************************/
/*读取DHT11温湿度计*/
/*读取结果存在DHT_data结构体内*/
/*输入:
无输出:
无*/
/**********************************************/
voidread_DHT11(void)
{
unsignedcharm,n,timer_dht;
unsignedchar*p;
p=&DHT_data.DH_H;//数据放在DHT_date的结构体中
for(m=0;m<5;m++)
{
for(n=0;n<8;n++)
{
while(~DHT_bus);//DHT拉低12-14us表示1bit数据开始
timer_dht=0x00;
while(DHT_bus)//随后DHT拉高总线,单片机通过高电
平维持的时间判断“数据0”还是“数据1”
{//数据0维持26~28us高电平,数据1维持116~118us高电平
timer_dht++;//由于此处对延时时间的
长度要求很高,所以采用另一种办法判断
}
if(timer_dht>DHT_timeover)
{
*p<<=1;
*p|=0x01;
}
else
{
*p<<=1;
*p&=0xfe;
}
}
p++;
}
TR0=1;
}
/**********************************************/
/*20us精确延时*/
/*51用在12Mhz晶振下*/
/*调用函数使用LCALL和RET指令,共花费4个周期*/
/*因此只有16个NOP*/
/**********************************************/
voiddelay_20us(void)
{
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();
}
/**********************************************/
/*Nms延时*/
/*while()额外占用约5周期*/
/*因此内层while(40--)20us大约1ms*/
/*Nms延时函数(未测试)