- #include <reg51.h>
- #include "key_contrl.h"
- #include "lcd1602.h"
- #define LCM_Data P1
- #define Busy 0x80 //用于檢測 LCM 狀態(tài)字中的 Busy 標識
- extern int temp_value, humi_value;
- extern int flag;
- extern int temp;
- sbit red=P2^6;
- sbit blue=P2^7;
- sbit LCM_RW= P2^4; // 定義引腳
- sbit LCM_RS= P2^5;
- sbit LCM_E= P2^3;
- sbit beep = P0^6; //beep = 0時候發(fā)聲
- extern int temph,templ,disp_mode,huih,huil;
- extern char tel,teh,hh,hl;
- //寫數(shù)據(jù)
- void alarm()
- {
- beep=0;
- Delay5Ms();
- Delay5Ms();
- beep=1;
- Delay5Ms();
- Delay5Ms();
- }
- void WriteDataLCM(unsigned char WDLCM)
- {
- ReadStatusLCM(); //檢測忙
- LCM_Data = WDLCM;
- LCM_RS = 1;
- LCM_RW = 0;
- LCM_E = 0; // 若晶振速度太高可以在這后加小的延時
- LCM_E = 0; // 延時
- LCM_E = 1;
- }
- //寫指令
- void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC 為 0 時忽略忙檢
- 測
- {
- if (BuysC) ReadStatusLCM(); //根據(jù)需要檢測忙
- LCM_Data = WCLCM;
- LCM_RS = 0;
- LCM_RW = 0;
- LCM_E = 0;
- LCM_E = 0;
- LCM_E = 1;
- }
- //讀數(shù)據(jù)
- unsigned char ReadDataLCM(void)
- {
- LCM_RS = 1;
- LCM_RW = 1;
- LCM_E = 0;
- LCM_E = 0;
- LCM_E = 1;
- return(LCM_Data);
- }
- //讀狀態(tài)
- unsigned char ReadStatusLCM(void)
- {
- LCM_Data = 0xFF;
- LCM_RS = 0;
- LCM_RW = 1;
- LCM_E = 0;
- LCM_E = 0;
- LCM_E = 1;
- while (LCM_Data & Busy); // 檢測忙信號
- return(LCM_Data);
- }
- void LCMInit(void) //LCM 初始化
- {
- LCM_Data = 0;
- WriteCommandLCM(0x38,0); // 三次顯示模式設(shè)置,不檢測忙信號
- Delay5Ms();
- WriteCommandLCM(0x38,0);
- Delay5Ms();
- WriteCommandLCM(0x38,0);
- Delay5Ms();
- WriteCommandLCM(0x38,1); // 顯示模式設(shè)置 ,開始要求每次檢測忙信號
- WriteCommandLCM(0x08,1); // 關(guān)閉顯示
- WriteCommandLCM(0x01,1); // 顯示清屏
- WriteCommandLCM(0x06,1); // 顯示光標移動設(shè)置
- WriteCommandLCM(0x0C,1); // 顯示開及光標設(shè)置
- }
- //按指定位置顯示一個字符
- void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
- {
- Y &= 0x1;
- X &= 0xF; // 限制 X 不能大于 15,Y 不能大于 1
- if (Y) X |= 0x40; // 當要顯示第二行時地址碼 0x40;
- X |= 0x80; // 算出指令碼
- WriteCommandLCM(X, 0); // 這里不檢測忙信號,發(fā)送地址碼
- WriteDataLCM(DData);
- }
- //按指定位置顯示一串字符
- void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
- {
- unsigned char ListLength;
- ListLength = 0;
- Y &= 0x1;
- X &= 0xF; // 限制 X 不能大于 15,Y 不能大于 1
- while (DData[ListLength]>0x20) // 若到達字串尾則退出
- {
- if (X <= 0xF) //X 坐標應小于 0xF
- {
- DisplayOneChar(X, Y, DData[ListLength]); // 顯示單個字符
- ListLength++;
- X++;
- }
- }
- }
- //5ms 延時
- void Delay5Ms(void)
- {
- unsigned int TempCyc = 5552;
- while(TempCyc--);
- }
- /*void Delay_xMs(unsigned int x)
- {
- unsigned int i,j;
- for( i =0;i < x;i++ )
- {
- for( j =0;j<500;j++ );
- }
- }
- */
- void display_temp(void)
- {
- DisplayOneChar(0,0,' ');
- DisplayOneChar(1,0,' ');
- DisplayOneChar(2,0,'T');
- DisplayOneChar(3,0,'e');
- DisplayOneChar(4,0,'m');
- DisplayOneChar(5,0,'p');
- DisplayOneChar(6,0,':');
- DisplayOneChar(10,0,'C');
- DisplayOneChar(9,0,0xdf);
- DisplayOneChar(7,0,temp_value/100+0x30);
- DisplayOneChar(8,0,(temp_value/10)-(temp_value/100)*10+0x30);
- DisplayOneChar(11,0,' ');
- DisplayOneChar(12,0,' ');
- DisplayOneChar(13,0,' ');
- DisplayOneChar(14,0,' ');
- DisplayOneChar(15,0,' ');
- DisplayOneChar(0,1,' ');
- DisplayOneChar(1,1,' ');
- DisplayOneChar(2,1,'H');
- DisplayOneChar(3,1,'u');
- DisplayOneChar(4,1,'m');
- DisplayOneChar(5,1,'i');
- DisplayOneChar(6,1,'d');
- DisplayOneChar(7,1,'i');
- DisplayOneChar(8,1,'t');
- DisplayOneChar(9,1,'y');
- DisplayOneChar(10,1,':');
- DisplayOneChar(11,1,humi_value/100+0x30);
- DisplayOneChar(12,1,(humi_value/10)-(humi_value/100)*10+0x30);
- DisplayOneChar(13,1,'%');
- DisplayOneChar(14,1,' ');
- DisplayOneChar(15,1,' ');
- }
- void display_temp1(void)
- {
- DisplayOneChar(0,0,' ');
- DisplayOneChar(1,0,'T');
- DisplayOneChar(2,0,'h');
- DisplayOneChar(3,0,':');
- if(flag&teh)
- {
- DisplayOneChar(4,0,0x20);
- DisplayOneChar(5,0,0x20);
- }
- else
- {
- DisplayOneChar(4,0,temph/10+0x30);
- DisplayOneChar(5,0,temph%10+0x30);
- }
- DisplayOneChar(6,0,0xdf);
- DisplayOneChar(7,0,'C');
- DisplayOneChar(8,0,' ');
- DisplayOneChar(9,0,'T');
- DisplayOneChar(10,0,'h');
- DisplayOneChar(11,0,':');
- if(flag&tel)
- {
- DisplayOneChar(12,0,0x20);
- DisplayOneChar(13,0,0x20);
- }
- else
- {
- DisplayOneChar(12,0,templ/10+0x30);
- DisplayOneChar(13,0,templ%10+0x30);
- }
- DisplayOneChar(14,0,0xdf);
- DisplayOneChar(15,0,'C');
- DisplayOneChar(0,1,' ');
- DisplayOneChar(1,1,'H');
- DisplayOneChar(2,1,'h');
- DisplayOneChar(3,1,':');
- if(flag&hh)
- {
- DisplayOneChar(4,1,0x20);
- DisplayOneChar(5,1,0x20);
- }
- else
- {
- DisplayOneChar(4,1,huih/10+0x30);
- DisplayOneChar(5,1,huih%10+0x30);
- }
- DisplayOneChar(6,1,'%');
- DisplayOneChar(7,1,' ');
- DisplayOneChar(8,1,' ');
- DisplayOneChar(9,1,'H');
- DisplayOneChar(10,1,'l');
- DisplayOneChar(11,1,':');
- if(flag&hl)
- {
- DisplayOneChar(12,1,0x20);
- DisplayOneChar(13,1,0x20);
- }
- else
- {
- DisplayOneChar(12,1,huil/10+0x30);
- DisplayOneChar(13,1,huil%10+0x30);
- }
- DisplayOneChar(14,1,'%');
- DisplayOneChar(15,1,' ');
- }
- void displayfun1()
- {
- display_temp();
- }
- void displayfun2()
- {
- display_temp1();
- }
- void display()
- {
- if((((temp_value/10)%100)<templ)||(((humi_value/10)%100)<huil))
- {beep=0;red=0;} //溫度低于下限值,報警
- else if(((temp_value/10)%100)>=temph || ((humi_value/10)%100)>=huih)
- {beep=0;blue=0;} //溫度高于或等于上限值,報警
- else {beep=1;red=1;blue=1;}
- // if(((humi_value/10)%100)<huil){beep=0;led=0;} //溫度低
- 于下限值,報警
- // else if(((humi_value/10)%100)>=huih)beep=0; //溫度高于或等于上限
- 值,報警
- // else {beep=1;led=1;}
- if(!disp_mode)
- displayfun1(); //顯示正常
- else
- displayfun2(); //設(shè)置界面
- }
- #include "dht11.h"
- #include <reg52.h>
- //請根據(jù)自己的 dht11 接的 IO 口來改動位定義
- sbit dht11 = P3^0;
- //防止在與硬件通信時發(fā)生死循環(huán)的計數(shù)范圍
- #define NUMBER 20
- #define SIZE 5
- static unsigned char status;
- //存放五字節(jié)數(shù)據(jù)的數(shù)組
- static unsigned char value_array[SIZE];
- /*可在其他的文件引用溫濕度值 ,實際是溫度的整數(shù)的 10 倍
- 如 dht11 讀回的溫度是 26,則 temp_value = 260, 濕度同理 */
- int temp_value, humi_value;
- static unsigned char ReadValue(void);
- void Delay_1ms(unsigned int ms)
- {
- unsigned int x, y;
- for(x = ms; x > 0; x--)
- {
- for(y = 124; y > 0; y--);
- }
- }
- static void DHT11_Delay_10us(void)
- {
- unsigned char i;
- i--;
- i--;
- i--;
- i--;
- i--;
- i--;
- }
- /*讀一個字節(jié)的數(shù)據(jù) */
- static unsigned char DHT11_ReadValue(void)
- {
- unsigned char count, value = 0, i;
- status = OK; //設(shè)定標志為正常狀態(tài)
- for(i = 8; i > 0; i--)
- {
- //高位在先
- value <<= 1;
- count = 0;
- //每一位數(shù)據(jù)前會有一個 50us 的低電平時間 .等待 50us 低電平結(jié)束
- while(dht11 == 0 && count++ < NUMBER);
- if(count >= NUMBER)
- {
- status = ERROR; //設(shè)定錯誤標志
- return 0; //函數(shù)執(zhí)行過程發(fā)生錯誤就退出函數(shù)
- }
- //26-28us 的高電平表示該位是 0,為 70us 高電平表該位 1
- DHT11_Delay_10us();
- DHT11_Delay_10us();
- DHT11_Delay_10us();
- //延時 30us 后檢測數(shù)據(jù)線是否還是高電平
- if(dht11 != 0)
- {
- //進入這里表示該位是 1
- value++;
- //等待剩余 (約 40us)的高電平結(jié)束
- while(dht11 != 0 && count++ < NUMBER)
- {
- dht11 = 1;
- }
- if(count >= NUMBER)
- {
- status = ERROR; //設(shè)定錯誤標志
- return 0;
- }
- }
- }
- return (value);
- }
- //讀溫度和濕度函數(shù), 讀一次的數(shù)據(jù) ,共五字節(jié),讀出成功函數(shù)返回 OK, 錯誤返回
- ERROR
- unsigned char DHT11_ReadTempAndHumi(void)
- {
- unsigned char i = 0, check_value = 0,count = 0;
- EA = 0;
- dht11 = 0; //拉低數(shù)據(jù)線大于 18ms 發(fā)送開始信號
- Delay_1ms(20); //需大于 18 毫秒
- dht11 = 1; //釋放數(shù)據(jù)線 ,用于檢測低電平的應答信號
- //延時 20-40us,等待一段時間后檢測應答信號 ,應答信號是從機拉低數(shù)據(jù)線
- 80us
- DHT11_Delay_10us();
- DHT11_Delay_10us();
- DHT11_Delay_10us();
- DHT11_Delay_10us();
- if(dht11 != 0) // 檢測應答信號 ,應答信號是低電平
- {
- //沒應答信號
- EA = 1;
- return ERROR;
- }
- else
- {
- //有應答信號
- while(dht11 == 0 && count++ < NUMBER); // 等待應答信號結(jié)束
- if(count >= NUMBER) // 檢測計數(shù)器是否超過了設(shè)定的范圍
- {
- dht11 = 1;
- EA = 1;
- return ERROR; //讀數(shù)據(jù)出錯 ,退出函數(shù)
- }
- count = 0;
- dht11 = 1;//釋放數(shù)據(jù)線
- //應答信號后會有一個 80us 的高電平,等待高電平結(jié)束
- while(dht11 != 0 && count++ < NUMBER);
- if(count >= NUMBER)
- {
- dht11 = 1;
- EA = 1;
- return ERROR; //退出函數(shù)
- }
- //讀出濕 .溫度值
- for(i = 0; i < SIZE; i++)
- {
- value_array[i] = DHT11_ReadValue();
- if(status == ERROR)//調(diào)用 ReadValue()讀數(shù)據(jù)出錯會設(shè)定 status 為
- ERROR
- {
- dht11 = 1;
- EA = 1;
- return ERROR;
- }
- //讀出的最后一個值是校驗值不需加上去
- if(i != SIZE - 1)
- {
- //讀出的五字節(jié)數(shù)據(jù)中的前四字節(jié)數(shù)據(jù)和等于第五字節(jié)數(shù)據(jù)表示
- 成功
- check_value += value_array[i];
- }
- }//end for
- //在沒用發(fā)生函數(shù)調(diào)用失敗時進行校驗
- if(check_value == value_array[SIZE - 1])
- {
- //將溫濕度擴大 10 倍方便分離出每一位
- humi_value = value_array[0] * 10;
- temp_value = value_array[2] * 10;
- dht11 = 1;
- EA = 1;
- return OK; //正確的讀出 dht11 輸出的數(shù)據(jù)
- }
- else
- {
- //校驗數(shù)據(jù)出錯
- EA = 1;
- return ERROR;
- }
- }
- }
- #include "lcd1602.h"
- #include "key_contrl.h"
- #include"dht11.h"
- #include <reg52.h>
- int temp;
- int temph = 40; //初始上限值
- int templ = 10; //初始下限值
- int huih = 90;
- int huil =10;
- int timecount,flag=0,number=0,count=0;
- void t0(void) interrupt 1 using 0
- { TH0=(65535-50000)/256; //50ms定時
- TL0=(65535-50000)%256;
- timecount++;//re_disp++;
- if(timecount>9){timecount=0;flag=~flag;} //50ms 到了則反顯
- //if(re_disp>200){re_disp=0;if(id)id=0;} //10 秒到了則由調(diào)整模式自動進入正
- 常顯示模式
- }
- void t1(void) interrupt 3 using 0
- {
- TH1=(65535-50000)/256;//50ms定時
- TL1=(65535-50000)%256;
- number++;
- if(number>2)
- {
- number=0;
- count++;
- //beep=0;
- }
- }
- void main(void)
- {
- TMOD=0x11; //初始化定時器 t0 方式 1
- TH0=(65535-50000)/256;
- TL0=(65535-50000)%256;
- TH1=(65535-50000)/256;
- TL1=(65535-50000)%256;
- EA=1;
- ET0=1;
- ET1=1;
- TR0=1;
- TR1=1;
- LCMInit(); //LCM 初始化
- Delay5Ms(); //延時片刻
- while(1)
- {
- if(count==2)
- {
- DHT11_ReadTempAndHumi();
- count=0;
- }
- delay_LCM(300);
- Scan_Key();
- }
復制代碼 |