- #include<reg52.h>
- #include<stdlib.h>
- #include <ctype.h>
- #define uint unsigned int
- #define uchar unsigned char
- uchar DHT11[5],RTflag=0;
- uchar FLAG; //超時標志位
- uchar a;
- sbit dat=P1^0; //DHT11數據引腳
- sbit RS=P2^5; //1602引腳
- sbit RW=P2^6; //1602引腳
- sbit EN=P2^7; //1602引腳
- uchar table[5];
- uint wd,sd;
- void Delay_t(uint j) //延時函數
- { 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(uint z)//1毫秒延時函數
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- void lcd_write_com(uchar com) //1602寫指令
- {
- RS=0;
- //RW=0;
- delay(1);
- EN=1;
- P0=com;
- delay(1);
- EN=0;
- }
- void lcd_init() //1602初始化
- {
- EN=0;
- RW=0;
- lcd_write_com(0x38);
- delay(1);
- lcd_write_com(0x08);
- delay(1);
- lcd_write_com(0x01);//1602清屏指令
- delay(1);
- lcd_write_com(0x06);
- delay(1);
- lcd_write_com(0x0C);
- delay(1);
- }
- void lcd_write_data(uchar date)//1602寫數據
- {
- RS=1;
- //RW=0;
- EN=1;
- P0=date;
- delay(1);
- EN=0;
- }
- void write_str(uchar x,uchar y,uchar *s)//在任意地址寫符號字母或數字
- {
- if(y==0)
- lcd_write_com(0x80+x);
- else
- lcd_write_com(0xc0+x);
- while(*s)
- {
- lcd_write_data(*s);
- s++;
- }
- }
- void write_shu(uchar x,uchar y,uchar num)//數據顯示函數
- {
- uchar s,g;
- if(y==0)
- lcd_write_com(0x80+x);
- else
- lcd_write_com(0xc0+x);
- s=num/10;// 數據分離顯示
- lcd_write_data(0x30+s);
- g=num%10;//數據分離顯示
- lcd_write_data(0x30+g);
- }
- uchar write_byte1() //讀一個字節
- {
- uchar i,comdata,temp1;
- for(i=0;i<8;i++)
- {
- FLAG=2;
- while((!dat)&&FLAG++);//判斷數據位是0還是1
- Delay_10us();
- Delay_10us();
- Delay_10us();
- temp1=0;
- if(dat)temp1=1; // 如果高電平高過預定0高電平值則數據位為 1
- FLAG=2;
- while((dat)&&FLAG++);//flag先與后加1 如果dat一直為1 uchar型變量 flag 溢出變為0 再自加1
- if(FLAG==1)break; //超時則跳出for循環
- comdata<<=1;//左移一位 高位在前 低位在后
- comdata|=temp1;
- }
- return (comdata);
- }
- void DHT11_5() //讀5個字節數據 兩個字節為溫度數據 兩個字節為濕度數據 最后一個字節為校驗
- {
- int p;
- char o;
- uchar i,temp;
- //主機拉低18ms
- dat=0;
- Delay_t(180);
- dat=1;
- //總線由上拉電阻拉高 主機延時20us
- Delay_10us();
- Delay_10us();
- Delay_10us();
- Delay_10us();
- //主機設為輸入 判斷從機響應信號
- dat=1;
- //判斷從機是否有低電平響應信號 如不響應則跳出,響應則向下運行
- if(!dat) //T !
- {
- FLAG=2; //超時標志位
- while((!dat)&&FLAG++);//判斷從機是否發出 80us 的低電平響應信號是否結束
- FLAG=2;
- while(
- (dat)&&FLAG++); //判斷從機拉高80us是否結束
- for(i=0;i<5;i++)//數據接收狀態
- {
- DHT11[i]=write_byte1();
- }
- dat=1; //釋放數據總線 為下一次讀取做好準備
- temp=(DHT11[0]+DHT11[1]+DHT11[2]+DHT11[3]);
- if(temp==DHT11[4]) //數據校驗
- {
- RTflag=1;
- }
- p=DHT11[0];
- o=toascii(p);
- if(RTflag==1) //如果RTflag=1 說明讀取到得數據正確
- {
- RTflag=0;
- // tm[0]=DATARHT[0]/10;
- // tm[1]=DATARHT[0]%10;
- // tm[2]=DATARHT[1]/10; //濕度
- // tm[3]=DATARHT[2]/10;
- // tm[4]=DATARHT[2]%10;
- // tm[5]=DATARHT[3]/10; //溫度
- write_str(0,0,"shidu: ");//第一行顯示濕度
- write_shu(12,0,o);
- write_str(14,0,"RH");
- write_str(0,1,"wendu: ");//第二行為顯示溫度
- write_shu(12,1,DHT11[2]);
- write_str(14,1,"^C");
- }
- }
- }
- void main()
- {
- lcd_init(); //1602初始化
- delay(1000); //等待DHT11溫濕度傳感器數據穩定 開始激活DHT11
- while(1)//循環讀取 并更新數據顯示
- {
- delay(1000);//等待DHT11溫濕度傳感器數據穩定 開始激活DHT11
- write_byte1();//讀一個字節
- DHT11_5(); //讀數據
- delay(1000); //延時等待
- }
- }
復制代碼 |