DHT11按鍵控制+土壤濕度報警
單片機源程序如下:
- #include<reg52.h>
- #include "intrins.h"
- typedef unsigned char uint8;
- typedef unsigned int uint16;
- sbit rs=P2^6; // 數據命令選擇
- sbit rw=P2^5; //讀寫選擇
- sbit e=P2^7; //使能
- sbit k1=P3^3; //模式
- sbit k2=P2^1; //加
- sbit k3=P2^2; //減
- sbit bee=P1^5;//蜂鳴器
- sbit DO=P3^1;
- sbit DHT11_DQ_OUT=P3^2;
- sbit led1=P1^0;
- sbit led2=P1^1;
- sbit led3=P1^2;
- sbit dq=P2^0;
- uint8 date;
- uint8 mode=0,xian;
- char temph=28,templ=20;
- char humih=80,humil=20;
- uint8 temp,humi;
- uint8 flag; //設定報警標志
- 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:"; //設定溫度上限顯示
- uint8 code str7[]="TempL:"; //設定溫度下限顯示
- uint8 code str8[]="HumiH:"; //設定濕度上限顯示
- uint8 code str9[]="HumiL:"; //設定濕度下限顯示
- void delay(uint16 i)
- {
- while(i--);
- }
- void delay_ms(uint16 i)
- {
- while(i--)
- delay(90);
- }
- void delay1(uint16 z)
- {
- uint16 i,j;
- for(i=z;i>0;i--)
- for(j=110;j>0;j--);
- }
- void wrc(uint8 c) //寫命令
- {
- delay(1000);
- rs=0;
- rw=0;
- e=0;
- P0=c;
- e=1;
- delay(10);
- e=0;
- }
- void wrd(uint8 dat) //寫數據
- {
- 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); //功能設置命令,選擇8位總線,雙行顯示 5*7點陣字符
- wrc(0x38);
- wrc(0x06); //光標和顯示模式設置 光標右移 整屏不移動
- wrc(0x0c); //顯示開關控制 開顯示 無光標 光標不閃爍
- wrc(0x01); //清零指令 固定的
- }
- //復位DHT11
- void DHT11_Rst()
- {
- DHT11_DQ_OUT=0; //拉低DQ
- delay_ms(20); //拉低至少18ms
- DHT11_DQ_OUT=1; //DQ=1
- delay(3); //主機拉高20~40us
- }
- //等待DHT11的回應
- //返回1:未檢測到DHT11的存在
- //返回0:存在
- uint8 DHT11_Check()
- {
- uint8 retry=0;
- while (DHT11_DQ_OUT&&retry<100)//DHT11會拉低40~50us
- {
- retry++;
- _nop_();
- };
- if(retry>=100)return 1;
- else retry=0;
- while (!DHT11_DQ_OUT&&retry<100)//DHT11拉低后會再次拉高40~50us
- {
- retry++;
- _nop_();
- };
- if(retry>=100)return 1;
- return 0;
- }
- //DHT11初始化
- //返回0:初始化成功,1:失敗
- uint8 DHT11_Init()
- {
- DHT11_Rst();
- return DHT11_Check();
- }
- //從DHT11讀取一個位
- //返回值:1/0
- uint8 DHT11_Read_Bit(void)
- {
- uint8 retry=0;
- while(DHT11_DQ_OUT&&retry<100)//等待變為低電平 12-14us 開始
- {
- 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讀取一個字節
- //返回值:讀到的數據
- uint8 DHT11_Read_Byte(void)
- {
- uint8 i,dat=0;
- for (i=0;i<8;i++)
- {
- dat<<=1;
- dat|=DHT11_Read_Bit();
- }
- return dat;
- }
- //從DHT11讀取一次數據
- //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位數據
- {
- 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 key_pros() //按鍵處理函數
- {
- if(k1==0)
- {
- delay(1000);
- if(k1==0)
- {
- mode++;
- if(mode==5)mode=0;
- wrc(0x01);
- }
- while(!k1);
- }
- if(mode==1) //對溫度上限設定
- {
- 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) //對溫度下限設定
- {
- 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) //對濕度上限設定
- {
- 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) //對濕度下限設定
- {
- 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() //數據處理函數
- {
- uint8 i;
- uint8 temp_buf[2],humi_buf[2];
- uint8 temphbuf[2],templbuf[2],humihbuf[2],humilbuf[2];
- 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;
-
- 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[temp/10]);
- wrd(num[temp%10]);
- 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]);
- wrd(humilbuf[1]);
- }
- }
- void baojinpros() //報警處理
- {
- if(temp>=temph||humi>=humih) //檢測溫度或者濕度高于設定上限值 降溫濕
- {
- led1=1; //降溫濕指示燈
- led2=0;
- }
- if(temp<=templ||humi<=humil) //檢測溫度或者濕度低于設定下限值 升溫濕
- {
- led1=0;
- led2=1; //升高溫濕指示燈
- }
- if(DO==0)
- {
- led3=1;
- }
- if(DO==1)
- {
- led3=0;
- }
- if((temp>templ&&temp<temph)&&(humi>humil&&humi<humih)&&DO==1)
- {
- led1=0;
- led2=0;
- led3=0;
- }
- }
- void Initial_com(void)
- {
- EA=1; //開總中斷
- ES=1; //允許串口中斷
- ET1=1; //允許定時器T1的中斷
- TMOD=0x20; //定時器T1,在方式2中斷產生波特率
- PCON=0x00; //SMOD=0
- SCON=0x50; // 方式1 由定時器控制
- TH1=0xfd; //波特率設置為9600
- TL1=0xfd;
- TR1=1; //開定時器T1運行控制位
- }
- void main()
- {
- uint8 i=0;
- led1=0;
- led2=0;
- led3=0;
- Initial_com();
- lcd_init();
- if(DO==0)
- {
- delay1(1); //消抖動
- if(DO==0) //確認觸發
- {
- SBUF=0X01;
- delay1(200);
- }
- if(RI)
- {
- date=SBUF; //單片機接受
- SBUF=date; //單片機發送
- RI=0;
- }
- }
- while(DHT11_Init()) //檢測DHT11是否純在
- {
- for(i=0;i<5;i++)
- {
- wrc(0x80+i);
- wrd(str3[i]);
- }
- }
- wrc(0x01);
- lcd_init_display(); //LCD初始化顯示
- i=0;
- while(1)
- {
- i++;
- key_pros();
- baojinpros(); //報警處理
- if(i==15)
- {
- i=0;
- data_pros(); //讀取一次DHT11數據最少要大于100ms
- }
- delay(1000);
-
- }
- }
復制代碼
|