温湿度判断控制部分的程序整体思路如图18
实际值与给定值比较调用控制声光报警是否在给定范围内返回 图18 温湿度判断控制程序整体思路
4.4 1602液晶显示模块
本系统采用1602液晶显示温湿度值,当系统刚开始上电时1602液晶不显示任何数据,等待AM2301的监测数据,双行显示在1602液晶上。第一行显示:Temperature:--。C,第二行显示:Humidity: --%
4.5报警模块
报警模块具备两项功能,即为报警灯和声音报警。报警灯模块是完成LED有规律的转换,以便从视觉上提醒用户。LED是由单片机控制2个双色LED灯组成的,其转换规律为:
1 系统温湿度值在给定的范围时,绿色LED亮。 2 系统温湿度值超出给定的范围时,红色LED亮。
在LED灯转换的同时,声音报警也会同时启动,可采用延时的方式来延长声音报警的声音。
警报灯由2个双色的LED灯组成,一共需要2根数据线,使用单片机控制。要实现的功能是使2个双色LED灯有规律的转换,当系统上电后,系统进行实时的采样,并判断出当前温湿度与给定温湿度之间的差异,如果当前温湿度低于用户给定的下限温湿度值,则说明当前温湿度过低,系统自动启动红色警报灯,同时开始加温増湿,直至加到所需温湿度值时警报灯熄灭。反之,如果当前温湿度高于用户设定的上限温湿度值,则说明当前温湿度过高,系统也会自动启动警报灯,同时开始降温减湿,直至降到所需温湿度值时警报
17
灯熄灭。
4.6 系统整体软件程序
本系统采用C语言编程,使用单片机编程软件:Keil软件[11]。
#include
#define uchar unsigned char #define uint unsigned int
uint hum,temp; //定义湿度、温度(全局)
uchar hum_h,hum_l,temp_h,temp_l,check; //湿度高、低8位,温度高、低8位,校验位 uchar num,num1, bai,shi,ge,bai1,shi1,ge1,cnt=0; // sbit dht=P1^0; sbit fine=P1^1; sbit hot=P1^2; sbit pwq=P1^3; sbit ccq=P1^4; sbit beef=P2^7; sbit redled=P2^6; sbit greedled=P2^5; sbit lcden=P3^4; sbit lcdrs=P3^5;
uchar code table[]=%uchar code table1[]=\void write_com(uchar com); void write_data(uchar date); void delay_us(uint i); void delay(uint z); void dht_init(); void interrupt_init(); void lcd_int(); uchar read_byte(); void read_hum_temp(); void zhuanhuan(); void warm_control(); void main()//主函数 { interrupt_init(); lcd_int(); delay(200); while(1) { read_hum_temp();
zhuanhuan();
18
warm_control();
delay(3000); //此处的时间不能小于3000,否则读不出! //
hum_h=hum_l=temp_h=temp_l=check=temp=hum=0;
}
}
/*--------------------延时(10us级)------------------*/ void delay_us(uint i) {
while(i--);
}
/*--------------------延时(ms级)------------------*/ void delay(uint z) { uint i,j; for(i=z;i>0;i--)
for(j=110;j>0;j--);
}
/*--------------温湿度初始化(准备传送数据)----------*/ void dht_init() {
// delay(1000); //延时一会,避开不稳定区域 dht=0; //拉低延时500微秒,发送开始信号 delay_us(50);
dht=1; //释放总线,延时30微秒 delay_us(4);
while(!dht); //拉低等待
while(dht); //拉高等待,即将传送数据 }
uchar read_byte() { uchar n,byte=0,dat; for(n=0;n<8;n++) {
while(!dht); delay_us(4); //理论上28us<延时<70us,此处写2--6都可以 dat=0;
if(dht) dat=1; while(dht);
byte=(byte<<=1)|dat; //0
}
return byte;
19
}
/*----------------------读40位数据---------------------*/ void read_hum_temp()
{ dht_init();
hum_h=read_byte(); //读湿度 hum_l=read_byte();
temp_h=read_byte(); //读温度 temp_l=read_byte(); check=read_byte(); //读校验 while(!dht); //等待低电平结束 dht=1;
//最后拉高总线
}
void zhuanhuan() //提取各位数字
{ uchar a;
a=hum_h+hum_l+temp_h+temp_l; if(a==check) {
//
P1=temp_l; hum=temp=0;
hum=((hum|hum_h)<<8)|hum_l; temp=((temp|temp_h)<<8)|temp_l; bai=temp/100;
shi=temp0/10; ge=temp; bai1=hum/100; shi1=hum0/10; ge1=hum; }
else bai=shi=ge=bai1=shi1=ge1=0;
}
/*----------------------中断初始化---------------------*/ void interrupt_init() { TMOD=0X01;
TH0=(65536-10000)/256;
TL0=(65536-10000)%6; EA=1; ET0=1;
TR0=1;
20
}
/*----------------------中断处理液晶显示函数---------------------*/ void timer0() interrupt 1 { TH0=(65536-10000)/256; TL0=(65536-10000)%6; if(cnt==2) {
for(num=0;num<13;num++) { write_data(table[num]); delay(20);
}
write_data(bai); write_data(shi); write_data(ge); write_data('C'); write_com(0x80+0x40); for(num1=0;num1<10;num1++) { write_data(table1[num1]); delay(20);
}
write_data(bai1); write_data(shi1); write_data(ge1);
write_data('%');
cnt=0;
}cnt++;
}
/*--------------------液晶控制------------------*/ void lcd_int()//lcd初始化 { lcden=0; write_com(0x38); write_com(0x0e); write_com(0x06); write_com(0x80); }
void write_com(uchar com) // lcd写指令 {
lcdrs=0; 21