|
89c52rc單片機控制超聲波測距和讀取實時的溫濕度情況,按鍵控制切換注釋準(zhǔn)確。
詳情見文件
單片機源程序如下:
- #include <reg52.h> //51 的頭文件
- #include <intrins.h> //超聲波的固有函數(shù)頭文件
- #define uchar unsigned char //表示之后代碼中的“uchar”全部代表“unsigned char”
- #define uint unsigned int //定義uint為無符號整型。
- #define LCD_databus P2 //定義LCD的數(shù)據(jù)口為P2
- //全局變量定義
- unsigned int time; //聲明無符號類型 time
- unsigned int S,s_false; //聲明無符號類型
- unsigned long num1; //聲明無符號長整數(shù)
- bit flag;
- //12864液晶顯示定義
- uchar code sj1[]={"<<超聲波測距儀>>"};
- uchar code sj4[]={"當(dāng)前距離:"};
- uchar code sj5[]={"錯誤 "};
- uchar dht_num=0; //用于while循環(huán)中計數(shù),超時則跳出循環(huán)
- uchar code table[]={"溫度:"};
- uchar code table1[]={"濕度:"};
- uchar code table2[]={"℃"};
- uchar dht_d1=0,dht_d2=0 ; //依次為濕度整數(shù)部分和濕度小數(shù)部
- uchar dht_t1=0,dht_t2=0 ; //依次為溫度整數(shù)部分和溫度小數(shù)部分
- uchar dht_j=0; //和校驗,可選擇是否使用,具體參照數(shù)據(jù)手
- uchar i,t11,t12,d11,d12;
- uchar t21,t22,d21,d22;
- //超聲波引腳定義
- sbit Trig =P1^0; //定義引腳
- sbit Echo =P1^1;
- //12864液晶引腳定義
- sbit RS=P0^7; //命令數(shù)據(jù)
- sbit RW=P0^6; //讀寫
- sbit EN =P0^5;
- sbit dht_dat=P1^2; //用哪個I/O口自選,注意不要用P2口
- //定義按鍵
- sbit key1 = P3^5;
- sbit key2 = P3^4;
- /*****************ms延時函數(shù)*********************************/
- void delay(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- /*****************20us延時函數(shù)*********************************/
- void delay_20us()
- {
- uchar a;
- for(a=0;a<100;a++);
- }
- /*****************ms延時函數(shù)*********************************/
- void dh11delayms(uint xms)
- {
- uint i,j;
- for(i=xms;i>0;i--)
- for(j=110;j>0;j--);
- }
- /*****************us延時函數(shù)*****************************/
- void delay_10us()
- {
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- }
- /*寫指令函數(shù)*/
- /*rs=l,rw=l,en=高脈沖,D0-D7=指令碼。*/
- void write_cmd(uchar cmd)
- {
- RS=0;
- RW=0;
- EN=0;
- LCD_databus=cmd;
- dh11delayms(5);
- EN=1;
- dh11delayms(5);
- EN=0;
- }
- /***************************寫顯示數(shù)據(jù)************************/
- /*rs=h,rw=l,*/
- void write_dat(uchar date)
- {
- RS=1;
- RW=0;
- EN=0;
- LCD_databus=date;
- dh11delayms(5);
- EN=1;
- dh11delayms(5);
- EN=0;
- }
- /*****************初始化************************/
- void DH11init()
- {
- EN=0;
- RW=0;
-
- write_cmd(0x30); //基本指令操作
- dh11delayms(5);
- write_cmd(0x0c); //顯示開,關(guān)光標(biāo)
- dh11delayms(5);
- write_cmd(0x06);
- dh11delayms(2);
- write_cmd(0x01); //清除顯示內(nèi)容
- dh11delayms(5);
-
-
- }
- void dht_init()
- {
- dh11delayms(1000); //DHT11上電前準(zhǔn)備時間,大概1s
- dht_dat=1; // //總線準(zhǔn)備
- }
- uchar read_date() //接收一個8位數(shù)據(jù),先高位后低位
- {
- uchar i,dat;
- for(i=0;i<8;i++) //也就是說程序是循環(huán)八次,把判斷有“1”輸出到dat中,然后輸出一個八位的數(shù)據(jù)。
- {
- dht_num=2;
- while((dht_dat==0)&&(dht_num++)); //dht_dat 數(shù)據(jù)線由DH11拉低準(zhǔn)備發(fā)送數(shù)據(jù)
- delay_10us();
- delay_10us();
- delay_10us();
- delay_10us();
- dat=dat<<1;
- if(dht_dat==1)
- {
- dht_num=2;
- dat=dat|0x01; //如果來自DQ的數(shù)據(jù)是高電平1,則把1放到dat的最低位
- while((dht_dat==1)&&(dht_num++));
- }
- }
- return dat;
- }
- void get_temp() //給DHT11一個開始信號,然后讀取一次數(shù)據(jù),共五個8位字節(jié)
- {
- dht_dat=0;
- dh11delayms(25);
- dht_dat=1; //單片機給起始脈沖信號
- delay_10us();
- delay_10us();
- delay_10us();
- delay_10us();
- dht_dat=1; //稍作延時,等待DHT11返回響應(yīng)(響應(yīng)為低電 平)
- if(dht_dat==0) //有響應(yīng)才接收數(shù)據(jù),否則不作處理
- {
- dht_num=2;
- while((dht_dat==0)&&(dht_num++));
- dht_num=2;
- while((dht_dat==1)&&(dht_num++));
- dht_d1=read_date();
- dht_d2=read_date();
- dht_t1=read_date();
- dht_t2=read_date();
- dht_j=read_date(); //一次讀出五個數(shù)據(jù)
- }
- dht_dat=1; //釋放總線
- dh11delayms(10);
- d11=dht_d1/10;
- d12=dht_d1%10;
- t11=dht_t1/10;
- t12=dht_t1%10;
-
- d21=dht_d2/10;
- d22=dht_d2%10;
- t21=dht_t2/10;
- t22=dht_t2%10;
-
- }
- //2864液晶寫命令函數(shù)
- void xmn(unsigned char com)
- {
- RS=0;
- LCD_databus=com;
- delay(5);
- EN=1;
- delay(5);
- EN=0;
- }
- //2864液晶寫數(shù)據(jù)函數(shù)
- void xsj(unsigned char zifu)
- {
- RS=1;
- LCD_databus=zifu;
- delay(5);
- EN=1;
- delay(5);
- EN=0;
- }
- //2864液晶顯示函數(shù)1
- void xs1()
- {
- uchar i;
- xmn(0x80);
- for(i=0;i<16;i++)
- {
- xsj(sj1[i]);
- }
-
-
- xmn(0x88);
- for(i=0;i<16;i++)
- {
- xsj(sj4[i]);
- }
- }
- //2864液晶顯示函數(shù)2
- void xs2(uint t_emp)
- {
- uchar qian,bai,shi,ge;
- qian=t_emp/1000;
- bai=(t_emp%1000)/100;
- shi=(t_emp%100)/10;
- ge=t_emp%10;
- xmn(0x8d);
- xsj(0x30+qian);
- delay(1);
- xsj(0x30+bai);
- delay(1);
- xsj(0x30+shi);
- delay(1);
- xsj(0x30+ge);
- delay(1);
- xsj('c');
- delay(1);
- xsj('m');
- delay(100);
- }
- //超聲波計數(shù)函數(shù)
- void T0_time() interrupt 1 //T0中斷用來計數(shù)器溢出,超過測距范圍
- {
- flag=0; //中斷溢出標(biāo)志,失敗
- TH0=0;
- TL0=0;
- TR0=0; //關(guān)閉計數(shù)
- }
- //中斷定時函數(shù)
- void T1_timer() interrupt 3 //中斷
- {
- TH1=(65536-50000)/256;
- TL1=(65536-50000)%256;
- num1++;
- }
- //超聲波模塊啟動函數(shù)
- void StartModule() //啟動模塊
- {
- Trig=1; //啟動一次模塊
- _nop_();_nop_();_nop_();_nop_();_nop_();
- _nop_();_nop_();_nop_();_nop_();_nop_();
- _nop_();_nop_();_nop_();_nop_();_nop_();
- _nop_();_nop_();_nop_();_nop_();_nop_();
- _nop_();
- Trig=0;
- }
- //超聲波測試距離計算函數(shù)
- void Count(void)
- {
- uchar i;
- time=TH0*256+TL0;
- TH0=0;
- TL0=0;
- S=(time*1.7)/100; //算出來是CM
- if(((S<1)||(S>=600))||flag==0) //超出測量范圍顯示“-”失敗
- {
-
- s_false=1000;
- xmn(0x8d);
- for(i=0;i<6;i++)
- {
- xsj(sj5[i]);
- }
-
- }
- else
- {
- xs2(S);
- }
- }
- //12864液晶初始化函數(shù)
- void init()
- {
- delay(100);
- xmn(0x30);
- delay_20us();
- xmn(0x30);
- delay_20us();
- xmn(0x0c);
- delay_20us();
- xmn(0x01);
- delay_20us();
- xmn(0x06);
- delay_20us();
- }
- void WSD()
- {
- dht_init();
- DH11init();
- while(1)
- {
- get_temp();
-
-
-
-
- write_cmd(0x80);
- for(i=0;i<6;i++)
- {
- write_dat(table[i]);
- }
- write_cmd(0x83);
- write_dat(0x30+t11);
- write_dat(0x30+t12);
- write_cmd(0x80+4);
- write_dat('.');
- write_dat(0x30+t21);
- write_cmd(0x85);
- write_dat(0x30+t22);
- write_cmd(0x86);
- for(i=0;i<4;i++)
- {
- write_dat(table2[i]);
- }
- write_cmd(0x90);
- for(i=0;i<6;i++)
- {
- write_dat(table1[i]);
- }
- write_cmd(0x93);
- write_dat(0x30+d11);
- write_dat(0x30+d12);
- write_cmd(0x94);
- write_dat('.');
- write_dat(0x30+d21);
- write_cmd(0x95);
- write_dat(0x30+d22);
- write_cmd(0x96);
- write_dat('%');
- }
- }
- void CSB()
- {
- delay(500); //啟動等待,等LCM講入工作狀態(tài)
- RW=0;
- init(); //LCM初始化
- delay(500); //延時片刻(可不要)
- while(1)
- {
- TMOD=0x11; //設(shè)T0為方式1,GATE=1;
- TH0=0;
- TL0=0;
- ET0=1; //允許T0中斷
- ET1=1;
- TR1=1;
- EA=1; //開啟總中斷
- xs1();
- Trig=0;
- Echo=0;
- while(1)
- {
- StartModule();
- flag=1;
- //while(!Echo); //當(dāng)echo為零時等待
- while((!Echo)&&flag);//當(dāng)echo為零時等待,中斷flag跳出等待
- TR0=1; //開啟計數(shù)
- while(Echo&&flag); //當(dāng)echo為1計數(shù)并等待
- TR0=0; //關(guān)閉計數(shù)
- Count(); //計算
- delay(120); //80MS
- }
- }
- }
- void keyscan()
- {
-
- if(key1 == 0)
- {
-
- if(key1 == 0)
- {
- CSB();
- }
- }
-
- if(key2 == 0)
- {
-
- if(key2 == 0)
- WSD();
- }
- }
-
- void main(void)
-
- {
- while(1)
-
- {
-
- keyscan();}
- }
復(fù)制代碼
51hei.png (5.64 KB, 下載次數(shù): 48)
下載附件
2021-4-25 19:49 上傳
以上的代碼51hei提供下載:
整合版本加按鍵.zip
(61.35 KB, 下載次數(shù): 129)
2021-4-24 23:33 上傳
點擊文件名下載附件
按鍵控制 下載積分: 黑幣 -5
|
|