单片机设计温湿度传感器的设计程序.docx
《单片机设计温湿度传感器的设计程序.docx》由会员分享,可在线阅读,更多相关《单片机设计温湿度传感器的设计程序.docx(16页珍藏版)》请在冰豆网上搜索。
单片机设计温湿度传感器的设计程序
(GDAIB小远制作)
Reg51.h
#ifndef__REG51_H__
#define__REG51_H__
/*BYTERegister*/
sfrP0=0x80;
sfrP1=0x90;
sfrP2=0xA0;
sfrP3=0xB0;
sfrPSW=0xD0;
sfrACC=0xE0;
sfrB=0xF0;
sfrSP=0x81;
sfrDPL=0x82;
sfrDPH=0x83;
sfrPCON=0x87;
sfrTCON=0x88;
sfrTMOD=0x89;
sfrTL0=0x8A;
sfrTL1=0x8B;
sfrTH0=0x8C;
sfrTH1=0x8D;
sfrIE=0xA8;
sfrIP=0xB8;
sfrSCON=0x98;
sfrSBUF=0x99;
/*BITRegister*/
/*PSW*/
sbitCY=0xD7;
sbitAC=0xD6;
sbitF0=0xD5;
sbitRS1=0xD4;
sbitRS0=0xD3;
sbitOV=0xD2;
sbitP=0xD0;
/*TCON*/
sbitTF1=0x8F;
sbitTR1=0x8E;
sbitTF0=0x8D;
sbitTR0=0x8C;
sbitIE1=0x8B;
sbitIT1=0x8A;
sbitIE0=0x89;
sbitIT0=0x88;
/*IE*/
sbitEA=0xAF;
sbitES=0xAC;
sbitET1=0xAB;
sbitEX1=0xAA;
sbitET0=0xA9;
sbitEX0=0xA8;
/*IP*/
sbitPS=0xBC;
sbitPT1=0xBB;
sbitPX1=0xBA;
sbitPT0=0xB9;
sbitPX0=0xB8;
/*P3*/
sbitRD=0xB7;
sbitWR=0xB6;
sbitT1=0xB5;
sbitT0=0xB4;
sbitINT1=0xB3;
sbitINT0=0xB2;
sbitTXD=0xB1;
sbitRXD=0xB0;
/*SCON*/
sbitSM0=0x9F;
sbitSM1=0x9E;
sbitSM2=0x9D;
sbitREN=0x9C;
sbitTB8=0x9B;
sbitRB8=0x9A;
sbitTI=0x99;
sbitRI=0x98;
#endif
Main.h
#ifndef_MAIN_H_
#define_MAIN_H_
#include
#defineucharunsignedchar
#defineuintunsignedint
voiddelay1m(uintx);
voidRH_founction();//温湿度读取子程序
voidinit_1602();//初始化1602函数
voidDHT11_display(ucharadd,ucharshi,ucharge);//温湿度显示函数
voidkey_shidu();
voidkey_wendu();
voidalarm_function();
voidw_string(ucharadd,uchar*p);
#endif
Main.c
//温湿度实时监测显示,超限报警,温度测量范围为0~+50℃;湿度测量范围为20%~90%;
#include"main.h"
sbits1=P1^4;//温度
sbits2=P1^3;//湿度
sbits3=P1^2;//+
sbits4=P1^1;//-
sbits5=P1^0;//确定
sbitalarm=P1^5;//蜂鸣器报警
externucharTH,RH;//温度整数,湿度整数部分
ucharcodeword1[16]={"Myowndesign!
"};
ucharcodeword2[16]={"Tem=CHum=%"};//word2[4]word2[5]Cword2[13]word2[14]%
ucharcodehehe[16]={"SetTemperature!
"};//设置温度上下限界面
ucharcodehaha[16]={"SetHumidity!
"};//设置湿度上下限界面
ucharcodeword3[16]={"up=Cdown=C"};
ucharcodeword4[16]={"up=%down=%"};
ucharw_up=30;w_down=20;//温度上下限
uchars_up=60;s_down=40;//湿度上下限
voidmain()
{
uinti;
init_1602();
delay1m(500);//延时等待1602稳定
RH_founction();
while
(1)
{
key_wendu();//温度上下限调整
key_shidu();//湿度上下限调整
i++;if(i>2000)//动态延时读取温湿度值
{
i=0;RH_founction();//读取温湿度
}
DHT11_display(0xc0+4,TH/10+0x30,TH%10+0x30);//显示温度
DHT11_display(0xc0+13,RH/10+0x30,RH%10+0x30);//显示湿度
if((TH>w_up)||(THs_up)||(RH}
}
//=======================================温度上下限调整函数================================
voidkey_wendu()
{
uchardz[2]={0xc3,0xcd};//温度上下限数据在1602上显示的初始地址
ucharwei;//需要调整的位
ucharbuf[2];//温度上下限缓存,buf[0]温度上限,buf[1]温度下限
uintcounter;//用于产生闪烁效果
if(!
s1)
{
delay1m(3);
if(!
s1)//进入温度设置
{
alarm=1;while(!
s1);wei=0;buf[0]=w_up;buf[1]=w_down;
w_string(0x80,hehe);//发送字符串到LCD第一行
w_string(0xc0,word3);//此句很重要,不写的话,会显示乱码
do
{
counter++;if(counter>4000){counter=0;}//清零
if(counter>2000){DHT11_display(dz[wei],0x20,0x20);}//显示空格
if(counter<=2000){DHT11_display(0xc3,buf[0]/10+0x30,buf[0]%10+0x30);DHT11_display(0xcd,buf[1]/10+0x30,buf[1]%10+0x30);}//显示数据
if(!
s1)//继续按下s1,调整右移
{
while(!
s1);
wei++;if(wei>1){wei=0;}
}
if(!
s3)//加1
{
while(!
s3);
buf[wei]++;if(buf[wei]>50){buf[wei]=0;}
}
if(!
s4)//减1
{
while(!
s4);
buf[wei]--;if(buf[wei]==0xff){buf[wei]=50;}
}
if(buf[0]<=buf[1]){buf[0]=30;buf[1]=20;}//如果温度上限不大于下限,回到初始状态
}while(s5);//按下s5设置确定
w_up=buf[0];w_down=buf[1];w_string(0x80,word1);w_string(0xc0,word2);//发送字符串到LCD第一行
}
}
}
//=======================================湿度上下限调整函数================================
voidkey_shidu()
{
uchardz[2]={0xc3,0xcd};//温度上下限数据在1602上显示的初始地址
ucharwei;//需要调整的位
ucharbuf[2];//湿度上下限缓存,buf[0]湿度上限,buf[1]湿度下限
uintcounter;//用于产生闪烁效果
if(!
s2)
{
delay1m(3);
if(!
s2)//进入湿度设置
{
alarm=1;while(!
s2);wei=0;buf[0]=s_up;buf[1]=s_down;
w_string(0x80,haha);//发送字符串到LCD第一行
w_string(0xc0,word4);//此句很重要,不写的话,会显示乱码
do
{
counter++;if(counter>4000){counter=0;}//清零
if(counter>2000){DHT11_display(dz[wei],0x20,0x20);}//显示空格
if(counter<=2000){DHT11_display(0xc3,buf[0]/10+0x30,buf[0]%10+0x30);DHT11_display(0xcd,buf[1]/10+0x30,buf[1]%10+0x30);}//显示数据
if(!
s1)//继续按下s1,调整右移
{
while(!
s1);
wei++;if(wei>1){wei=0;}
}
if(!
s3)//加1
{
while(!
s3);
buf[wei]++;if(buf[wei]>90){buf[wei]=0;}
}
if(!
s4)//减1
{
while(!
s4);
buf[wei]--;if(buf[wei]<20){buf[wei]=90;}
}
if(buf[0]<=buf[1]){buf[0]=60;buf[1]=40;}//如果湿度上限不大于下限,回到初始状态
}while(s5);//按下s5设置确定
s_up=buf[0];s_down=buf[1];w_string(0x80,word1);w_string(0xc0,word2);//发送字符串到LCD第一行
}
}
}
//======================================ms级延时函数======================================
voiddelay1m(uintx)
{
uintk,j;
for(k=0;kfor(j=0;j<120;j++);//数120次,约1ms
}
1602.c
#include"main.h"
#defineshujuP0//数据脚
sbitrs=P2^7;//数据命令选择端
sbitrw=P2^6;//读写选择端
sbiten=P2^5;//1602使能端
sbitbusy=P0^7;//检测为1,说明1602忙
externucharcodeword1[16];
externucharcodeword2[16];
//=====================读繁忙标记函数===================
voidread_busy()
{
shuju=0xff;//准备读数据
do
{
rs=0;//读状态
rw=1;//读
en=0;
en=1;//使能1602数据读出
}while(busy);
en=0;
}
//=====================写命令函数===========================
voidwrite_cmd(ucharcmd)
{
read_busy();
rs=0;//写指令
rw=0;//写
shuju=cmd;
en=0;
en=1;
en=0;
}
//=======================写数据函数==========================
voidwrite_dat(uchardat)
{
read_busy();
rs=1;//写数据
rw=0;//写
shuju=dat;
en=0;
en=1;
en=0;
}
//========================1602初始化函数=======================
voidinit_1602()
{
write_cmd(0x38);//16*2显示,5*7点阵,8位数据接口
write_cmd(0x0c);//显示开、光标关、光标不允许闪烁
write_cmd(0x06);//文字不动,光标自动右移
write_cmd(0x01);//清屏
w_string(0x80,word1);
w_string(0xc0,word2);
}
//=======================将温湿度数据分成高低位在1602上显示函数==============
voidDHT11_display(ucharad,ucharshi,ucharge)
{
write_cmd(ad);write_dat(shi);write_dat(ge);
}
//================================调整数据的时候,1602显示====================
voidw_string(ucharadd,uchar*p)//发送字符串到LCD
{
uchari;
write_cmd(add);
for(i=0;i<16;i++){write_dat(p[i]);}
}
Dht11.c
#include"main.h"
sbitDQ=P2^0;//dht11数据端
ucharflag;
uchartemp;
ucharTH,TL,RH,RL,check;//温度高低8位,湿度高低8位,校验8位
ucharTH_temp,TL_temp,RH_temp,RL_temp,check_temp;//温度高低8位,湿度高低8位,校验8位缓存
ucharcomdata;
voidDelay(uintj)
{
uchari;
for(;j>0;j--)
{
for(i=0;i<27;i++);
}
}
voidDelay_10us(void)
{
uchari;
i--;i--;i--;
i--;i--;i--;
}
voidCOM(void)
{
uchari;
for(i=0;i<8;i++)
{
flag=2;
while((!
DQ)&&flag++);
Delay_10us();
Delay_10us();
Delay_10us();
temp=0;
if(DQ)temp=1;//判断数据位是0还是1
flag=2;
while((DQ)&&flag++);
if(flag==1)break;//超时则跳出for循环
//如果高电平高过预定0高电平值则数据位为1
comdata<<=1;
comdata|=temp;
}
}
//-----温湿度读取子程序------------
voidRH_founction()
{
DQ=0;
Delay(180);//主机拉低18ms
DQ=1;//总线由上拉电阻拉高主机延时20us
Delay_10us();
Delay_10us();
Delay_10us();
Delay_10us();
DQ=1;//主机设为输入判断从机响应信号
if(!
DQ)//判断从机是否有低电平响应信号如不响应则跳出,响应则向下运行
{
flag=2;
while((!
DQ)&&flag++);//判断从机是否发出80us的低电平响应信号是否结束
flag=2;
while((DQ)&&flag++);//判断从机是否发出80us的高电平,如发出则进入数据接收状态
//数据接收状态
COM();
RH_temp=comdata;
COM();
RL_temp=comdata;
COM();
TH_temp=comdata;
COM();
TL_temp=comdata;
COM();
check_temp=comdata;
DQ=1;
temp=(TH_temp+TL_temp+RH_temp+RL_temp);//数据校验
if(temp==check_temp)
{
RH=RH_temp;
RL=RL_temp;
TH=TH_temp;
TL=TL_temp;
check=check_temp;
}
}
}