|
首先檢測(cè)DHT11是否連接成功,如果沒(méi)有連接好,則LCD1602上顯示ERROR。通過(guò)按鍵K1可對(duì)溫濕度閥值進(jìn)行設(shè)定按下一次K1,進(jìn)入溫度上限設(shè)定,再按下K1一次,進(jìn)入溫度下限設(shè)定,再按下一次K1,進(jìn)入濕度上限設(shè)定,再按下一次K1,進(jìn)入濕度下限設(shè)定,再按下一次K1,退出模式選擇,進(jìn)入正常溫濕度采集狀態(tài)。
選擇好要設(shè)定的模式,然后通過(guò)K2和K3進(jìn)行數(shù)值加減。當(dāng)采集的溫度或者濕度高于設(shè)定上限值,降溫濕指示燈D1亮,當(dāng)采集的溫度或者濕度低于設(shè)定下限值,升溫濕指示燈D2亮,溫濕度正常范圍內(nèi),D1和D2指示燈不亮。
電路原理圖如下:
原理圖截圖.png (45.71 KB, 下載次數(shù): 48)
下載附件
2021-6-13 15:15 上傳
單片機(jī)源程序如下:
- #include<reg52.h>
- #include "intrins.h"
- typedef unsigned char uint8;
- typedef unsigned int uint16;
- sbit rs=P2^6; // 數(shù)據(jù)命令選擇
- sbit rw=P2^5; //讀寫(xiě)選擇
- sbit e=P2^7; //使能
- sbit k1=P3^3; //模式
- sbit k2=P2^1; //加
- sbit k3=P2^2; //減
- sbit DHT11_DQ_OUT=P3^2;
- sbit led1=P3^6;
- sbit led2=P3^7;
- sbit dq=P2^0;
- uint8 mode=0,xian;
- char temph=50,templ=20;
- char humih=80,humil=20;
- uint8 temp,humi;
- uint8 flag; //設(shè)定報(bào)警標(biāo)志
- uint8 a,c,tempvalue;
- uint8 code num[10]="0123456789";
- uint8 code str1[]="Temp:"; //溫度
- uint8 code str2[]="Humi:"; //濕度
- uint8 code str3[]="Error";
- uint8 code str4[]="Success ";
- uint8 code str5[]="%RH";
- uint8 code str6[]="TempH:"; //設(shè)定溫度上限顯示
- uint8 code str7[]="TempL:"; //設(shè)定溫度下限顯示
- uint8 code str8[]="HumiH:"; //設(shè)定濕度上限顯示
- uint8 code str9[]="HumiL:"; //設(shè)定濕度下限顯示
- void delay(uint16 i)
- {
- while(i--);
- }
- void delay_ms(uint16 i)
- {
- while(i--)
- delay(90);
- }
- void wrc(uint8 c) //寫(xiě)命令
- {
- delay(1000);
- rs=0;
- rw=0;
- e=0;
- P0=c;
- e=1;
- delay(10);
- e=0;
- }
- void wrd(uint8 dat) //寫(xiě)數(shù)據(jù)
- {
- delay(1000);
- rs=1;
- rw=0;
- e=0;
- P0=dat;
- e=1;
- delay(10);
- e=0;
- rs=0;
- }
- void lcd_init() // LCD1602初始化
- {
- delay(1000);
- wrc(0x38);
- wrc(0x38); //功能設(shè)置命令,選擇8位總線,雙行顯示 5*7點(diǎn)陣字符
- wrc(0x38);
- wrc(0x06); //光標(biāo)和顯示模式設(shè)置 光標(biāo)右移 整屏不移動(dòng)
- wrc(0x0c); //顯示開(kāi)關(guān)控制 開(kāi)顯示 無(wú)光標(biāo) 光標(biāo)不閃爍
- wrc(0x01); //清零指令 固定的
- }
- //復(fù)位DHT11
- void DHT11_Rst()
- {
- DHT11_DQ_OUT=0; //拉低DQ
- delay_ms(20); //拉低至少18ms
- DHT11_DQ_OUT=1; //DQ=1
- delay(3); //主機(jī)拉高20~40us
- }
- //等待DHT11的回應(yīng)
- //返回1:未檢測(cè)到DHT11的存在
- //返回0:存在
- uint8 DHT11_Check()
- {
- uint8 retry=0;
- while (DHT11_DQ_OUT&&retry<100)//DHT11會(huì)拉低40~50us
- {
- retry++;
- _nop_();
- };
- if(retry>=100)return 1;
- else retry=0;
- while (!DHT11_DQ_OUT&&retry<100)//DHT11拉低后會(huì)再次拉高40~50us
- {
- retry++;
- _nop_();
- };
- if(retry>=100)return 1;
- return 0;
- }
- //DHT11初始化
- //返回0:初始化成功,1:失敗
- uint8 DHT11_Init()
- {
- DHT11_Rst();
- return DHT11_Check();
- }
- //從DHT11讀取一個(gè)位
- //返回值:1/0
- uint8 DHT11_Read_Bit(void)
- {
- uint8 retry=0;
- while(DHT11_DQ_OUT&&retry<100)//等待變?yōu)榈碗娖?12-14us 開(kāi)始
- {
- retry++;
- _nop_();
- }
- retry=0;
- while((!DHT11_DQ_OUT)&&retry<100)//等待變高電平 26-28us表示0,116-118us表示1
- {
- retry++;
- _nop_();
- }
- delay(1);//等待40us
- if(DHT11_DQ_OUT)return 1;
- else return 0;
- }
- //從DHT11讀取一個(gè)字節(jié)
- //返回值:讀到的數(shù)據(jù)
- uint8 DHT11_Read_Byte(void)
- {
- uint8 i,dat=0;
- for (i=0;i<8;i++)
- {
- dat<<=1;
- dat|=DHT11_Read_Bit();
- }
- return dat;
- }
- //從DHT11讀取一次數(shù)據(jù)
- //temp:溫度值(范圍:0~50°)
- //humi:濕度值(范圍:20%~90%)
- //返回值:0,正常;1,讀取失敗
- uint8 DHT11_Read_Data(uint8 *temp,uint8 *humi)
- {
- uint8 buf[5];
- uint8 i;
- DHT11_Rst();
- if(DHT11_Check()==0)
- {
- for(i=0;i<5;i++)//讀取40位數(shù)據(jù)
- {
- buf[i]=DHT11_Read_Byte();
- }
- if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
- {
- *humi=buf[0];
- *temp=buf[2];
- }
-
- }else return 1;
- return 0;
- }
- void ds18b20init() //18b20的初始化
- {
- dq=1;
- delay(1);
- dq=0;
- delay(80);
- dq=1;
- delay(5);
- dq=0;
- delay(20);
- dq=1;
- delay(35);
- }
- void ds18b20wr(uint8 dat) //18b20寫(xiě)數(shù)據(jù)
- {
- uint8 i;
- for(i=0;i<8;i++)
- {
- dq=0;
- dq=dat&0x01;
- dat>>=1;
- delay(8);//在時(shí)序上只有這一塊對(duì)時(shí)序要求最準(zhǔn)確,他的時(shí)間必須大于15us
- dq=1;
- delay(1);
- }
- }
- uint8 ds18b20rd() //18b20讀數(shù)據(jù)
- {
- uint8 value,i;
- for(i=0;i<8;i++)
- {
- dq=0;
- value>>=1;
- dq=1;
- if(dq==1)value|=0x80;
- delay(8);//在這一塊也對(duì)時(shí)間要求特別準(zhǔn)確,整段程序必須大于60us
- }
- return value;
- }
- uint8 readtemp() //讀取溫度內(nèi)需要復(fù)位的
- {
- uint8 b;
- ds18b20init(); //初始化
- ds18b20wr(0xcc); //發(fā)送忽略ROM指令
- ds18b20wr(0x44); //發(fā)送溫度轉(zhuǎn)換指令
- delay(100);
- ds18b20init(); //初始化
- ds18b20wr(0xcc); //發(fā)送忽略ROM指令
- ds18b20wr(0xbe); //發(fā)讀暫存器指令
- a=ds18b20rd(); //溫度的低八位
- b=ds18b20rd(); //溫度的高八位
- b<<=4; //ssss s***;s為標(biāo)志位s=0表示溫度值為正數(shù),s=1溫度值為負(fù)數(shù)
- c=b&0x80; //溫度正負(fù)標(biāo)志位確認(rèn)
- b+=(a&0xf0)>>4;
- a=a&0x0f; //溫度的小數(shù)部分
- return b;
- }
- void key_pros() //按鍵處理函數(shù)
- {
- if(k1==0)
- {
- delay(1000);
- if(k1==0)
- {
- mode++;
- if(mode==5)mode=0;
- wrc(0x01);
- }
- while(!k1);
- }
- if(mode==1) //對(duì)溫度上限設(shè)定
- {
- if(k2==0) //加
- {
- delay(1000);
- if(k2==0)
- {
- temph++;
- if(temph>=80)temph=80;
- }
- while(!k2);
- }
- if(k3==0) //減
- {
- delay(1000);
- if(k3==0)
- {
- temph--;
- if(temph<=0)temph=0;
- }
- while(!k3);
- }
- }
- if(mode==2) //對(duì)溫度下限設(shè)定
- {
- if(k2==0) //加
- {
- delay(1000);
- if(k2==0)
- {
- templ++;
- if(templ>=80)templ=80;
- }
- while(!k2);
- }
- if(k3==0) //減
- {
- delay(1000);
- if(k3==0)
- {
- templ--;
- if(templ<=0)templ=0;
- }
- while(!k3);
- }
- }
- if(mode==3) //對(duì)濕度上限設(shè)定
- {
- if(k2==0) //加
- {
- delay(1000);
- if(k2==0)
- {
- humih++;
- if(humih>=80)humih=80;
- }
- while(!k2);
- }
- if(k3==0) //減
- {
- delay(1000);
- if(k3==0)
- {
- humih--;
- if(humih<=0)humih=0;
- }
- while(!k3);
- }
- }
- if(mode==4) //對(duì)濕度下限設(shè)定
- {
- if(k2==0) //加
- {
- delay(1000);
- if(k2==0)
- {
- humil++;
- if(humil>=80)humil=80;
- }
- while(!k2);
- }
- if(k3==0) //減
- {
- delay(1000);
- if(k3==0)
- {
- humil--;
- if(humil<=0)humil=0;
- }
- while(!k3);
- }
- }
- }
- void lcd_init_display() //LCD初始化顯示
- {
- uint8 i;
- for(i=0;i<5;i++)
- {
- wrc(0x80+i);
- wrd(str1[i]);
- }
- for(i=0;i<5;i++)
- {
- wrc(0xc0+i);
- wrd(str2[i]);
- }
- }
- void data_pros() //數(shù)據(jù)處理函數(shù)
- {
- uint8 i;
- uint8 temp_buf[2],humi_buf[2];
- uint8 temphbuf[2],templbuf[2],humihbuf[2],humilbuf[2];
- float dio;
- uint16 k;
- tempvalue=readtemp();
- DHT11_Read_Data(&temp,&humi);
- temp_buf[0]=temp/10+0x30;
- temp_buf[1]=temp%10+0x30;
- humi_buf[0]=humi/10+0x30;
- humi_buf[1]=humi%10+0x30;
-
- dio=a*0.0625;
- k=dio*10000;//取小數(shù)點(diǎn)后兩位有效數(shù)字
- temphbuf[0]=temph/10+0x30;
- temphbuf[1]=temph%10+0x30;
- templbuf[0]=templ/10+0x30;
- templbuf[1]=templ%10+0x30;
- humihbuf[0]=humih/10+0x30;
- humihbuf[1]=humih%10+0x30;
- humilbuf[0]=humil/10+0x30;
- humilbuf[1]=humil%10+0x30;
- if(mode==0)
- {
- lcd_init_display();
- wrc(0x85);
- wrd(num[tempvalue%100/10]);
- wrd(num[tempvalue%100%10]);
- wrd('.');
- wrd(num[k/1000]);
- wrd(0xdf);
- wrd('C');
-
- for(i=0;i<2;i++)
- {
- wrc(0Xc5+i);
- wrd(humi_buf[i]);
- }
- for(i=0;i<3;i++)
- {
- wrc(0Xc7+i);
- wrd(str5[i]);
- }
- }
- if(mode==1) //溫度上限顯示
- {
- wrc(0x80);
- for(i=0;i<6;i++)
- {
- wrd(str6[i]);
- }
- wrd(temphbuf[0]);
- wrd(temphbuf[1]);
- }
- if(mode==2) //溫度下限顯示
- {
- wrc(0x80);
- for(i=0;i<6;i++)
- {
- wrd(str7[i]);
- }
- wrd(templbuf[0]);
- wrd(templbuf[1]);
- }
- if(mode==3) //濕度上限顯示
- {
- wrc(0x80);
- for(i=0;i<6;i++)
- {
- wrd(str8[i]);
- }
- wrd(humihbuf[0]);
- wrd(humihbuf[1]);
- }
- if(mode==4) //濕度下限顯示
- {
- wrc(0x80);
- for(i=0;i<6;i++)
- {
- wrd(str9[i]);
- }
- wrd(humilbuf[0]);
- ……………………
- …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
所有程序51hei提供下載:
程序.7z
(21.56 KB, 下載次數(shù): 45)
2021-6-13 15:16 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
|