本设计中设定报警上限温度30℃,报警下限温度20℃。图中分别是温度超过30℃和低于20℃时LED灯模拟制冷和制热系统开启,并且蜂鸣器报警。
附录2:单片机程序
#include<reg52.h>#define uchar unsigned char#define uint unsigned intsbit d1=P2^2;sbit d2=P2^1;sbit d3=P2^0;sbit d4=P2^3;sbit key1=P1^3;sbit key2=P1^4;sbit key3=P1^5;sbit led1=P1^0;sbit led2=P1^1;sbit baojing=P1^6;sbit DS=P1^2;sbit ACC_7=ACC^7;uint count=300,alarm=200; //最初温度上下限值:30度、20度uchar shu;uchar shi,fen,ri,yue,nian,xq,miao,ss; uint temp; // 定义温度变量uchar flag;uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //共阳数码管不带小数点的0~9编码uchar code tab1[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; //带小数点的0~9编码void send_int(void){ TMOD = 0x21; // 定时器1工作于8位自动重载模式, 用于产生波特率 TH1 = 0xfd; // 波特率9600 TL1 = 0xfd; TH0=0xD8; //定时器0定时10ms TL0=0xF0; ET0=1; //允许定时器0中断 ES=1; //允许串口中断 EA=1; //开中断SCON = 0xd8; // 设定串行口工作方式 PCON = 0x00; // 波特率不倍增} void delay(uint z){ uint x,y; for(x=z;x>0;x--) for(y=120;y>0;y--);}void dsreset() //复位{ uint i; DS=0; i=103; while(i>0)i--; DS=1; i=4; while(i>0)i--;}uchar tmpread() //读取一字节{ uchar j,k,dat; uint i; for(j=1;j<=8;j++) { DS=0;i++; //延时 DS=1;i++;i++; k=DS; i=8;while(i>0)i--; dat=(k<<7)|(dat>>1);//读出的数据最低位在最前面存一个字节在DAT里 } return(dat);}void tmpwritebyte(uchar dat) //写一个字节{ uint i; uchar j; bit testb; for(j=1;j<=8;j++) { testb=dat&0x01; dat=dat>>1; if(testb) //写 1 { DS=0; i++;i++; DS=1; i=8;while(i>0)i--; } else { DS=0; //写 0 i=8;while(i>0)i--; DS=1; i++;i++; } }}void tmpchange() //DS18B20温度变换{ dsreset(); delay(1); tmpwritebyte(0xcc); //跳过读取内存rom tmpwritebyte(0x44); //开始转换}uint tmp() //读取温度{ float tt; uchar a,b; dsreset(); delay(1); tmpwritebyte(0xcc); tmpwritebyte(0xbe); a=tmpread(); //a为低字节8位 b=tmpread(); //b为高字节8位 temp=b; //temp为温度值UINT 16bit temp<<=8; //两个字节组合到一起 temp=temp|a; if(b>127) { flag=1; ss=flag; temp=~temp+1; } tt=temp*0.0625; // temp/16 则是温度的真实值tt.7位整数,4位小数 temp=tt*10+0.5; // 扩大十倍取出了第一位小数 return(temp);} /*****温度显示********/void displayTemp(uint temp) { uchar ge,shi,bai,qian,ser; d1=0; d1=0; d3=0; d4=0; dsreset(); ser=temp/10; //分离出三位要显示的数字 SBUF=ser; qian=temp/1000; bai=temp/100%10; // 百位数字 shi=temp/10%10; // 十位数字 ge=temp%10; // 个位数字 if(flag==1) { flag=0; P0=0xbf; d1=1; delay(2); d1=0; } if(qian!=0) { P0=tab[qian]; d1=1; delay(2); d1=0; } else { P0=0xff; d1=1; delay(2); d1=0; } if(temp>99) { P0=tab[bai]; d2=1; delay(2); d2=0; } P0=tab1[shi]; d3=1; delay(2); d3=0; P0=tab[ge]; d4=1; delay(2); d4=0;} /****按键控制******/uint keyscan(){ if(key1==0) //按键1 { delay(5); if(key1==0) { while(!key1); shu++; //按键1数按下次数 } } if(key2==0) //按键2 { delay(5); if(key2==0) { while(!key2); count=count+10; //温度上限值加1 if(shu==2) //按键1按下2次 { alarm+=10; //温度下限值加1 } } } if(key3==0) //按键3 { delay(5); if(key3==0) { while(!key3); count=count-10; //温度上限值减1 if(shu==2) //按键1按下2下 { alarm-=10; //温度下限值减1 } } } return(count);} /*****报警控制******/void main(){ led1=1; led2=1; delay(10); while( 1 ) { tmpchange(); if(shu==0) { displayTemp(tmp( )); } keyscan(); if(shu==1) { displayTemp(count); } if(shu==2) { displayTemp(alarm); } if(shu==3) { shu=0; } if(temp>count) { led1=0;baojing=0; } else if(temp<alarm) { led2=0;baojing=0; } else { led1=1; led2=1; baojing=1; } }}
|