『壹』 100分,求溫濕度感測器SHT11的源程序(51單片機語言)
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
//數碼管位定義
sbit la = P2^6;
sbit wela = P2^7;
#define OK 1
#define ERROR 0
#define NUMBER 20
#define SIZE 5
sbit dht11 = P2^0;
uchar status;
//存放五位元組數據的數組
uchar value_array[SIZE];
/*可在其他的文件引用溫濕度值,實際是溫度的整數的10 倍
如dht11 讀回的溫度是26,則temp_value = 260, 濕度同理*/
uchar flag;
//數碼管編碼
uchar code array[]= {
0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f
};
int temp_value, humi_value;
void InitTime(void);
//void Delay_1ms(uint ms);
void SMG_Display(uint value);
void Delay_1ms(uint ms)
{
uint x, y;
for(x = ms; x > 0; x--)
{
for(y = 124; y > 0; y--);
}
}
void Delay_10us(void)
{
unsigned char i;
i--;
i--;
i--;
i--;
i--;
i--;
}
/*讀一個位元組的數據*/
uchar ReadValue(void)
{
uchar count, value = 0, i;
status = OK; //設定標志為正常狀態
for(i = 8; i > 0; i--)
{
//高位在先
value <<= 1;
count = 0;
//每一位數據前會有一個50us 的低電平時間.等待50us 低電平結束
while(dht11 == 0 && count++ < NUMBER);
if(count >= NUMBER)
{
status = ERROR; //設定錯誤標志
return 0; //函數執行過程發生錯誤就退出函數
}
//26-28us 的高電平表示該位是0,為70us 高電平表該位1
Delay_10us();
Delay_10us();
Delay_10us();
//延時30us 後檢測數據線是否還是高電平
if(dht11 != 0)
{
//進入這里表示該位是1
value++;
//等待剩餘(約40us)的高電平結束
while(dht11 != 0 && count++ < NUMBER)
{
dht11 = 1;
}
if(count >= NUMBER)
{
status = ERROR; //設定錯誤標志
return 0;
}
}
}
return (value);
}
//讀一次的數據,共五位元組
uchar ReadTempAndHumi(void)
{
uchar i = 0, check_value = 0,count = 0;
EA = 0;
dht11 = 0; //拉低數據線大於18ms 發送開始信號
Delay_1ms(20); //需大於18 毫秒
dht11 = 1; //釋放數據線,用於檢測低電平的應答信號
//延時20-40us,等待一段時間後檢測應答信號,應答信號是從機拉低數據線80us
Delay_10us();
Delay_10us();
Delay_10us();
Delay_10us();
if(dht11 != 0) //檢測應答信號,應答信號是低電平
{
//沒應答信號
EA = 1;
return ERROR;
}
else
{
//有應答信號
while(dht11 == 0 && count++ < NUMBER); //等待應答信號結束
if(count >= NUMBER) //檢測計數器是否超過了設定的范圍
{
dht11 = 1;
EA = 1;
return ERROR; //讀數據出錯,退出函數
}
count = 0;
dht11 = 1;//釋放數據線
//應答信號後會有一個80us 的高電平,等待高電平結束
while(dht11 != 0 && count++ < NUMBER);
if(count >= NUMBER)
{
dht11 = 1;
EA = 1;
return ERROR; //退出函數
}
//讀出濕.溫度值
for(i = 0; i < SIZE; i++)
{
value_array[i] = ReadValue();
if(status == ERROR)//調用ReadValue()讀數據出錯會設定status 為ERROR
{
dht11 = 1;
EA = 1;
return ERROR;
}
//讀出的最後一個值是校驗值不需加上去
if(i != SIZE - 1)
{
//讀出的五位元組數據中的前四位元組數據和等於第五位元組數據表示成功
check_value += value_array[i];
}
}//end for
//在沒用發生函數調用失敗時進行校驗
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 輸出的數據
}
else
{
//校驗數據出錯
EA = 1;
return ERROR;
}
}
}
void main(void)
{
uchar mark = 0;
//先等上電穩定
Delay_1ms(1000);
//因為讀一次數據dht11 才會觸發一次採集數據.
//即在先使用數據時採集一次數據
ReadTempAndHumi();
//因為在兩次採集數據需一定的時間間隔,這里還可減少
Delay_1ms(3000);
//設定定時器
InitTime();
while(1)
{
//三秒讀一次溫濕度
if(flag == 60)
{
flag = 0;
mark++;
/*
//讀溫濕度,可檢測函數調用是否失敗,
//函數返回OK(1)表示成功,返回ERROR(0)表示失敗
//OK和ERROR是在DHT11.H中定義的宏
*/
ReadTempAndHumi();
}
if(mark % 2 == 0)
{
//顯示溫度
SMG_Display(temp_value);
}
else
{
//顯示濕度
SMG_Display(humi_value);
}
}
}
//設定定時器
void InitTime(void)
{
TH0 = (65535 - 50000)/256;
TL0 = (65535 - 50000)%256 ;
TMOD = 0X01;
TR0 = 1;
ET0 = 1;
EA = 1;
}
//數碼管顯示函數
void SMG_Display(uint value)
{
uchar ge, , shi;
ge = value % 10;
shi = value % 100 / 10;
= value % 1000 / 100;
wela=1;
P0 = 0XFE;
wela=0;
P0 = 0XFF;
la=1;;
P0 = array[];
la=0;
Delay_1ms(2);
wela=1;
P0 = 0XFD;
wela=0;
P0 = 0XFF;
la=1;
P0 = array[shi];
P0 |= 0x80; /*顯示小數點*/
la=0;
Delay_1ms(2);
wela=1;
P0 = 0XFB;
wela=0;
P0 = 0XFF;
la=1;
P0 = array[ge];
la=0;
Delay_1ms(2);
}
//中斷函數
void timer(void) interrupt 1
{
TH0 = (65535 - 50000)/256;
TL0 = (65535 - 50000)%256;
flag++;
}
『貳』 求老師大俠幫忙看看一個關於和51單片機相連的sht11溫濕度感測器/讀取一個位元組/函數c語言
嗯,默認你已經對硬體及時序比較熟悉了,直接解釋一下數據讀取過程了
先看一下初值部分
unsigned char i,val=0;
....
for(i=0x80;i>0;i/=2)
....
先注意到val的初值為0,
i的初值為0x80(對應的二進制為 1000 0000)
每次循環之後有個'i/=2' 即i的值減半
1000 0000 0x80
0100 0000 0x40
0010 0000 0x20
....
再來看循環部分
{
SCK=1; //上升沿讀入
if(DATA)
val=(val | i); //確定值
SCK=0;
}
對於該串列埠,控制器輸出時鍾SCK下降沿之後sht11更新數據匯流排DATA,所以高電平的時候讀取數據是可靠的(具體你可以分析琢磨一下,一般的串列口是上升沿鎖存輸入指令,下降沿更新輸出數據)
下面假設串列口將要輸出的數據位0x58即依次輸出 0101 1000,高位數據首先輸出
第一次循環(此時val=0,i=0x80)
SCK=1;
上升沿之後判斷數據匯流排的電平(這之前SCK應該一直是低電平的,具體看一下你的初始化部分)
對於0x58 二進制的最高位為0,此時DATA匯流排為0, 「 if(DATA)」不滿足
val保持不變
然後SCK=0,產生下降沿,sht11更新DATA數據(執行之後DATA輸出次高位『1』)
第二次循環(此時val=0,i=0x40)
SCK=1;
上升沿之後判斷數據匯流排的電平
對於0x58 二進制的第二位為1,此時DATA匯流排為1, 「 if(DATA)」滿足,
val=(val | i);
執行後val=0x40,即將次高位數據更新
然後SCK=0,產生下降沿,更新DATA數據(執行之後DATA輸出第3位數據)
第三次循環(此時val=0(0x40,i=0x20)
SCK=1;
上升沿之後判斷數據匯流排的電平
對於0x58 二進制的第三位為0,此時DATA匯流排為0, 「 if(DATA)」不滿足,
val保持不變
然後SCK=0,產生下降沿,更新DATA數據(執行之後DATA輸出第4位數據)
....
第8次循環(此時val=0(0x58,i=0x01)
SCK=1;
上升沿之後判斷數據匯流排的電平
對於0x58 二進制的第8位為0,此時DATA匯流排為0, 「 if(DATA)」不滿足,
val保持不變
然後SCK=0,產生下降沿,更新DATA數據
這樣就把完成的8個位元組讀出來了
然後
temp_h=val;
val=0;
把高8位的數據暫存一下,並把val清零,准備讀取低8位數據
接下來的就和上面的讀取過程很相像了,不再過多解釋...
『叄』 我已經實現了單片機控制sht11溫濕度感測器,那怎麼樣才可以實現自動升
糾正一個概念,感測器不是被控制的。而感測器給單片機提供信息的。要實現控制升溫,你的單片機必需要對感測器送來的溫度信號進行處理,並與預設參數比較並給出控制量,再通過控制器件對加熱部件進行加熱控制。
實用中一般是不做降溫控制的(停止加熱後自然降溫)
『肆』 關於SHT11的編程
SHT11是瑞士Sensirion公司生產的具有I2C匯流排介面的單片全校準數字式相對濕度和溫度感測器。該感測器採用獨特的CMOSens TM技術,具有數字式輸出、免調試、免標定、免外圍電路及全互換的特點。文中對感測器的性能特點、介面時序與命令進行了詳細的闡述,給出了SHT11與單片機的介面電路及相應程序。 關鍵詞:數字式;溫濕度感測器;I2C匯流排;單片機1 概述溫濕度的測量在倉儲管理、生產製造、氣象觀測、科學研究以及日常生活中被廣泛應用,傳統的模擬式濕度感測器一般都要設計信號調理電路並需要經過復雜的校準和標定過程,因此測量精度難以保證,且在線性度、重復性、互換性、一致性等方面往往不盡人意。SHT11是瑞士Sensirion公司推出的基於CMOSensTM技術的新型溫濕度感測器。該感測器將CMOS晶元技術與感測器技術結合起來,從而發揮出它們強大的優勢互補作用。
2 性能特點SHT11溫濕度感測器的主要特性如下:●將溫濕度感測器、信號放大調理、A/D轉換、I2C匯流排介面全部集成於一晶元(CMOSensTM技術);●可給出全校準相對濕度及溫度值輸出;●帶有工業標準的I2C匯流排數字輸出介面;●具有露點值計算輸出功能;●具有卓越的長期穩定性;●濕度值輸出解析度為14位,溫度值輸出解析度為12位,並可編程為12位和8位;●小體積(7.65×5.08×23.5mm),可表面貼裝;●具有可靠的CRC數據傳輸校驗功能;●片內裝載的校準系數可保證100%互換性;●電源電壓范圍為2.4~5.5V;●電流消耗,測量時為550μA,平均為28μA,休眠時為3μA。
SHT11溫濕度感測器採用SMD(LCC)表面貼片封裝形式,管腳排列如圖1所示,其引腳說明如下:(1)GND:接地端;(2)DATA:雙向串列數據線;(3)SCK:串列時鍾輸入;(4)VDD電源端:0.4~5.5V電源端;(5~8)NC:空管腳。
3 工作原理SHT11的濕度檢測運用電容式結構,並採用具有不同保護的「微型結構」檢測電極系統與聚合物覆蓋層來組成感測器晶元的電容,除保持電容式濕敏器件的原有特性外,還可抵禦來自外界的影響。由於它將溫度感測器與濕度感測器結合在一起而構成了一個單一的個體,因而測量精度較高且可精確得出露點,同時不會產生由於溫度與濕度感測器之間隨溫度梯度變化引起的誤差。CMOSensTM技術不僅將溫濕度感測器結合在一起,而且還將信號放大器、模/數轉換器、校準數據存儲器、標准I2C匯流排等電路全部集成在一個晶元內。SHT11感測器的內部結構框圖如圖2所示。SHT11的每一個感測器都是在極為精確的濕度室中校準的。SHT11感測器的校準系數預先存在OTP內存中。經校準的相對濕度和溫度感測器與一個14位的A/D轉換器相連,可將轉換後的數字溫濕度值送給二線I2C匯流排器件,從而將數字信號轉換為符合I2C匯流排協議的串列數字信號。
由於將感測器與電路部分結合在一起,因此,該感測器具有比其它類型的濕度感測器優越得多的性能。首先是感測器信號強度的增加增強了感測器的抗干擾性能,保證了感測器的長期穩定性,而A/D轉換的同時完成,則降低了感測器對干擾雜訊的敏感程度。其次在感測器晶元內裝載的校準數據保證了每一隻濕度感測器都具有相同的功能,即具有100%的互換性。最後,感測器可直接通過I2C匯流排與任何類型的微處理器、微控制器系統連接,從而減少了介面電路的硬體成本,簡化了介面方式。3.1 輸出特性(1)濕度值輸出SHT11可通過I2C匯流排直接輸出數字量濕度值,其相對濕度數字輸出特性曲線如圖3所示。由圖3可看出,SHT11的輸出特性呈一定的非線性,為了補償濕度感測器的非線性,可按如下公式修正濕度值:RHlinear=c1+c2SORH+c3SORH2式中,SORH為感測器相對濕度測量值,系數取值如下:12位:SORH:c1=-4,c2=0.0405,c3=-2.8×10-68位:SORH:c1=-4,c2=0.648,c3=-7.2×10-4(2)溫度值輸出由於SHT11溫度感測器的線性非常好,故可用下列公式將溫度數字輸出轉換成實際溫度值:T=d1+d2SOT當電源電壓為5V,且溫度感測器的解析度為14位時,d1=-40�d2=0.01,當溫度感測器的解析度為12位時,d1=-40�d2=0.04。(3)露點計算空氣的露點值可根據相對濕度和溫度值來得出,具體的計算公式如下:LogEW=(0.66077+7.5T/(237.3+T)+[log10(RH)-2]Dp=[(0.66077-logEW)×237.3]/(logEW-8.16077)3.2 命令與介面時序SHT11感測器共有5條用戶命令,具體命令格式見表1所列。下面介紹一下具體的命令順序及命令時序。
i2c匯流排數字式溫濕度感測器sht11及其在單片機系統的應用 來自: 免費論文網
表1 SHT11感測器命令列表命 令編 碼說 明測量溫度00011溫度測量測量濕度00101濕度測量讀寄存器狀態00111「讀」狀態寄存器寫寄存器狀態00110「寫」狀態寄存器軟啟動11110重啟晶元,清除狀態記錄器的錯誤記錄11毫秒後進入下一個命令(1)傳輸開始初始化傳輸時,應首先發出「傳輸開始」命令,該命令可在SCK為高時使DATA由高電平變為低電平,並在下一個SCK為高時將DATA升高。接下來的命令順序包含三個地址位(目前只支持「000」)和5個命令位,當DATA腳的ack位處於低電位時,表示SHT11正確收到命令。(2)連接復位順序如果與SHT11感測器的通訊中斷,下列信號順序會使串口復位:即當DATA線處於高電平時,觸發SCK 9次以上(含9次),此後應接著發一個「傳輸開始」命令。
表2 SHT11狀態寄存器類型及說明位類型說 明缺 省 7 保留0 6讀工檢限(低電壓檢查)X 5 保留0 4 保留0 3 只用於試驗,不可以使用0 2讀/寫加熱0關1讀/寫不從OTP重下載0重下載0讀/寫'1'=8位相對濕度,12位溫度解析度。'0'=12位相對濕度,14位濕度解析度012位相對濕度,14位濕度(3)溫濕度測量時序當發出了溫(濕)度測量命令後,控制器就要等到測量完成。使用8/12/14位的解析度測量分別需要大約11/55/210ms的時間。為表明測量完成,SHT11會使數據線為低,此時控制器必須重新啟動SCK,然後傳送兩位元組的測量數據與1位元組CRC校驗和。控制器必須通過使DATA為低來確認每一個位元組,所有的量均從右算,MSB列於第一位。通訊在確認CRC數據位後停止。如果沒有用CRC-8校驗和,則控制器就會在測量數據LSB後保持ack為高來停止通訊,SHT11在測量和通訊完成後會自動返回睡眠模式。需要注意的是:為使SHT11的溫升低於0.1℃�此時的工作頻率不能大於標定值的15%(如:12位精確度時,每秒最多進行3次測量)。測量溫度和濕度命令所對應的時序如圖4所示。
論文I2C匯流排數字式溫濕度感測器SHT11及其在單片機系統的應用來自
圖4
3.3 寄存器配置SHT11感測器中的一些高級功能是通過狀態寄存器來實現的,寄存器各位的類型及說明見表2所列。下面對寄存器相關位的功能說明:(1)加熱使晶元中的加熱開關接通後,感測器溫度大約增加5℃,從而使功耗增加至8mA@5V。加熱用途如下:●通過對啟動加熱器前後的溫、濕度進行比較,可以正確地區別感測器的功能;●在相對濕度較高的環境下,感測器可通過加熱來避免冷凝。(2)低電壓檢測SHT11工作時可以自行檢測VDD電壓是否低於2.45V,准確度為±0.1V。(3)下載校準系數為了節省能量並提高速度,OTP在每次測量前都要重新下載校準系數,從而使每一次測量節省8.2ms的時間。(4)測量解析度設定將測量解析度從14位(溫度)和12位(濕度)分別減到12位和8位可應用於高速或低功耗場合。
4 應用說明4.1 運行條件測量量程以外的溫度會使濕度信號暫時地偏移+3%。然後感測器會慢慢返回到校準條件。若將晶元在濕度小於5%環境下加熱24小時到90℃,晶元就會迅速恢復高相對濕度、高溫度環境的影響,但是,延長強度條件會加速晶元的老化。4.2 安裝注意事項由於大氣的相對濕度與溫度的關系比較密切,因此,測量大氣溫度時的要點是將感測器與大氣保持同一溫度,如果感測器線路板上有發熱元件,SHT11應與熱源保持良好的通風,為減少SHT11和PCB之間的熱傳導,應使銅導線最細並在其中加上窄縫,同時應避免使感測器在強光或UV下曝曬。感測器在布線時,SCK和DATA信號平行且相互接近,或信號線長於10cm時,均會產生干擾信息,此時應在兩組信號之間放置VDD或GND。
5 具體應用圖5是AT89C2051單片機與SHT11的介面電路。由於AT89C2051不具備I2C匯流排介面,故使用單片機通用I/O口線來虛擬I2C匯流排,並利用P1.0來虛擬數據線DATA,利用P1.1口線來虛擬時鍾線,並在DATA端接入一隻4.7kΩ的上拉電阻,同時,在VDD及GND端接入一隻0.1μF的去耦電容。下面給出與上述硬體電路配套的C51應用程序。#define DATA P1_1#define SCK P1_0#define ACK 1#define noACK 0#define MEASURE_TEMP 0x03 //測量溫度命令#define MEASURE_HUMI 0x05 //測量濕度命令//讀溫濕度數據char s-measure(unsigned char *p- value, un-signed char *p_checksum, unsigned char mode){unsigned char error=0;unsigned int i;s_transstart(); //傳輸開始switch(mode){caseTEMP:error+=s_write_byte(measure_temp);break;caseHUMI:error+=s_write_byte(measure_humi);break;default:break;}for(i=0;i<65535;i++) if(DATA==0) break;if (DATA) reeor+=1;*(p_value)=s_read_byte(ACK);*(p_value+1)=s_read_byte(ACK);*p_checksum=s_read_byte(noACK);return error;}//溫濕度值標度變換及溫度補償void calc_sth15(float *p_humidity,float *p_tempera-ture){const float c1=-4.0;const float c2=0.0405;const float c3=-0.0000028;const float t1=-0.01;const float t2=0.00008;float rh=×p_humidity;float t=×p_temperature;float rh_lin;float th_ture;float t_c;t_c=t×0.01-40;rh_lin=c3×rh×rh+c2×rh+c1;trh_ture=(t_c-25)×(t1+t2×rh)+rh_lin;×p_temperature=t-c;×p_humidity=rh_ture;}//從相對溫度和濕度計算露點char calc_dewpoint(float h,float t){float logex,dew_point;logex=0.66077+7.5×t/(237.3+t)+[log10(h)-2];dew_point=(logex-0.66077)×237.3/(0.66077+7.5-logex);return dew_point;}限於篇幅,上述程序中未給出傳輸開始、寫位元組數據、讀位元組數據函數。
『伍』 誰能發張溫濕度感測器sht11和單片機連接原理圖,現成的也可以。謝謝
原理圖很簡單 就是把sht11的數據口和時鍾口就到單片機的兩個埠,關鍵是編程啊,下面一段是我之前寫的一段關於sht11的程序,希望能幫到你,有問題交流下的
#include <reg52.h> //頭文件
#include <intrins.h>
#include <stdio.h> //
#include <math.h> //Keil library
//**************************************
#define uchar unsigned char //定義一下方便使用
#define uint unsigned int //定義一下方便使用
#define ulong unsigned long //定義一下方便使用
#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 ;//全局應答變數
unsigned int xian_t=0;//溫度顯值
unsigned int xian_h=0;//濕度顯值
uchar set_h,set_l;
bit setbz_h,setbz_l,setkey;
sbit DATA =P2^6;//數據
sbit SCK=P2^7;//時鍾
sbit hot =P2^0;// 加熱
sbit motor =P2^1;// 電機
sbit speek =P2^2;// 聲音
sbit set =P0^0;// 設置
sbit setup =P0^1;// 設置+
sbit setdown =P0^2;// 設置-
sbit gwei =P3^4;//個位
sbit swei =P3^3;//十位
sbit bwei =P3^2;//百位
sbit qwei =P3^1;//千位
unsigned char code dispcode[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};//共陽
//*******************************基本驅動程
/////////////////
//////////////////////
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_sht11(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_sht11(); //啟動
}
////////////////////////////////
//測量溫度或者是溫度,返回校驗值
text_a(unsigned char ml)
{
unsigned int i;
start_sht11(); //啟動
write(ml);//寫入測溫度
if (ack==1)
{
sht_rest() ;//復位
write(ml);//寫入測溫度
}
//判斷是否處於忙
// DATA=1;//釋放數據匯流排
//for (i=0;i<65535;i++) if(DATA==0) break;
for (i=0;i<55535;i++){ if(DATA==0) break;else {xianshi();} }
read();//讀溫度
}
/////////溫濕度處理//////
text_jishuan_temp11()
{
error=0;
ack=0;
sht_rest() ;//復位
text_a(TEMP_ML);
text_jishuan_temp();
key();
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;
//
if (temp_zi<0)
{
temp_zi=0;
}
temp_zi=temp_zi*10;
xian_t=(int)temp_zi;//給顯示值
}
///////計算濕度//////
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;
xian_h=(int)humi_zi;
}
///////延時///////
delay(int i)
{
while(--i);
}
///////顯示處理///////
xianshi()
{
int abcd=0;
int i;
for (i=0;i<1;i++)
{
abcd=xian_h;
gwei=1;
swei=1;
bwei=1;
qwei=1;
P1=dispcode[abcd/100];
qwei=0;
delay(40);
qwei=1;
abcd=abcd%100 ;
P1=dispcode[abcd/10];
bwei=0;
delay(40);
bwei=1;
if(setbz_h^setbz_l)
{
if(setbz_h) abcd=set_h;
if(setbz_l) abcd=set_l;
P1=dispcode[abcd/10];
swei=0;
delay(40);
swei=1;
P1=dispcode[abcd%10];
gwei=0;
delay(40);
gwei=1;
}
else
{
abcd=xian_t;
P1=dispcode[abcd/100];
swei=0;
delay(40);
swei=1;
abcd=abcd%100 ;
P1=dispcode[abcd/10];
gwei=0;
delay(40);
gwei=1;
}
}
}
doing()
{
char xian_mi;
xian_mi=xian_t/10;
if((xian_mi<set_h)&(xian_t>set_l)) { motor=0;hot=0;speek=0;}
if(xian_mi>set_h) { motor=1;hot=0;speek=1;}
if(xian_mi<set_l) { motor=0;hot=1;speek=1;}
}
key()
{
if(set&setkey)
{
setkey=0;
if(setbz_l) {setbz_l=0;setbz_h=0;}
else
{ if(!setbz_h) setbz_h=1;
else {setbz_h=0;setbz_l=1;}
}
}
if(!set) setkey=1;
if(setup==0)
{
if(setbz_h==1)
{ if (set_h<=99) set_h++;}
if(setbz_l==1)
{ if ((set_l<set_h)&(set_l<=99)) set_l++;}
}
if(setdown==0)
{
if(setbz_h==1)
{ if ((set_h>set_l)&(set_h>=1)) set_h--;}
if(setbz_l==1)
{ if (set_l>=1) set_l--;}
}
}
//系統初始化///
csh()
{
P0=0XFF;
P1=1;
P2=0;
P3=0XFF;
}
/////////////////////////////////
///////////////////////
main()
{
set_h=22;//設置高溫
set_l=20;//設置低溫
csh();//系統初始化
while(1)
{
text_jishuan_temp11();//測溫濕度
//xianshi();//顯示
doing();//處理
key();//鍵處理
// xianshi();//顯示
}
}
『陸』 請問SHT11是不是目前最好的溫濕度感測器
SHT11是瑞士Sensirion公司生產的具有I2C匯流排介面的單片全校準數字式相對濕度和溫度感測器。該感測器採用獨特的CMOSens TM技術,具有數字式輸出、免調試、免標定、免外圍電路及全互換的特點。文中對感測器的性能特點、介面時序與命令進行了詳細的闡述,給出了SHT11與單片機的介面電路及相應程序。 關鍵詞:數字式;溫濕度感測器;I2C匯流排;單片機1 概述溫濕度的測量在倉儲管理、生產製造、氣象觀測、科學研究以及日常生活中被廣泛應用,傳統的模擬式濕度感測器一般都要設計信號調理電路並需要經過復雜的校準和標定過程,因此測量精度難以保證,且在線性度、重復性、互換性、一致性等方面往往不盡人意。SHT11是瑞士Sensirion公司推出的基於CMOSensTM技術的新型溫濕度感測器。該感測器將CMOS晶元技術與感測器技術結合起來,從而發揮出它們強大的優勢互補作用。
2 性能特點SHT11溫濕度感測器的主要特性如下:●將溫濕度感測器、信號放大調理、A/D轉換、I2C匯流排介面全部集成於一晶元(CMOSensTM技術);●可給出全校準相對濕度及溫度值輸出;●帶有工業標準的I2C匯流排數字輸出介面;●具有露點值計算輸出功能;●具有卓越的長期穩定性;●濕度值輸出解析度為14位,溫度值輸出解析度為12位,並可編程為12位和8位;●小體積(7.65×5.08×23.5mm),可表面貼裝;●具有可靠的CRC數據傳輸校驗功能;●片內裝載的校準系數可保證100%互換性;●電源電壓范圍為2.4~5.5V;●電流消耗,測量時為550μA,平均為28μA,休眠時為3μA。
SHT11溫濕度感測器採用SMD(LCC)表面貼片封裝形式,管腳排列如圖1所示,其引腳說明如下:(1)GND:接地端;(2)DATA:雙向串列數據線;(3)SCK:串列時鍾輸入;(4)VDD電源端:0.4~5.5V電源端;(5~8)NC:空管腳。
3 工作原理SHT11的濕度檢測運用電容式結構,並採用具有不同保護的「微型結構」檢測電極系統與聚合物覆蓋層來組成感測器晶元的電容,除保持電容式濕敏器件的原有特性外,還可抵禦來自外界的影響。由於它將溫度感測器與濕度感測器結合在一起而構成了一個單一的個體,因而測量精度較高且可精確得出露點,同時不會產生由於溫度與濕度感測器之間隨溫度梯度變化引起的誤差。CMOSensTM技術不僅將溫濕度感測器結合在一起,而且還將信號放大器、模/數轉換器、校準數據存儲器、標准I2C匯流排等電路全部集成在一個晶元內。SHT11感測器的內部結構框圖如圖2所示。SHT11的每一個感測器都是在極為精確的濕度室中校準的。SHT11感測器的校準系數預先存在OTP內存中。經校準的相對濕度和溫度感測器與一個14位的A/D轉換器相連,可將轉換後的數字溫濕度值送給二線I2C匯流排器件,從而將數字信號轉換為符合I2C匯流排協議的串列數字信號
『柒』 單片機通過溫濕度感測器sht11控制草坪噴水,程序怎麼寫啊
大致流程 ,先讀取溫濕度, 然後進入比較程序
做一個遲滯控制, 濕度低於多少啟動噴水,高於多少停止,同理,溫度也這樣處理
『捌』 求單片機程序關於溫濕度。感測器採用DHT11,按鍵四個可以設置溫濕度的上下限,顯示用lcd1602,超限報警
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
typedef unsigned char unint8; //unint8 代替undigned char 提高可移植性
typedef unsigned char unint16;
unsigned char str1[]={" "};
unsigned char str2[]={" "};
unsigned char code dis1[] = {" Xh RH: "}; //定義數組
unsigned char code dis2[] = {" DO T: "};
sbit buz=P1^0;
sbit TRH = P1^7;//溫濕度感測器DHT11數據接入
sbit LCD_RS = P1^1;
sbit LCD_RW = P1^2;
sbit LCD_EN = P1^3;
unint8 TH_data,TL_data,RH_data,RL_data,CK_data;
unint8 TH_temp,TL_temp,RH_temp,RL_temp,CK_temp;
unint8 com_data,untemp,temp;
unint8 respond;
void initcom()
{
TMOD=0x20;
TH1=0xfd;
TL1=0xfd;
TR1=1;
REN=1;
SM0=0;
SM1=1;
EA=1;
ES=1;
}
void send(unsigned char temp)
{
//send biao zi
SBUF=temp;
while(!TI);
TI=0;
}
void sendwd()
{
//send wen
uint w_d ;
w_d=TH_data+128;
SBUF=w_d;
while(!TI);
TI=0;
}
void sendsd()
{
//send shi
SBUF=RH_data;
while(!TI);
TI=0;
}
/*********************************************************************************/
void delayNOP() //延時
{
_nop_();
_nop_();
_nop_();
_nop_();
}
/*********************************************************************************/
/*********************************************************************************/
// 毫秒級延時子程序
/*********************************************************************************/
void delay_ms(unsigned int ms)
{
unsigned char i;
while(ms--)
{
for(i = 0; i< 150; i++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}
/*********************************************************************************/
/*********************************************************************************/
//5us級延時程序
/*********************************************************************************/
void delay_us()
{
unint8 i;
i--;
i--;
i--;
i--;
i--;
i--;
}
/********************************************************************************/
/********************************************************************************/
// 測試LCD忙碌狀態
//lcd_busy()為1時,忙,等待。lcd_busy()為0時,閑,可寫指令與數據。
/********************************************************************************/
bit lcd_busy()
{
bit result;
LCD_RS = 0;
LCD_RW = 1;
LCD_EN = 1;
delayNOP();
result = (bit)(P0&0x80);
LCD_EN = 0;
return(result);
}
/*******************************************************************************/
/*******************************************************************************/
// 寫入指令數據到LCD
/*******************************************************************************/
void lcd_wcmd(unsigned char cmd)
{
while(lcd_busy());
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
_nop_();
_nop_();
P0 = cmd;
delayNOP();
LCD_EN = 1;
delayNOP();
LCD_EN = 0;
}
/*****************************************************************************/
/*****************************************************************************/
//寫顯示數據到LCD
//RS=高電平,RW=低電平,E=高脈沖,D0-D7=數據。
/*****************************************************************************/
void lcd_wdata(unsigned char dat)
{
while(lcd_busy());
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
P0 = dat;
delayNOP();
LCD_EN = 1;
delayNOP();
LCD_EN = 0;
}
/****************************************************************************/
/****************************************************************************/
//LCD初始化設定
/****************************************************************************/
void lcd_init()
{
delay_ms(15);
lcd_wcmd(0x38); //16*2顯示,5*7點陣,8位數據
delay_ms(5);
lcd_wcmd(0x38);
delay_ms(5);
lcd_wcmd(0x38);
delay_ms(5);
lcd_wcmd(0x0c); //顯示開,關游標
delay_ms(5);
lcd_wcmd(0x06); //移動游標
delay_ms(5);
//lcd_wcmd(0x01); //清除LCD的顯示內容,如果屏幕過暗,可將這倆句刪除
//delay_ms(5);
}
/****************************************************************************/
/****************************************************************************/
//設定LCD顯示位置
/****************************************************************************/
void lcd_dis_pos(unsigned char pos)
{
lcd_wcmd(pos | 0x80); //數據指針=80+地址變數
}
/****************************************************************************/
/****************************************************************************/
//收發信號檢測,數據讀取
/****************************************************************************/
char receive()
{
unint8 i;
com_data=0;
for(i=0;i<=7;i++)
{
respond=2;
while((!TRH)&&respond++);
delay_us();
delay_us();
delay_us();
if(TRH)
{
temp=1;
respond=2;
while((TRH)&&respond++);
}
else
temp=0;
com_data<<=1;
com_data|=temp;
}
return(com_data);
}
/****************************************************************************/
/****************************************************************************/
//濕度讀取子程序
//溫度高8位== TL_data
//溫度低8位== TH_data
//濕度高8位== RH_data
//濕度低8位== RH_data
//校驗 8位 == CK_data
//調用的程序有 delay();, Delay_5us();,RECEIVE();
/***************************************************************************/
void read_TRH()
{
//主機拉低18ms
TRH=0;
delay_ms(18);
TRH=1;
//DATA匯流排由上拉電阻拉高 主機延時20us
delay_us();
delay_us();
delay_us();
delay_us();
//delay_us();
//delay_us();delay_us();delay_us();delay_us();
//主機設為輸入 判斷從機響應信號
TRH=1;
//判斷DHT11是否有低電平響應信號 如不響應則跳出,響應則向下運行
if(!TRH)
{
respond=2;
//判斷DHT11發出 80us 的低電平響應信號是否結束
while((!TRH)&& respond++);
respond=2;
//判斷從機是否發出 80us 的高電平,如發出則進入數據接收狀態
while(TRH && respond++);
//數據接收狀態
RH_temp = receive();
RL_temp = receive();
TH_temp = receive();
TL_temp = receive();
CK_temp = receive();
TRH=1;
//數據校驗
untemp=(RH_temp+RL_temp+TH_temp+TL_temp);
if(untemp==CK_temp)
{
RH_data = RH_temp;
RL_data = RL_temp;
TH_data = TH_temp;
TL_data = TL_temp;
CK_data = CK_temp;
}
}
//濕度整數部分
str1[0] = (char)(0X30+RH_data/10);
str1[1] = (char)(0X30+RH_data%10);
str1[2] = 0x2e; //小數點
//濕度小數部分
str1[3] = (char)(0X30+RL_data/10);
str1[5] = 0X25; //"%"
str1[6] = 0X52; //"R"
str1[7] = 0X48; //"H"
//溫度整數部分
str2[0] = (char)(0X30+TH_data/10);
str2[1] = (char)(0X30+TH_data%10);
str2[2] = 0x2e; //小數點
//溫度小數部分
str2[3] = (char)(0X30+TL_data/10);
str2[5] = 0X27; //"'"
str2[6] = 0X43; //"C"
}
/****************************************************************************/
//冬天適宜溫濕度 夏天適宜溫濕度
//濕度:30%--80% 30%--60%
//溫度:18℃--25℃ 23℃--28℃
/****************************************************************************/
void baoj()//報警函數
{
if(RH_data>=80) //濕度上限80%
{
buz=0;
delay_ms(200);
buz=1;
delay_ms(10);
}
else if(RH_data<=30) //濕度下限30%
{
buz=0;
delay_ms(200);
buz=1;
delay_ms(10);
}
else if(TH_data>=25) //溫度上限25℃
{
buz=0;
delay_ms(200);
buz=1;
delay_ms(10);
}
else if(TH_data<=18) //溫度下限18℃
{
buz=0;
delay_ms(200);
buz=1;
delay_ms(10);
}
else
{
buz=1;
}
}
/****************************************************************************/
//主函數
//TH,TL,RH,RL分別代表溫濕度的整數和小數部分
/****************************************************************************/
void main()
{
lcd_init();
initcom();
delay_us();
while(1)
{
unsigned char i,n=0x40,m;
read_TRH();
//寫字元
for(i=0;i<=7;i++)
{
lcd_dis_pos(i); //顯示字元
lcd_wdata(dis1[i]);
lcd_dis_pos(n+i); //顯示字元
lcd_wdata(dis2[i]);
}
//寫濕度數據
m=0x08;
for(i=0;i<=7;i++)
{
lcd_dis_pos(m);
lcd_wdata(str1[i]);
m++;
}
//寫溫度數據
m=0x48;
for(i=0;i<=7;i++)
{
lcd_dis_pos(m);
lcd_wdata(str2[i]);
m++;
}
//延時
delay_ms(500);
baoj();//報警
send(0xff);//wsd flags
//delay_ms(10);
sendwd();
//delay_ms(10);
sendsd();
//delay_ms(10);
}
}
『玖』 利用單片機開發板和sht11溫濕度感測器連接怎麼提取溫濕度感測器的數據到開發板
這個程序網上非常多,也非常成熟,就是按順序來就行,上網找一下就O啦