|
- #include<reg52.h>
- #include<intrins.h>
- #define uint unsigned int
- #define uchar unsigned char
- sbit IO=P3^2;
- sbit lcden=P3^4;
- sbit lcdrs=P3^5;
- sbit lcdrw=P3^6;
- uchar data_byte;
- uchar RH,RL,TH,TL;
- void delay(uchar ms) // 延時模塊
- {
- uint i,j;
- for(i=ms;i>0;i--)
- for(j=110;j>0;j--);
- }
- void delayms() //一個for循環大概需要8個多機器周期一個機器周期為1us
- { //本函數延時8us多
- uchar i;
- for(i=0;i<1;i++);
- }
- void writecom(uchar com)
- {
- lcdrs=0;
- P0=com;
- delay(5);
- lcden=1;
- delay(5);
- lcden=0;
- }
- void writedata(uchar date)
- {
- lcdrs=1;
- P0=date;
- delay(5);
- lcden=1;
- delay(5);
- lcden=0;
- }
- void lcd_init()
- {
- lcden=0;
- lcdrw=0;
- writecom(0x38);
- writecom(0x0c);
- writecom(0x06);
- writecom(0x01);
- }
- void display(uchar addr,uchar q)
- {
- delay(10);
- writecom(addr|0x80);
- writedata(q);
- delay(1);
- }
- //DHT11測試
- void start()// 開始信號
- {
- IO=1;
- delayms();
- IO=0;
- delay(25); // 主機把總線拉低必須大于 18ms 保證 DHT11 能檢測到起始信號
- IO=1; //發送開始信號結束后 拉高電平延時 20-40us
- delayms(); // 以下三個延時函數差不多為 24us 符合要求
- delayms();
- delayms();
- }
- uchar receive_byte()//接收一個字節
- {
- uchar i,temp;
- for(i=0;i<8;i++) // 接收 8bit 的數據
- {
- while(!IO); // 等待 50us的低電平開始信號結束
- delayms(); //開始信號結束之后 延時 26us-28us 以下三個延時函數
- delayms();
- delayms();
- temp=0; //時間為 26us-28us 表示接收的為數據 '0'
- if(IO==1)
- temp=1; //如果 26us-28us之后 還為高電平 則表示接收的數據為 '1'
- while(IO); // 等待數據信號高電平 '0'為 26us-28us '1'為 70us
- data_byte<<=1; // 接收的數據為高位在前 右移
- data_byte|=temp;
- }
- return data_byte;
- }
- void receive()// 接收數據
- {
- uchar T_H,T_L,R_H,R_L,check,num_check,i;
- start();// 開始信號
- IO=1; //主機設為輸入 判斷從機 DHT11 響應信號
- if(!IO) // 判斷從機是否有低電平響應信號
- {
- while(!IO); // 判斷從機發出 80us 的低電平響應信號是否結束
- while(IO); // 判斷從機發出 80us 的高電平是否結束 如結束則主機進入數據接收狀態
- R_H=receive_byte();// 濕度高位
- R_L=receive_byte();// 濕度低位
- T_H=receive_byte();// 溫度高位
- T_L=receive_byte();// 溫度低位
- check=receive_byte();// 校驗位
- IO=0; // 當最后一 bit 數據接完畢后 從機拉低電平 50us
- for(i=0;i<7;i++)// 差不多 50us 的延時
- delayms();
- IO=1; // 總線由上拉電阻拉高 進入空閑狀態
- num_check=R_H+R_L+T_H+T_L;
- if(num_check==check) // 判斷讀到的四個數據之和是否與校驗位相同
- {
- RH=R_H;
- RL=R_L;
- TH=T_H;
- TL=T_L;
- check=num_check;
- }}}
- void main()
- {
- lcd_init();// 初始化LCD
- while(1)
- {
- receive();// 接收數據
- display(0x00,'R');//LCD 的第一行顯示
- display(0x01,':');
- display(0x02,RH/10+0x30); //0x30 表示 帶字庫的 LCD1602 中 0x30 的位置放有數字 0 RH/10+0x30 即表示濕度的十位數字在字庫 RH/10+0x30 的位置處放著
- display(0x03,RH%10+0x30);
- display(0x04,'.');
- display(0x05,RL+0x30);
- display(0X06,'%');
- display(0x40,'T');
- display(0x41,':');
- display(0x42,TH/10+0x30);
- display(0x43,TH%10+0x30);
- display(0x44,'.');
- display(0x45,TL+0x30); //溫度的小數部分就一位數,范圍0-9
- display(0x46,0xdf); //溫度單位
- display(0x47,0x43);
- } }
復制代碼 |
-
-
DHT11.zip
2020-11-13 18:08 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
3.52 KB, 下載次數: 45, 下載積分: 黑幣 -5
|