標(biāo)題:
SHT10溫濕度傳感器應(yīng)用,含單片機源碼
[打印本頁]
作者:
dengzhen11
時間:
2018-5-5 12:25
標(biāo)題:
SHT10溫濕度傳感器應(yīng)用,含單片機源碼
早幾年用了SHT10的溫濕度傳感器,穩(wěn)定,可靠,就是更新數(shù)據(jù)時間比較長些,
電路很簡單,請看手冊,
已經(jīng)在產(chǎn)品中使用了,請放心使用和指正,
#include <iom64v.h>
#include <macros.h>
#include <math.h>
/*********************************************************************************************************/
#include "sht.h"
#include "uart.h"
#include "key.h"
#include "IO.h"
#include "Lcd.h"
/*********************************************************************************************************/
enum {TEMP,HUMI};
/*********************************************************************************************************/
//0: 溫度1, 1:濕度1 , 2 : 溫度2, 3: 濕度2
float todao[4]; //{temp,rh}; 模擬量寄存器從1到2
float humi_val1; //濕度變量
float temp_val1; //溫度變量
unsigned int humi_val; //濕度變量
unsigned int temp_val; //溫度變量
unsigned char checksum;
/*
const float C1=-4; // for 12 Bit RH
const float C2=+0.0405; // for 12 Bit RH
const float C3=-0.0000028; // for 12 Bit RH
const float T1=+0.01; // for 12 Bit RH
const float T2=+0.00008; // for 12 Bit RH
*/
const float C1=-2.0468; // for 12 Bit RH
const float C2=+0.0367; // for 12 Bit RH
const float C3=-0.0000015955; // for 12 Bit RH
const float T1=+0.01; // for 12 Bit RH
const float T2=+0.00008; // for 12 Bit RH
/*********************************************************************************************************/
extern unsigned char wendu1_biaozhi;
extern unsigned char wendu2_biaozhi;
extern unsigned char R_KeyValue1;
/*********************************************************************************************************/
/**********************************************************************************************************
** 函數(shù)名稱: s_write_byte()
** 函數(shù)功能: SHT10寫單個字節(jié), 寫一個字節(jié)并輸出ACK驗證
** 入口參數(shù): 寫入單個字節(jié)
** 出口參數(shù): ACK驗證
** 說 明: writes a byte on the Sensibus and checks the acknowledge
*********************************************************************************************************/
unsigned char s_write_byte(unsigned char value)
{
unsigned char i,j,error1=0;
SHT10_SDA1_OUT;
for(i=0x80;i>0;i/=2) //shift bit for masking
{
if (i & value)
SHT10_SDA1_OUT1; //masking value with i , write to SENSI-BUS
else
SHT10_SDA1_OUT0;
SHT10_SCK1_OUT1; //clk for SENSI-BUS
for(j = 0; j<40;j++)
{
NOP(); //pulswith approx. 5 us
}
SHT10_SCK1_OUT0;
}
NOP();
NOP();
NOP();
SHT10_SDA1_OUT1; //release DATA-line
NOP();
SHT10_SCK1_OUT1; //clk #9 for ack
NOP();
SHT10_SDA1_IN;
NOP();
if(SHT10_SDA1) //check ack (DATA will be pulled down by SHT11)
{
error1 = 1;
}
else
{
error1 = 0;
}
SHT10_SCK1_OUT0;
return error1; //error=1 in case of no acknowledge
}
/**********************************************************************************************************
** 函數(shù)名稱: s_read_byte()
** 函數(shù)功能: SHT10讀單個字節(jié),
** 入口參數(shù): ACK驗證
** 出口參數(shù): 讀單個字節(jié)
** 說 明: reads a byte form the Sensibus and gives an acknowledge in case of "ack=1" 讀字節(jié)并給一個ACK
*********************************************************************************************************/
unsigned char s_read_byte(unsigned char ack)
{
unsigned char i,j,val=0;
SHT10_SDA1_OUT;
NOP();
SHT10_SDA1_OUT1; //release DATA-line
for(i=0x80;i>0;i/=2) //shift bit for masking
{
SHT10_SCK1_OUT1; //clk for SENSI-BUS
NOP();
NOP();
SHT10_SDA1_IN;
NOP();
if(SHT10_SDA1)
val = (val | i); //read bit
SHT10_SCK1_OUT0;
}
SHT10_SDA1_OUT;
NOP();
NOP();
if(!ack)
SHT10_SDA1_OUT1; //in case of "ack==1" pull down DATA-Line
else
SHT10_SDA1_OUT0;
SHT10_SCK1_OUT1; //clk #9 for ack
for(j = 0; j<40;j++)
{
NOP(); //pulswith approx. 5 us
}
SHT10_SCK1_OUT0;
NOP();
NOP();
SHT10_SDA1_OUT1; //release DATA-line
return val;
}
/**********************************************************************************************************
** 函數(shù)名稱: s_transstart()
** 函數(shù)功能: 啟動傳輸
** 入口參數(shù): 無
** 出口參數(shù): 無
** 說 明: generates a transmission start //啟動傳輸
// _____ ________
// DATA: |_______|
// ___ ___
// SCK : ___| |___| |______
*********************************************************************************************************/
void s_transstart(void)
{
SHT10_SDA1_OUT;
NOP();
NOP();
SHT10_SDA1_OUT1;
NOP();
SHT10_SCK1_OUT0; //Initial state
NOP();
NOP();
SHT10_SCK1_OUT1;
NOP();
SHT10_SDA1_OUT0;
NOP();
SHT10_SCK1_OUT0;
NOP();
NOP();
NOP();
SHT10_SCK1_OUT1;
NOP();
SHT10_SDA1_OUT1;
NOP();
SHT10_SCK1_OUT0;
}
/**********************************************************************************************************
** 函數(shù)名稱: s_connectionreset()
** 函數(shù)功能: 復(fù)位SHT10 //復(fù)位通訊時序
** 入口參數(shù): 無
** 出口參數(shù): 無
** 說 明: reads a byte form the Sensibus and gives an acknowledge in case of "ack=1" 讀字節(jié)并給一個ACK
//----------------------------------------------------------------------------------
// communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
// _____________________________________________________ ________
// DATA: |_______|
// _ _ _ _ _ _ _ _ _ ___ ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______
*********************************************************************************************************/
void s_connectionreset(void)
{
unsigned char i;
SHT10_SDA1_OUT;
NOP();
NOP();
SHT10_SDA1_OUT1;
NOP();
NOP();
SHT10_SCK1_OUT0; //Initial state
NOP();
NOP();
for(i=0;i<9;i++) //9 SCK cycles
{
SHT10_SCK1_OUT1;
NOP();
NOP();
SHT10_SCK1_OUT0
NOP();
NOP();
}
s_transstart(); //transmission start
}
/**********************************************************************************************************
** 函數(shù)名稱: s_measure()
** 函數(shù)功能: SHT10測量溫度 或者濕度 ,帶校驗
** 入口參數(shù): 讀出溫濕度值存入地址,校驗值存入地址,測量模式
** 出口參數(shù): 測量出錯次數(shù)
** 說 明: makes a measurement (humidity/temperature) with checksum 產(chǎn)生算法
*********************************************************************************************************/
unsigned char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)
{
unsigned char error1=0;
unsigned long i;
s_transstart(); //transmission start
switch(mode)
{ //send command to sensor
case TEMP : error1+=s_write_byte(MEASURE_TEMP); break;
case HUMI : error1+=s_write_byte(MEASURE_HUMI); break;
default : break;
}
SHT10_SDA1_IN;
NOP();
NOP();
//delay_nms(150);
for(i=0;i<90000;i++)
{
if(SHT10_SDA1 == 0) //wait until sensor has finished the measurement
break;
}
if(SHT10_SDA1)
error1 += 1; // or timeout (~2 sec.) is reached
*(p_value+1 ) =s_read_byte(ACK); // read the first byte (MSB)
*(p_value)=s_read_byte(ACK); // read the second byte (LSB)
*p_checksum =s_read_byte(noACK); // read checksum
return error1;
}
/**********************************************************************************************************
** 函數(shù)名稱: s_write_byte_1()
** 函數(shù)功能: SHT10寫單個字節(jié), 寫一個字節(jié)并輸出ACK驗證
** 入口參數(shù): 寫入單個字節(jié)
** 出口參數(shù): ACK驗證
** 說 明: writes a byte on the Sensibus and checks the acknowledge
*********************************************************************************************************/
unsigned char s_write_byte_1(unsigned char value)
{
unsigned char i,error1=0;
SHT10_SDA2_OUT;
for(i=0x80;i>0;i/=2) //shift bit for masking
{
if (i & value)
SHT10_SDA2_OUT1; //masking value with i , write to SENSI-BUS
else
SHT10_SDA2_OUT0;
SHT10_SCK2_OUT1; //clk for SENSI-BUS
NOP();
NOP();
NOP(); //pulswith approx. 5 us
SHT10_SCK2_OUT0;
}
SHT10_SDA2_OUT1; //release DATA_1-line
NOP();
NOP();
SHT10_SCK2_OUT1; //clk #9 for ack
NOP();
NOP();
SHT10_SDA2_IN;
NOP();
NOP();
if(SHT10_SDA2) //check ack (DATA_1 will be pulled down by SHT11)
{
error1 = 1;
}
else
{
error1 = 0;
}
SHT10_SCK2_OUT0;
return error1; //error=1 in case of no acknowledge
}
/**********************************************************************************************************
** 函數(shù)名稱: s_read_byte_1()
** 函數(shù)功能: SHT10讀單個字節(jié),
** 入口參數(shù): ACK驗證
** 出口參數(shù): 讀單個字節(jié)
** 說 明: reads a byte form the Sensibus and gives an acknowledge in case of "ack=1" 讀字節(jié)并給一個ACK
*********************************************************************************************************/
unsigned char s_read_byte_1(unsigned char ack)
{
unsigned char i,val=0;
SHT10_SDA2_OUT;
NOP();
SHT10_SDA2_OUT1; //release DATA_1-line
for(i=0x80;i>0;i/=2) //shift bit for masking
{
SHT10_SCK2_OUT1; //clk for SENSI-BUS
NOP();
SHT10_SDA2_IN;
NOP();
NOP();
if(SHT10_SDA2)
val=(val | i); //read bit
SHT10_SCK2_OUT0;
}
SHT10_SDA2_OUT;
NOP();
NOP();
if(!ack)
SHT10_SDA2_OUT1; //in case of "ack==1" pull down DATA_1-Line
else
SHT10_SDA2_OUT0;
SHT10_SCK2_OUT1; //clk #9 for ack
NOP();
NOP();
NOP(); //pulswith approx. 5 us
SHT10_SCK2_OUT0;
NOP();
SHT10_SDA2_OUT1; //release DATA_1-line
return val;
}
/**********************************************************************************************************
** 函數(shù)名稱: s_transstart_1()
** 函數(shù)功能: 啟動傳輸
** 入口參數(shù): 無
** 出口參數(shù): 無
** 說 明: generates a transmission start //啟動傳輸
// _____ ________
// DATA: |_______|
// ___ ___
// SCK : ___| |___| |______
*********************************************************************************************************/
void s_transstart_1(void)
{
SHT10_SDA2_OUT;
SHT10_SDA2_OUT1;
NOP();
SHT10_SCK2_OUT0; //Initial state
NOP();
NOP();
SHT10_SCK2_OUT1;
NOP();
SHT10_SDA2_OUT0;
NOP();
SHT10_SCK2_OUT0;
NOP();
NOP();
NOP();
SHT10_SCK2_OUT1;
NOP();
SHT10_SDA2_OUT1;
NOP();
SHT10_SCK2_OUT0;
}
/**********************************************************************************************************
** 函數(shù)名稱: s_connectionreset_1()
** 函數(shù)功能: 復(fù)位SHT10 ,復(fù)位通訊時序
** 入口參數(shù): 無
** 出口參數(shù): 無
** 說 明: reads a byte form the Sensibus and gives an acknowledge in case of "ack=1" 讀字節(jié)并給一個ACK
//----------------------------------------------------------------------------------
// communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
// _____________________________________________________ ________
// DATA: |_______|
// _ _ _ _ _ _ _ _ _ ___ ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______
*********************************************************************************************************/
void s_connectionreset_1(void)
{
unsigned char i;
SHT10_SDA2_OUT;
NOP();
NOP();
SHT10_SDA2_OUT1;
NOP();
NOP();
SHT10_SCK2_OUT0; //Initial state
NOP();
NOP();
for(i=0;i<9;i++) //9 SCK cycles
{
SHT10_SCK2_OUT1;
NOP();
SHT10_SCK2_OUT0;
NOP();
}
s_transstart_1(); //transmission start
}
/**********************************************************************************************************
** 函數(shù)名稱: s_measure_1()
** 函數(shù)功能: SHT10測量溫度 或者濕度 ,帶校驗
** 入口參數(shù): 讀出溫濕度值存入地址,校驗值存入地址,測量模式
** 出口參數(shù): 測量出錯次數(shù)
** 說 明: makes a measurement (humidity/temperature) with checksum 產(chǎn)生算法
*********************************************************************************************************/
unsigned char s_measure_1(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)
{
unsigned char error1=0;
unsigned long i;
s_transstart_1(); //transmission start
switch(mode)
{ //send command to sensor
case TEMP : error1+=s_write_byte_1(MEASURE_TEMP); break;
case HUMI : error1+=s_write_byte_1(MEASURE_HUMI); break;
default : break;
}
SHT10_SDA2_IN;
NOP();
NOP();
//delay_nms(150);
for (i=0;i<90000;i++)
{
if(SHT10_SDA2==0)
break; //wait until sensor has finished the measurement
}
if(SHT10_SDA2)
error1 += 1; // or timeout (~2 sec.) is reached
*(p_value+1) =s_read_byte_1(ACK); //read the first byte (MSB)
*(p_value)=s_read_byte_1(ACK); //read the second byte (LSB)
*p_checksum =s_read_byte_1(noACK); //read checksum
return error1;
}
/**********************************************************************************************************
** 函數(shù)名稱: calc_sht10()
** 函數(shù)功能: 計算溫度和濕度
** 入口參數(shù): 讀出濕度值存入地址,讀出溫度值存入地址
** 出口參數(shù): 無
** 說 明: See an application note Non-linearity Compensation from www.Sensirion.com for details
***********************************************************************************************************/
//----------------------------------------------------------------------------------------
// calculates temperature [Deg Cel] and humidity [%RH]
// input : humi [Ticks] (12 bit)
// temp [Ticks] (14 bit)
// output: humi [10x %RH] for 1 decimal place
// temp [100x Deg Cel] for 2 decimal places
/*********************************************************************************************************/
/*
void calc_sht10( float *p_humidity ,float *p_temperature)
{
float rh = *p_humidity;
float t = *p_temperature;
float t_C;
float rh_lin;
t_C=t*0.01-40.1;
//multiplied by 100, t_C=t-4000
//t_C = t - 4000;
//58<=rh<=1720, (1430*rh-5120*16)/4096, in x10
//1721<=rh<=3273, (1110*rh+28930*16)/4096, in x10
//From : Application Note Non-Linearity compensation, Sensirion
if(rh<=1720)
{
rh_lin = (1430UL*(long)rh)>>12;
(rh_lin>=20)?(rh_lin = rh_lin-20):(rh_lin=0);
}
else
{
//rh_lin = (1110*rh + 12320 + 4096*110)/4096, in x10
rh_lin = ((1110UL*(long)rh + 12320UL) >> 12) + 110;
if(rh_lin>1000)
rh_lin=1000;
}
//rh_true = (t_C-25)*(rh*0.00008+0.01)+rh_lin
//~0.12 %RH /deg C, this factor has been ignored at this moment
*p_temperature = t_C;
*p_humidity = rh_lin;
} */
/**********************************************************************************************************
** 函數(shù)名稱: calc_sht10()
** 函數(shù)功能: 計算溫度和濕度
** 入口參數(shù): 讀出濕度值存入地址,讀出溫度值存入地址
** 出口參數(shù): 無
** 說 明: See an application note Non-linearity Compensation from www.Sensirion.com for details
***********************************************************************************************************/
void calc_sht10(float *p_humidity ,float *p_temperature)
{
float rh=*p_humidity; // rh: Humidity [Ticks] 12 Bit
float t=*p_temperature; // t: Temperature [Ticks] 14 Bit
float rh_lin; // rh_lin: Humidity linear
float rh_true; // rh_true: Temperature compensated humidity
float t_C; // t_C : Temperature [°C]
t_C=t*0.01 - 40.1; // calc. temperature[°C]from 14 bit temp.ticks @5V
rh_lin=C3*rh*rh + C2*rh + C1; // calc. humidity from ticks to [%RH]
rh_true=(t_C-25)*(T1+T2*rh)+rh_lin; // calc. temperature compensated humidity[%RH]
if(rh_true>100)rh_true=100; // cut if the value is outside of
if(rh_true<0.1)rh_true=0.1; // the physical possible range
*p_temperature=t_C; // return temperature [°C]
*p_humidity=rh_true; // return humidity[%RH]
}
/**********************************************************************************************************
** 函數(shù)名稱: calc_dewpoint()
** 函數(shù)功能: 計算露點
** 入口參數(shù): humidity [%RH], temperature [°C]
** 出口參數(shù): dew point [°C]
** 說 明: See an application note Non-linearity Compensation from www.Sensirion.com for details
***********************************************************************************************************/
float calc_dewpoint(float h,float t)
{
float k,dew_point ;
k = (log10(h)-2)/0.4343 + (17.62*t)/(243.12+t);
dew_point = 243.12*k/(17.62-k);
return dew_point;
}
/**********************************************************************************************************
** 函數(shù)名稱: Temp_Humi_Check()
** 函數(shù)功能: 溫度濕度檢測
** 入口參數(shù): 無
** 出口參數(shù): 無
** 說 明:
*********************************************************************************************************/
void Temp_Humi_Check(void)
{
unsigned char error=0;
if(wendu1_biaozhi==1)
{
error=0;
s_connectionreset(); //傳送重置
error += s_measure((unsigned char*) &humi_val,&checksum,HUMI); //measure humidity 濕度測量
error += s_measure((unsigned char*) &temp_val,&checksum,TEMP); //measure temperature 溫度測量
if(error!=0)
{
s_connectionreset(); //in case of an error: connection reset
todao[0]=0; //濕度測量 1
todao[1]=0; //溫度測量 1
}
else
{
humi_val1=(float)humi_val; //converts integer to float
temp_val1=(float)temp_val; //converts integer to float
calc_sht10(&humi_val1,&temp_val1); //calculate humidity, temperature
//calc_dewpoint(humi_val1,temp_val1);
todao[0]=temp_val1; //溫度測量 1
todao[1]=humi_val1; //濕度測量 1
}
}
if(wendu2_biaozhi==1)
{
error=0;
s_connectionreset_1(); ////傳送重置
error+=s_measure_1((unsigned char*) &humi_val,&checksum,HUMI); //measure humidity 濕度測量
error+=s_measure_1((unsigned char*) &temp_val,&checksum,TEMP); //measure temperature 溫度測量
if(error!=0)
{
s_connectionreset_1(); //in case of an error: connection reset
todao[2]=0; //濕度測量 2
todao[3]=0; //溫度測量 2
return;
}
else
{
humi_val1=(float)humi_val; //converts integer to float
temp_val1=(float)temp_val; //converts integer to float
calc_sht10(&humi_val1,&temp_val1); //calculate humidity, temperature
//calc_dewpoint(humi_val1,temp_val1);
todao[2]=temp_val1; //溫度測量 2
todao[3]=humi_val1; //濕度測量 2
}
}
}
/**********************************************************************************************************
** 函數(shù)名稱: Temp_Humi_Init()
** 函數(shù)功能: 溫度濕度檢測
** 入口參數(shù): 無
** 出口參數(shù): 無
** 說 明: 檢測到溫度時 ,置 標(biāo)志位
*********************************************************************************************************/
void Temp_Humi_Init(void)
{
unsigned char error=0;
//float Dew_Point;
s_connectionreset(); //傳送重置
error+=s_measure((unsigned char*) &humi_val,&checksum,HUMI); //measure humidity 濕度測量
error+=s_measure((unsigned char*) &temp_val,&checksum,TEMP); //measure temperature 溫度測量
if(error!=0)
{
s_connectionreset(); //in case of an error: connection reset
todao[0]=0; //濕度測量 1
todao[1]=0; //溫度測量 1
}
else
{
humi_val1=(float)humi_val; //converts integer to float
temp_val1=(float)temp_val; //converts integer to float
calc_sht10(&humi_val1,&temp_val1); //calculate humidity, temperature
//Dew_Point=calc_dewpoint(humi_val1,temp_val1);
todao[0]=temp_val1; //濕度測量 1
todao[1]=humi_val1; //溫度測量 1
}
error=0;
s_connectionreset_1(); //傳送重置
error+=s_measure_1((unsigned char*) &humi_val,&checksum,HUMI); //measure humidity 濕度測量
error+=s_measure_1((unsigned char*) &temp_val,&checksum,TEMP); //measure temperature 溫度測量
if(error!=0)
{
s_connectionreset_1(); //in case of an error: connection reset
todao[2]=0; //溫度測量 2
todao[3]=0; //濕度測量 2
}
else
{
humi_val1=(float)humi_val; //converts integer to float
temp_val1=(float)temp_val; //converts integer to float
calc_sht10(&humi_val1,&temp_val1); //calculate humidity, temperature
//Dew_Point=calc_dewpoint(humi_val1,temp_val1);
todao[2] = temp_val1; //溫度測量 2
todao[3] = humi_val1; //濕度測量 2
}
if(todao[1]==0)
{
if( todao[0]==0)
{
wendu1_biaozhi = 0;
}
}
else // 有濕度時一定有溫度
{
wendu1_biaozhi = 1;
}
if(todao[3]==0)
{
if( todao[2]==0)
{
wendu2_biaozhi = 0;
}
} // 有濕度時一定有溫度?
else
{
wendu2_biaozhi = 1;
}
}
復(fù)制代碼
作者:
向日葵男人
時間:
2018-5-13 20:21
試試吧,看看用在stc上可以不
作者:
JHLSF
時間:
2022-1-19 13:03
向日葵男人 發(fā)表于 2018-5-13 20:21
試試吧,看看用在stc上可以不
STC89C52 OK
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1