|
這是我做的溫濕度控制系統資料。采用sht71溫濕度傳感器作為檢測元件。
包含proteus仿真資料。
源代碼。
0.png (32.95 KB, 下載次數: 115)
下載附件
2016-6-6 17:18 上傳
程序如下:
- /*注意:子函數多層調用時,要記住:寫子函數以及子函數聲明用形參;而調用子函數用實參*/
- /*頭文件*/
- #include<reg52.h>
- #include<intrins.h>
- #include<math.h>
- #include<hc595.h>
- #include<delay.h>
- #include<actuator.h>
- #include<ini.h>
- #include<sht71.h>
- /*全局變量定義 */
- uchar code duan[21]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
- 0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,
- 0x40}; //CC碼表:數字0~9 帶小數點數字0~9 負號
- uchar code wei[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//從LED0-7
- uchar high8=0,low8=0;//傳感器16位數據高低8位
- uchar temphigh8=0,templow8=0;//溫度高低8位
- uchar humihigh8=0,humilow8=0;//濕度高低8位
- long SO_RH=0;//濕度10進制數據
- long SO_T=0;//溫度10進制數據
- char temp; //實際溫度值,溫度分正負
- char temp_2;//因為濕度值計算時會用到溫度值,防止對temp數學處理過程引起的值變化影響濕度的計算,故將temp賦給temp_2保存以用于濕度計算
- char humi_relative;//相對濕度值,濕度只有正值
- char humi; //實際濕度值
- uchar a1,b1,c1,d1;//正負位、十位、個位、小數位
- uchar a2,b2,c2,d2;//正負位、十位、個位、小數位
- uchar error_command;//通訊檢查信號 0正常 1錯誤
- uchar temp_max,temp_min;//溫度上下極限值
- uchar p[16];
- /**********************溫濕度測量子函數***********************/
- void sht_measurement(uchar measure)
- {
- measurement_start();
- command_send(measure);
- measurement_wait();
- mcu_receive_date();
- }
- /************************啟動測量子函數***********************/
- void measurement_start()
- {
- SCK=0;//賦予時鐘線初始電平
- DATE=1;//賦予數據線初始電平
-
- SCK=1;
- _nop_();
- _nop_();
- DATE=0;
- _nop_();
- _nop_();
- SCK=0;
- _nop_();
- _nop_();//時鐘線低電平保持
- SCK=1;
- _nop_();
- _nop_();
- DATE=1;
- _nop_();
- _nop_();
- SCK=0;
- }
- /*********************發送測量命令子函數*********************/
- char command_send(uchar command) //寫時序:上升沿-高電平保持-下降沿
- { //注意:要先給DATE,再給寫時序(SCK)
- uchar value=0x80,i=0;
- SCK=0;//寫時序初始低電平
- for(i=0;i<8;i++)
- {
- if(command&value)
- DATE=1;
- else DATE=0;
- SCK=1;
- _nop_();
- SCK=0;
- value=value>>1;
- }
- SCK=1;
- if(DATE==0)
- error_command=0;
- SCK=0; //第9脈沖,即ACK脈沖,同時也是一個讀脈沖
- if(error_command==1)
- sht_reset();//如果通訊錯誤,則傳感器軟件復位
-
- return error_command; //error=1通訊錯誤
- }
- /***********************測量等待子函數*********************/
- void measurement_wait()
- {
- delay(40000);//測量等待390ms(20/80/320ms對應8、12、14位)
- }
- /***********************讀數據子函數**********************/
- void mcu_receive_date()
- {
- high8=mcu_receive_byte();
-
- DATE=0;//寫時序:上升沿-高電平保持-下降沿
- SCK=1;_nop_();_nop_();
- SCK=0;_nop_();_nop_();//接收完高字節數據后,手動拉低數據線(寫0),表示接收結束
- DATE=1;
-
- low8=mcu_receive_byte();
- DATE=1;//寫時序:上升沿-高電平保持-下降沿
- SCK=1;_nop_();_nop_();
- SCK=0;_nop_();_nop_();//接收完高字節校數據后,手動拉高數據線,傳感器不經校驗,直接休眠
- }
- /***********************讀字節子函數***********************/
- uchar mcu_receive_byte()
- {
- uchar value=0x80,dat=0,i=0;
- SCK=0;//讀時序初始低電平
- for(i=0;i<8;i++) //讀時序:低電平保持-上升沿-高電平保持
- {
- SCK=1;_nop_();
- if(DATE)
- dat=dat|value;
- SCK=0;_nop_();
- value=value>>1;
- }
- return dat;
- }
- /******************取實際溫度子函數********************/
- void temperature_calculate()
- {
- float d1_5V=-40.1;//定義溫度計算公式參數
- float d2_14bit=0.01;//定義溫度計算公式參數
- temphigh8=high8;
- templow8=low8;
- SO_T=temphigh8;//先賦值給低8位
- SO_T=((SO_T<<8)&0xff00)|templow8;//將兩個8位合成一個16位。與0xff00與運算,目的在于清低八位,避免不穩定錯誤
- SO_T=SO_T&0x3fff;//sht溫度精度默認為最高14位,即temp16的高2位為0,這里人為將高2位清零,避免不穩定錯誤。0011 1111 1111 1111=0x3fff
- temp=d1_5V+d2_14bit*SO_T;
- compensation_temp();//正溫度修正
- temp_2=temp;
- }
- /******************分離溫度值子函數********************/
- void temperature_seperate()
- {
- uchar i=0;//正負數標志位
- i=0x80&temp;//取符號位,判斷正負
- if(i)
- {
- temp=temp-1; //由補碼取原碼
- temp=~temp;
- a1=20;
- b1=(temp*10)/100;
- c1=((temp*10)%100)/10;
- d1=((temp*10)%100)%10;
- temp=~temp; //還原補碼,防止下次顯示將負數掃描成正數
- temp=temp+1;
- /*負溫度范圍補償代碼 統一上浮1度,使得精度保證在+-1度以內
- -12度以內,顯示誤差為0;-12以下,顯示誤差為-1度*/
- if(c1==9)
- {
- c1=0;
- b1+=1;
- }
- else
- {
- c1+=1;
- }
- c1+=10; //+10表示附帶小數點
- p[0]=a1;
- p[1]=b1;
- p[2]=c1;
- p[3]=d1;
- }
- else
- {
- a1=0;
- b1=(temp*10)/100;
- c1=((temp*10)%100)/10;
- d1=((temp*10)%100)%10;
- c1+=10; //+10表示附帶小數點
- p[0]=a1;
- p[1]=b1;
- p[2]=c1;
- p[3]=d1;
- }
- }
- /*****************溫度極限值分離子函數*********************/
- void temperature_limit_seperate()
- {
- uchar min1,min2,max1,max2;//溫度下限十位、溫度下限個位、溫度上限十位、溫度上限個位
- temp_min=10;temp_max=50;
-
- min1=temp_min/10;
- min2=temp_min%10;
- max1=temp_max/10;
- max2=temp_max%10;
-
- p[8]=min1;
- p[9]=min2;
- p[10]=max1;
- p[11]=max2;
- p[12]=8;
- p[13]=8;
- p[14]=8;
- p[15]=8;
- }
- /*****************溫濕度顯示子函數*********************/
- void display()
- {
- uchar m=0;
- for(m=0;m<16;m++)
- {
- if(m<8) //掃描顯示前8位數碼管,屏蔽后8位數碼管(因為數據線共用)
- {
- InputData(0xff); //給第三片595送屏蔽位選,LED8~15
- InputData(wei[m]); //給第二片595送位選,LED0~7
- InputData(duan[p[m]]);
- OutputData();
- delay(100);
- }
- else //掃描顯示后8位數碼管,屏蔽前8位數碼管(因為數據線共用)
- {
- InputData(wei[m-8]); //給第三片595送位選,LED8~15
- InputData(0xff); //給第三片595送屏蔽位選,LED0~7
- InputData(duan[p[m]]);
- OutputData();
- delay(100);
- }
- }
- }
- /****************取實際濕度子函數**********************/
- void humidity_calculate()
- {
- float c1_12bit=-2.0468,c2_12bit=0.0367,c3_12bit=-0.0000015955;//定義濕度計算公式參數
- float t1_12bit=0.01;//定義濕度計算溫補公式參數
- float t2_12bit=0.00008;//定義濕度計算溫補公式參數
- humihigh8=high8;
- humilow8=low8;
- SO_RH=humihigh8; //先賦值給低8位
- SO_RH=((SO_RH<<8)&0xff00)|humilow8;//將兩個8位合成一個16位。
- SO_RH=SO_RH&0x0fff;//濕度精度默認12位。0000 1111 1111 1111=0x0fff
- humi_relative=c1_12bit+c2_12bit*SO_RH+c3_12bit*SO_RH*SO_RH;
- // humi=(temp_2-25)*(t1_12bit+t2_12bit*SO_RH)+humi_relative; //溫度補償
- humi=humi_relative;
- compensation_humi();//濕度誤差修正
- }
- /******************分離濕度值子函數********************/
- void humidity_seperate()
- {
- a2=0;
- b2=(humi*10)/100;
- c2=((humi*10)%100)/10;
- d2=((humi*10)%100)%10;
-
- c2+=10; //+10表示附帶小數點
- p[4]=a2;
- p[5]=b2;
- p[6]=c2;
- p[7]=d2;
- }
- /*******************濕度補償子函數******************/
- void compensation_humi()
- {
- if(humi<=12) //0~7%
- {
- humi-=5;
- }
- else
- {
- if(humi<=20) //8~16%
- {
- humi-=4;
- }
- else
- {
- if(humi<=33) //17~30%
- {
- humi-=3;
- }
- else
- {
- if(humi<=93) //31~91%
- {
- humi-=2;
- }
- else
- {
- if(humi<=103) //92~100%
- {
- humi-=3;
- }
- }
- }
- }
- }
- }
- /************************軟復位子函數******************/
- void sht_reset()
- {
- uchar i;
- while(DATE==1)
- {
- SCK=0;
- for(i=0;i<12;i++) //數據線高電平的情況下,給時鐘線至少9個脈沖
- {
- SCK=1;
- _nop_ ();
- SCK=0;
- _nop_ ();
- }
- }
- }
- /************************溫度補償子函數******************/
- void compensation_temp()
- {
- if(temp>=20)
- {
- temp+=1;
- }
- if(temp>=53)
- {
- temp+=1;
- }
- if(temp>=86)
- {
- temp+=1;
- }
- }
復制代碼
0.png (80.98 KB, 下載次數: 134)
下載附件
2016-6-6 17:15 上傳
全部資料請下載附件:
|
-
-
SHT71模塊化最終版本.rar
2016-6-6 17:07 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
113.2 KB, 下載次數: 146, 下載積分: 黑幣 -5
評分
-
查看全部評分
|