|
|
單片機(jī)是根據(jù)硬件電路圖的設(shè)計(jì)來寫代碼的
- #include <reg52.h>
- #include <intrins.h>
- #define uint unsigned int
- #define uchar unsigned char
- sbit busy= P2^7; //P0^7;//檢測忙
- sbit bee= P3^6; //P1^5;//蜂鳴器
- sbit io = P1^1; //數(shù)據(jù)接收端口
- sbit rs = P0^7; //P2^0 ; //數(shù)據(jù)命令選擇
- sbit rw = P0^6; //P2^1 ;//讀寫選擇
- sbit e = P0^5; //P2^2 ;//使能
- sbit K1 = P3^5; //P1^2;//按鍵終止警報(bào)
- sbit K2 = P3^4; //P1^3;//按鍵恢復(fù)警報(bào)
- uchar Tem,Hum,TemHigh,TemLow,HumHigh,HumLow;//溫濕度高低8位數(shù)據(jù)
- uchar TemWarnHigh,TemWarnLow,HumWarnHigh,HumWarnLow;//報(bào)警的溫度和濕度
- uchar data1;//傳輸?shù)臄?shù)據(jù)存放
- uchar BeepFlag;//按鍵報(bào)警標(biāo)志,1為禁用,0為啟用
- //設(shè)置報(bào)警溫濕度上下限
- #define TemWarnHigh 24
- #define TemWarnLow 16
- #define HumWarnHigh 60
- #define HumWarnLow 50
- /**********延時(shí)模塊**********/
- void Delay10us() //11.0592MHz
- {
- uchar i;
- _nop_();
- i = 25;
- while (--i);
- }
- void DelayLong(uint times)
- {
- while(times--)
- Delay10us();
- }
- /**********LCD模塊**********/
- void LCDBusy()//測試LCD忙碌狀態(tài)
- {
- uchar result ;
- rs = 0 ;
- rw = 1 ;
- do
- {
- e = 1 ;
- result = busy;
- e = 0 ;
- }while(result & 0x80);//判斷D7是否為1,D7=1表示忙
- }
- void LCDWriteCmd(uchar cmd)// 寫指令
- {
- LCDBusy() ;//判斷LCD是否忙
- rs = 0 ;
- rw = 0 ;
- P2 = cmd ;//寫入指令
- e = 1 ;
- DelayLong(10);
- e = 0 ;
- DelayLong(10);
- }
- void LCDWriteAddr(uchar addr)//寫地址
- {
- LCDWriteCmd(addr|0x80) ;
- }
- void LCDWriteByte(uchar dat)//寫字節(jié)
- {
- LCDBusy() ;//判斷LCD是否忙
- rs = 1 ;
- rw = 0 ;
- P2 = dat ;//寫入數(shù)據(jù)
- e = 1 ;
- DelayLong(10);
- e = 0 ;
- DelayLong(10);
- }
- void LCDInit()// LCD初始化
- {
- LCDWriteCmd(0x38) ;
- DelayLong(500);
- LCDWriteCmd(0x38) ;
- DelayLong(500);
- LCDWriteCmd(0x38) ;
- DelayLong(500);
- LCDWriteCmd(0x38) ;//設(shè)置16×2顯示,每個(gè)方塊5×7點(diǎn)陣,8位數(shù)據(jù)接口
- LCDWriteCmd(0x0C) ;//顯示器開,光標(biāo)關(guān)閉
- LCDWriteCmd(0x06) ;//文字不動(dòng),地址自動(dòng)加一
- LCDWriteCmd(0x01) ;//清屏
- }
- void LCDDisplay(uchar addr, uchar q)//在某一地址顯示一字節(jié)
- {
- Delay10us();
- LCDWriteAddr(addr) ;
- LCDWriteByte(q) ;
- Delay10us();
- }
- void LCDWarning()
- {
- if(Tem>=TemWarnHigh) //檢測的溫度高于額定上限
- {
- LCDDisplay(0x08,'T') ;
- LCDDisplay(0x09,'e') ;
- LCDDisplay(0x0A,'m') ;
- LCDDisplay(0x0B,'H') ;
- LCDDisplay(0x0C,'i') ;
- LCDDisplay(0x0D,'g') ;
- LCDDisplay(0x0E,'h') ;
- LCDDisplay(0x0F,'!') ;
- }
- if(Tem<=TemWarnLow) //檢測的溫度低于額定下限
- {
- LCDDisplay(0x08,'T') ;
- LCDDisplay(0x09,'e') ;
- LCDDisplay(0x0A,'m') ;
- LCDDisplay(0x0B,'L') ;
- LCDDisplay(0x0C,'o') ;
- LCDDisplay(0x0D,'w') ;
- LCDDisplay(0x0E,'!') ;
- }
- if(Hum>=HumWarnHigh) //檢測的濕度高于額定上限
- {
- LCDDisplay(0x48,'H') ;
- LCDDisplay(0x49,'u') ;
- LCDDisplay(0x4A,'m') ;
- LCDDisplay(0x4B,'H') ;
- LCDDisplay(0x4C,'i') ;
- LCDDisplay(0x4D,'g') ;
- LCDDisplay(0x4E,'h') ;
- LCDDisplay(0x4F,'!') ;
- }
- if(Hum<=HumWarnLow) //檢測的濕度低于額定下限
- {
- LCDDisplay(0x48,'H') ;
- LCDDisplay(0x49,'u') ;
- LCDDisplay(0x4A,'m') ;
- LCDDisplay(0x4B,'L') ;
- LCDDisplay(0x4C,'o') ;
- LCDDisplay(0x4D,'w') ;
- LCDDisplay(0x4E,'!') ;
- }
- }
- /**********蜂鳴器模塊***********/
- void BEEP() //報(bào)警函數(shù)
- {
- if(Tem<=TemWarnLow || Tem>=TemWarnHigh) //檢測的溫度超標(biāo)
- bee=0; //報(bào)警
- if(Hum<=HumWarnLow || Hum>=HumWarnHigh) //檢測的濕度超標(biāo)
- bee=0; //報(bào)警
- }
- /**********DHT11模塊***********/
- void DHTStart()//開始信號(hào)
- {
- io=1;//拉高data
- Delay10us();
- io=0;
- DelayLong(180);//微處理器IO設(shè)置為高電平且時(shí)間>18ms
- io=1;//再拉高data
- Delay10us();
- }
- uchar DHTReceive()//接收一個(gè)字節(jié)
- {
- uint i;
- uchar temp,count;//temp記錄是0還是1,count計(jì)數(shù)收到第幾位
- data1=0;
- for(i=0;i<8;i++)//一次接受8位
- {
- temp=0;//初始收到0,低電平
- DelayLong(4);//延時(shí)40us后判斷收到的電平
- if(io==1)temp=1;//如果收到1,那么傳送的是1,否則傳送的是0
- count=2;
- while((io)&&count++);//io=0則等待,count防止死循環(huán)
- if(count==1)break;
- data1<<=1;//左移1位
- data1|=temp;//傳輸當(dāng)前位給data存儲(chǔ)
- }
- return data1;
- }
- void receive()//接收數(shù)據(jù)
- {
- uchar TemH,TemL,HumH,HumL,check,sum;
- uint time;
- DHTStart();//開始信號(hào)
- //DHT11收到開始信號(hào)后進(jìn)行應(yīng)答
- time=8;
- while(!io & time>0)time--;//等待DHT拉高80us
- time=8;
- while(io && time>0)time--;//等待DHT拉低80us
- //開始接收數(shù)據(jù)
- io=1;//主機(jī)拉高data
- Delay10us();
- if(!io)//讀取DHT11響應(yīng)信號(hào),DHT11拉低data
- {
- HumH=DHTReceive();//濕度高8位
- HumL=DHTReceive();//濕度低8位
- TemH=DHTReceive();//溫度高8位
- TemL=DHTReceive();//溫度低8位
- check=DHTReceive();//校驗(yàn)位
- io=0;//拉低延時(shí)50us,代表讀取結(jié)束
- DelayLong(5);
- io=1;
- sum=HumH+HumL+TemH+TemL;//校驗(yàn)
- if(sum==check)//校驗(yàn)通過數(shù)據(jù)錄入
- {
- HumHigh=HumH;
- HumLow=HumL;
- TemHigh=TemH;
- TemLow=TemL;
- }
- }
- }
- /**********主程序**********/
- void main()
- {
- BeepFlag=1;
- LCDInit();//LCD初始化
- while(1)
- {
- LCDDisplay(0x00,'T') ; //LCD顯示Tem:
- LCDDisplay(0x01,'e') ;
- LCDDisplay(0x02,'m') ;
- LCDDisplay(0x03,':') ;
- LCDDisplay(0x40,'H') ; //LCD顯示Hum:
- LCDDisplay(0x41,'u') ;
- LCDDisplay(0x42,'m') ;
- LCDDisplay(0x43,':') ;
- receive();
- LCDDisplay(0x04,TemHigh/10+0x30) ;//溫度顯示
- LCDDisplay(0x05,TemLow%10+0x30) ;
- LCDDisplay(0x44,HumHigh/10+0x30) ;//濕度顯示
- LCDDisplay(0x45,HumLow%10+0x30) ;
- LCDWarning();//超標(biāo)顯示
- if(!K1)BeepFlag=0;//若K1被按下,則禁用蜂鳴器
- if(!K2)BeepFlag=1;//若K2被按下,則啟用蜂鳴器
- if(BeepFlag) BEEP();
- }
- }
復(fù)制代碼
|
|