基于SHT11的溫濕度傳感器的仿真,有需要的下載
0.png (33.12 KB, 下載次數: 68)
下載附件
2017-4-30 17:18 上傳
0.png (77.44 KB, 下載次數: 74)
下載附件
2017-4-30 17:17 上傳
單片機源代碼:
- #include <reg52.h> //頭文件
- #include <intrins.h>
- #include <stdio.h> //
- #include <math.h> //Keil library
- //**************************************
- sbit DATA =P1^1;//數據
- sbit SCK=P1^0;//時鐘
- #define TEMP_ML 0x03 //000 0001 1 溫度命令
- #define HUMI_ML 0x05 //000 0010 1 溫度命令
- unsigned char error ;//全局錯誤變量
- unsigned char ack ;//全局應答變量
- //float temp_zi ;//全局應答變量
- //float humi_zi ;//全局應答變量
- unsigned char temp_h ;//全局應答變量
- unsigned char temp_LL ;//全局應答變量
- #define uchar unsigned char //定義一下方便使用
- #define uint unsigned int
- #define ulong unsigned long
- unsigned int recs=0;//接收次數
- const unsigned char X_WD[11]="當前溫度:+-";
- const unsigned char X_SD[10]="當前濕度:";
- const unsigned char S_WD[11]="報警溫度:+-";
- const unsigned char S_SD[10]="報警濕度:";
- const unsigned char SHUO[15]="0123456789.%RH";
- const unsigned char DU_ZHI[6]="℃ ";
- int xts_zi=0 ;//溫度值
- int xtg_zi=0 ;//溫度個位值
- int xtd_zi=0 ;//溫度點值
- int xss_zi=0 ;//濕度值
- int xsg_zi=0 ;//濕度個位值
- int xsd_zi=0 ;//濕度點值
- int sts_zi=6 ;//溫度值
- int stg_zi=0 ;//溫度個位值
- int std_zi=0 ;//溫度點值
- int sss_zi=9 ;//濕度值
- int ssg_zi=0 ;//濕度個位值
- int ssd_zi=0 ;//濕度點值
- int szf=1 ;//設正負
- int xzf=1 ;//顯正負
- //**************************************
- sbit E_CLK =P0^7;//起始信號
- sbit RW_SID=P0^6;//H:讀 L:寫
- sbit RS_CS =P0^5;// H:數據 L:命令
- sbit soud =P0^0;// 聲音
- //*******************************基本驅動程
- void busyaaa_check(void)
- {
- uchar keyx;
- P2=0XFF;
- while(1)
- {
- RS_CS=0;//命令
- RW_SID=1;//讀
- E_CLK=1;
- keyx=P2;
- E_CLK=0;
- if((keyx&0X80)==0X00)
- break;
- }
- }
- void wcom(unsigned char com)//并口寫命令
- {
- busyaaa_check();//忙檢測
- RS_CS=0; //以命令方式
- RW_SID=0;//寫
- E_CLK=1;//使能信號開始
- //nop();
- P2=com;//送出數據
- //_nop_();
- E_CLK=0;//不使能
- }
- void wdata(unsigned char dat)//并口寫數據
- {
- busyaaa_check();//忙檢測
- RS_CS=1;//以數據方式
- RW_SID=0;//寫
- E_CLK=1;//使能
- // nop();
- P2=dat;//寫入數據
- // nop();//延時
- E_CLK=0;//不使能
- }
- //
- //**************************系統初始化
- //**************************
- void initlcd_char(void)
- {
- wcom(0x30);//基本指令
- wcom(0x0C);//0000,1100 游標顯示關 整體顯示開
- // wcom(0x01);//0000,0001 清除顯示RAM
- wcom(0x02);//0000,0010 顯示RAM 地址歸位
- wcom(0x80);//1000,0000 設定顯示RAM 地址到地址計數器
- wcom(0x06);//0000 0110 右移位
- wcom(0x0c);//0000 1100開顯示
- }
- //****清屏******************
- void clear(void)
- {
- wcom(0x30);//基本指令
- wcom(0x01);//清屏
- }
- //****************************調用字庫顯示漢字
- //***************************************
- //printf 函數用到的函數。要在STDIO.H 中將原有的PUTCHAR 函數屏蔽。
- //寫漢字要在基本指令集下進行。
- void putchara(unsigned char cc)
- {
- switch(cc)
- {
- case 'c' : //clear
- wcom(0x01);
- break ;
- case 'f' : //first line
- wcom(0x80);
- break ;
- case 's' : //second line
- wcom(0x90);
- break ;
- case 't' : //third line
- wcom(0x88);
- break ;
- case 'd' : //fourth line
- wcom(0x98);
- break ;
- default :
- wdata(cc); //data
- break;
- }
- }
- //--顯示字---
- xian_zhi_t()
- {
- int i;
- for (i=0;i<9;i++)
- wdata(X_WD[i]);
- if(xzf==1)
- wdata(X_WD[9]);
- else
- wdata(X_WD[10]);
-
- wdata(SHUO[xts_zi]);//十位
- wdata(SHUO[xtg_zi]);//個位
- wdata(SHUO[10]);//點
- wdata(SHUO[xtd_zi]);//點值
- for (i=0;i<2;i++)
- wdata(DU_ZHI[i]);
- }
- /////////////////
- xian_zhi_s()
- {
- int i;
- for (i=0;i<9;i++)
- wdata(X_SD[i]);
- wdata(SHUO[xss_zi]);//十位
- wdata(SHUO[xsg_zi]);//個位
- wdata(SHUO[10]);//點
- wdata(SHUO[xsd_zi]);//點值
- for (i=11;i<14;i++) //RH
- wdata(SHUO[i]);
- }
- //--設定---
- set_zhi_t()
- {
- int i;
- for (i=0;i<9;i++)
- wdata(S_WD[i]);
- if(szf==1)
- wdata(S_WD[9]);
- else
- wdata(S_WD[10]);
- wdata(SHUO[sts_zi]);//十位
- wdata(SHUO[stg_zi]);//個位
- wdata(SHUO[10]);//點
- wdata(SHUO[std_zi]);//點值
- for (i=0;i<2;i++)
- wdata(DU_ZHI[i]);
- }
- //////////////
- set_zhi_s()
- {
- int i;
- for (i=0;i<9;i++)
- wdata(S_SD[i]);
- wdata(SHUO[sss_zi]);//十位
- wdata(SHUO[ssg_zi]);//個位
- wdata(SHUO[10]);//點
- wdata(SHUO[ssd_zi]);//點值
- for (i=11;i<14;i++) //RH
- wdata(SHUO[i]);
- }
- /////////////////
- //////////////////////
- char read() //讀一個字節 返回應答信號
- //----------------------------------------------------------------------------------
- // reads a byte form the Sensibus and gives an acknowledge in case of "ack=1"
- {
- unsigned char i,val=0;
- temp_LL=0;
- temp_h=0;
- DATA=1; //釋放數據總線
- for (i=0x80;i>0;i/=2) //位移8位
- { SCK=1; //上升沿讀入
- if (DATA) val=(val | i); //確定值
- SCK=0;
- }
- DATA=0; //讀應答信號,有應答為1,為應答為0 通過CPU下拉為應答
- SCK=1; //第9個脈沖
- _nop_(); _nop_(); _nop_(); //pulswith approx. 5 us
- SCK=0;
- DATA=1; //釋放數據總線
- temp_h=val;
- val=0;
- ////低8位/////////////////////////////
- DATA=1; //釋放數據總線
- for (i=0x80;i>0;i/=2) //位移8位
- { SCK=1; //上升沿讀入
- if (DATA) val=(val | i); //確定值
- SCK=0;
- }
- DATA=1;//0; //不需要應答 通過CPU下拉為應答
- SCK=1; //第9個脈沖
- _nop_(); _nop_(); _nop_(); //pulswith approx. 5 us
- SCK=0;
- DATA=1; //釋放數據總線
- temp_LL=val;
- }
- ////////////
- char write(unsigned char value) //寫一個字節 返回應答信號
- //---------------------------------------------------------
- {
- unsigned char i ;
- ack=0;
- for (i=0x80;i>0;i/=2) //釋放數據總線
- { if (i & value) DATA=1; //寫入值
- else DATA=0;
- SCK=1; //上升沿寫入
- _nop_(); _nop_(); _nop_(); //延時
- SCK=0;
- }
- DATA=1; //釋放數據總線
- SCK=1; //第9個脈沖
- if (DATA==1) ack=1;
- //讀應答信號
- SCK=0;
- return ack; //error=1 表示沒有應答
- }
- ////////
- void start(void) //啟動
- //--------------------------------------------------------
- {
- DATA=1; SCK=0; //數據為1,SCK=0
- _nop_();
- SCK=1; //第一個脈沖
- _nop_();
- DATA=0; //數據跌落
- _nop_ ();
- SCK=0; //完成一個脈沖
- _nop_(); _nop_(); _nop_();
- SCK=1; //再一個脈沖
- _nop_();
- DATA=1; //數據變為1
- _nop_();
- SCK=0; //完成該脈沖
- }
- //////////////////////////////////
- void sht_rest(void) //復位
-
- {
- unsigned char i;
- DATA=1; SCK=0; //數據為1 時鐘為0
- for(i=0;i<9;i++) //9 個脈沖為 復位
- { SCK=1;
- SCK=0;
- }
- start(); //啟動
- }
- ////////////////////////////////
- ///////
- //測量溫度或者是溫度,返回校驗值
- text_a(unsigned char ml)
- {
- unsigned int i;
- start(); //啟動
- write(ml);//寫入測溫度
- if (ack==1)
- {
- sht_rest() ;//復位
- write(ml);//寫入測溫度
- }
-
- //判斷是否處于忙
- // DATA=1;//釋放數據總線
- for (i=0;i<65535;i++) if(DATA==0) break;
- read();//讀溫度
- }
- ///////
- text_jishuan_temp11()
- {
- error=0;
- ack=0;
- sht_rest() ;//復位
- text_a(TEMP_ML);
- text_jishuan_temp();
- text_a(HUMI_ML);
- text_jishuan_humi();
- }
- /////
- //////////////
- text_jishuan_temp()
- {
- float aa=0,bb=0,temp_zi;
- int abcd=0;
- aa=(float)temp_h*256+(float)temp_LL;
- temp_zi=0.01*aa-40;
- //
- xzf=1;
- if (temp_zi<0)
- { xzf=0;
- temp_zi=-temp_zi ;
- }
- temp_zi=temp_zi*10;
- abcd=(int)temp_zi;
- xts_zi=abcd/100;
- abcd=abcd%100;
- xtg_zi=abcd/10;
- abcd=abcd%10;
- xtd_zi=abcd/1;
- }
- /////////////
- text_jishuan_humi()
- {
- float aa=0,bb=0,humi_zi;
- int abcd=0;
- aa=(float)temp_h*256+(float)temp_LL;
- bb=aa*aa*2.8/1000000;
- aa=0.0405*aa;
- aa=aa-4-bb;
- humi_zi=aa;
- //
- humi_zi=humi_zi*10;
- abcd=(int)humi_zi;
- xss_zi=abcd/100;
- abcd=abcd%100;
- xsg_zi=abcd/10;
- abcd=abcd%10;
- xsd_zi=abcd/1;
- }
- ////
- //-----顯示---
- xianshi()
- {
- putchara('f');//在第一行顯示
- xian_zhi_t();
-
- putchara('s');//在第二行顯示
- xian_zhi_s();
- putchara('t');//在第三行顯示
- set_zhi_t();
-
- putchara('d');//在第四行顯示
- set_zhi_s();
- }
- /////////////////////////////////
- ///////////////////////////////////////////
- ///////////////////////////////////////////
- ////接收給值/////
- void rece(int cc)
- {
- switch(cc)
- {
- case 1 : //clear
- { if (SBUF==0XCC) break;
- else
- {recs=0; //判斷頭對不對
- break;
- }
- }
- case 2 : //clear
- szf=(int) SBUF;
- break;
- case 3 : //clear
- sts_zi=(int) SBUF;
- break;
- case 4 : //clear
- stg_zi=(int) SBUF;
- break;
- case 5 : //clear
- std_zi=(int) SBUF;
- break;
- case 6 : //clear
- { if (SBUF==0xdd) break;
- else
- {recs=recs-6;
- break;
- }
- }
- case 7 : //clear
- sss_zi=(int) SBUF;
- break;
- case 8 : //clear
- ssg_zi=(int) SBUF;
- break;
- case 9 : //clear
- ssd_zi=(int) SBUF;
- break;
- }
- }
- ///////////////////////////////
- void text_232_main()
- {
- TI=0; //清發送完標志
- SBUF=0xaa; //AA頭碼
- while(!TI); //等發送完
- TI=0;
- SBUF=(char) xzf ;//發送正負
- while(!TI); //等發送完
- TI=0;
- SBUF=(char) xts_zi ;//發送正負
- while(!TI); //等發送完
- TI=0;
- SBUF=(char) xtg_zi ;//發送正負
- while(!TI); //等發送完
- TI=0;
- SBUF=(char) xtd_zi ;//發送正負
- while(!TI); //等發送完
- TI=0;
- SBUF=0xbb ;//發送正負
- while(!TI); //等發送完
- TI=0;
- SBUF=(char) xss_zi ;//發送正負
- while(!TI); //等發送完
- TI=0;
- SBUF=(char) xsg_zi ;//發送正負
- while(!TI); //等發送完
- TI=0;
- SBUF=(char) xsd_zi ;//發送正負
- while(!TI); //等發送完
- TI=0;
- }
- ///////////////
- void intrr() interrupt 4 //接收和發送中斷
- {
- char temp;
- if(RI)
- {
- RI=0;
- recs++;
- rece(recs); //接收給值
- while(recs==9) recs=0;
-
- temp=SBUF;
- P2=temp;
- }
- if(TI)
- {
- P0=SBUF ;
- }
- }
- //初始化串行口
- void csh()
- {
- SCON=0X50; //允許接收 工作方式1
- TI=0; //清發送完成標志
- RI=0; //清接收完成標志
- PCON=0; //波特率不加倍
- TH1=0xFD; //初始波特率的值
- TL1=0XFD;
- TMOD=0X20; //定時1工作方式1,自動裝載定時器值
- EA=1; //允許總中斷
- ET1=0; //不允許定時器0中斷
- ES=1; //允許串口中斷
- TR1=1; //啟動TM1
- }
- /////////////////////////////////
- //////////
- text_baojing()//報警
- {
- int temp1=0,temp2=0;
- temp1=xss_zi*100+xsg_zi*10+xsd_zi;
- temp2=sss_zi*100+ssg_zi*10+ssd_zi;
- while ((temp1-temp2)>0)
- { speek_cl();
- break;
- }
- while (xzf>szf) //當顯示為正,設定為負,立即報
- { speek_cl();
- break;
- }
- temp1=xts_zi*100+xtg_zi*10+xtd_zi;
- temp2=sts_zi*100+stg_zi*10+std_zi;
- if ((xzf>0)&&(szf>0)) //如果顯示大于0,設定也大于0
- {
- while ((temp1-temp2)>0)
- {
- speek_cl();
- break;
- }
- }
- else
- {
-
- while ((temp2-temp1)>0)
- {
- speek_cl();
- break;
- }
- }
- }
- ////////
- ///////////////////////////////
- /////////////////////////////////
- speek_cl()
- {
- int i=0,j=0;
- for(i=0;i<500;i++)
- { soud=!soud ;
- for(j=0;j<30;j++);
- }
- }
- ///////////////////////
- main()
- {
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
下載:
SHT11溫濕度傳感器仿真.rar
(76.65 KB, 下載次數: 148)
2017-4-30 14:06 上傳
點擊文件名下載附件
Proteus 下載積分: 黑幣 -5
|