基于51单片机的温湿度测量仪课程设计代码
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include
#include
#define uchar unsigned char
#define uint unsigned int
#define LCD_DB P2
uchar Seg_Tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x39,0x76,0x77,0x63};
//uchar Seg1_Tab[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};
uchar Dig_Tab[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
uchar temp_H,temp_L,humi_H,humi_L;
uchar value,check,bt,sum,bt_temp,keynum,flag;
uchar tH,tL,hH,hL,RHH,RHL,HT,LT;
uchar warning_RHHL[2]={65,20};
uchar warning_THL[2]={25,16};
uchar m,n,d1,d2,d3,d4,d5,d6;
uchar TD=0;
uchar s1[5];
uchar s2[5];
sbit Segce=P1^0;
sbit Digce=P1^1;
sbit Keyce=P1^3;
sbit LCD_RS=P1^4;
sbit LCD_RW=P1^5;
sbit LCD_E=P1^6;
sbit DHT11=P1^7;
sbit HXD=P1^2;
//******************延时函数部分****************
void Delay(uint j) //(j/10)ms
{
uchar i;
for(;j>0;j--)
{
for(i=0;i<27;i++);
}
}
void Delay_10us(void) //10us
{
uchar i;
i--;
i--;
i--;
i--;
i--;
i--;
}
void delay_n40us(uint n)
{
uint i;
uchar j;
for(i=n;i>0;i--)
for(j=0;j<2;j++);
}
//***************DHT11数据接收处理与数码管显示部分*************
void inter_init() //初始化函数
{
P0=0;
P1=0x0c;
TMOD=0x01;
TH0=-50000/256;
TL0=-50000%256;
EA=1;
ET0=1;
}
void COM(void) //DHT11的bit读取
{
uchar i;
for(i=0;i<8;i++)
{
flag=2;
while((!DHT11)&&flag++);
Delay_10us();
Delay_10us();
Delay_10us();
bt=0;
if(DHT11)bt=1;
flag=2;
while((DHT11)&&flag++);
//超时则跳出for循环
if(flag==1)break;
//判断数据位是0还是1
// 如果高电平高过预定0高电平值则数据位为 1
value<<=1; //DHT11数据是从高位开始传的,于是用左移,进行数据处理
value|=bt;
}
}
void RH(void) //DHT11的数据读取
{
//主机拉低18ms
DHT11=0;
Delay(180);
DHT11=1;
//总线由上拉电阻拉高 主机延时20us
Delay_10us();
Delay_10us();
Delay_10us();
Delay_10us();
//主机设为输入 判断从机响应信号
DHT11=1;
//判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行
if(!DHT11) //T !
{
flag=2;
//判断从机是否发出 80us 的低电平响应信号是否结束
while((!DHT11)&&flag++);
flag=2;
//判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
while((DHT11)&&flag++);
//数据接收状态
COM();
humi_H=value; //第一次出湿度的整数值
COM();
humi_L=value; //第二次出湿度的小数值
COM();
temp_H=value; //第三次出温度的整数值
COM();
temp_L=value; //第四次出温度的小数值
COM();
check=value; // 第
五次出效验码
DHT11=1;
//数据校验
bt=(humi_H+humi_L+temp_H+temp_L);//当前四次数据相加等于第五次的效验码时,数据正确
if(bt==check)
{
hH=humi_H;
hL=humi_L;
tH=temp_H;
tL=temp_L;
bt_temp=bt;
}
}
}
void deal() //数据处理函数
{
m=tH; //温度整数位
d1=m/10; //温度十位
d2=m%10; //温度个位
n=hH; //湿度整数位
d3=n/10; //湿度十位
d4=n%10; //湿度个位
d5=tL/10; //温度小数位
d6=hL/10; //湿度小数位
if(n>= warning_RHHL[0])
RHH=1 ;
else RHH=0; //湿度与最大值相比
if(n<= warning_RHHL[1])
RHL=1 ;
else RHL=0; //湿度与最小值相比
if(m>= warning_THL[0])
HT=1 ;
else HT=0; //温度与最大值相比
if(m<= warning_THL[1])
LT=1 ;
else LT=0; //温度与最小值相比
s1[0] = (char)(0X30+d3);
s1[1] = (char)(0X30+d4); //湿度整数部分
s1[2] = (char)(0X30+d6); //湿度小数部分
s2[0] = (char)(0X30+d1);
s2[1] = (char)(0X30+d2); //温度整数部分
s2[2] = (char)(0X30+d5); //温度小数部分
}
void warning() //报警函数
{
uchar i;
HXD=1; //蜂鸣器不报警
if((RHH||RHL)&&(HT||LT))
{
for(i=0;i<5;i++)
{
HXD=0;
Delay(2000);
HXD=1;
Delay(2000);
HXD=0;
Delay(2000);
HXD=1; //温湿度都超标时,频率1报警
}
}
else if((RHH||RHL)||(HT&<))
{
for(i=0;i<5;i++)
{
HXD=0;
Delay(1000);
HXD=1;
Delay(1000);
HXD=0;
Delay(1000);
HXD=1; // 只有湿度超标时,频率2报警
}
}
else if((RHH&&RHL)||(HT||LT))
{
for(i=0;i<5;i++)
{
HXD=0;
Delay(500);
HXD=1;
Delay(500);
HXD=0;
Delay(500);
HXD=1;
} // 只有温度超标时,频率3报警
} // 蜂鸣器报警
}
void display() //数码管显示函数
{
uint j=0;
P0=0XFF;Digce=1;Digce=0;
P0=Seg_Tab[10];Segce=1; Segce=0;
P0=Dig_Tab[4];Digce=1;Digce=0;for(j=0;j<500;j++);
P0=0XFF;Digce=1;Digce=0;
P0=Seg_Tab[11]; Segce=1;Segce=0;
P0=Dig_Tab[0];Digce=1;Digce=0;for(j=0;j<500;j++);
P0=0XFF;Digce=1;Digce=0;
P0=Seg_Tab[12];Segce=1;Segce=0;
P0=Dig_Tab[1];Digce=1;Digce=0;for(j=0;j<500;j++);
P0=0XFF;Digce=1;Digce=0;
P0=Seg_Tab[d4];Segce=1;Segce=0;
P0=Dig_Tab[2];Digce=1;Digce=0;for(j=0;j<500;j++);
P0=Seg_Tab[d3];Segce=1;Segce=0;
P0=Dig_Tab[3];Digce=1;Digce=0;for(j=0;j<500;j++);
P0=Seg_Tab[13];Segce=1;Segce=0;
P0=Dig_Tab[5];Digce=1;Digce=0;for(j=0;j<500;j++);
P0=0XFF;Digce=1;Digce=0;
P0=Seg_Tab[d2];Segce=1;Segce=0;
P0=Dig_Tab[6];Digce=1;Digce=0;for(j=0;j<500;j++);
P0=0XFF;Digce=1;Digce=0;
P
0=Seg_Tab[d1];Segce=1;Segce=0;
P0=Dig_Tab[7];Digce=1;Digce=0;for(j=0;j<500;j++);
}
//**************LCD液晶屏函数部分*************
void LCD_write_command(uchar dat) //写指令
{
LCD_DB=dat;
LCD_RS=0;//指令
LCD_RW=0;//写入
LCD_E=1;//允许
delay_n40us(1);
LCD_E=0;
delay_n40us(1);
}
void LCD_write_data(uchar dat) //写数据
{
LCD_DB=dat;
LCD_RS=1;//数据
LCD_RW=0;//写入
LCD_E=1;//允许
delay_n40us(1);
LCD_E=0;
delay_n40us(1);
}
void LCD_disp_char(uchar x,uchar y,uchar dat) //字符显示
{
uchar address;
if(y==1)
address=0x80+x;
else
address=0xc0+x;
LCD_write_command(address);
LCD_write_data(dat);
}
void LCD_init(void) //液晶屏初始化
{
LCD_write_command(0x38);//设置 8 位格式,2 行,5x7
LCD_write_command(0x0c);//整体显示,关光标,不闪烁
LCD_write_command(0x06);//设定输入方式,增量不移位
LCD_write_command(0x03);//清除屏幕显示
delay_n40us(100);
}
void LCD_display() //LCD液晶屏显示
{
LCD_disp_char(0,1,'s');LCD_disp_char(1,1,'h');LCD_disp_char(2,1,'i');
LCD_disp_char(3,1,'d');LCD_disp_char(4,1,'u');LCD_disp_char(5,1,':');
LCD_disp_char(6,1,s1[0]);LCD_disp_char(7,1,s1[1]);LCD_disp_char(8,1,'.');
LCD_disp_char(9,1,s1[2]);LCD_disp_char(10,1,'%');LCD_disp_char(11,1,'R');
LCD_disp_char(12,1,'H');//湿度的表示
LCD_disp_char(0,2,'w');LCD_disp_char(1,2,'e');LCD_disp_char(2,2,'n');
LCD_disp_char(3,2,'d');LCD_disp_char(4,2,'u');LCD_disp_char(5,2,':');
LCD_disp_char(6,2,s2[0]); LCD_disp_char(7,2,s2[1]);LCD_disp_char(8,2,'.');
LCD_disp_char(9,2,s2[2]); LCD_disp_char(10,2,0xDF);LCD_disp_char(11,2,'C'); //温度的表示
}
//***********主函数部分***********
void main()
{
inter_init();
LCD_init();
Delay(4);
while(1)
{
RH();
deal();
LCD_display();
warning();
TR0=1;
while((TD>=1)&&(TD<=100))
{
display();
}
}
}
timer0() interrupt 1
{
TD++;
if(TD>=100)
{
TH0=-50000/256;
TL0=-50000%256;
TR0=0;
TD=0;
}
TH0=-50000/256;
TL0=-50000%256;
}