标题:
SHT10温湿度传感器应用,含单片机源码
[打印本页]
作者:
dengzhen11
时间:
2018-5-5 12:25
标题:
SHT10温湿度传感器应用,含单片机源码
早几年用了SHT10的温湿度传感器,稳定,可靠,就是更新数据时间比较长些,
电路很简单,请看手册,
已经在产品中使用了,请放心使用和指正,
#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;
/*********************************************************************************************************/
/**********************************************************************************************************
** 函数名称: s_write_byte()
** 函数功能: SHT10写单个字节, 写一个字节并输出ACK验证
** 入口参数: 写入单个字节
** 出口参数: 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
}
/**********************************************************************************************************
** 函数名称: s_read_byte()
** 函数功能: SHT10读单个字节,
** 入口参数: ACK验证
** 出口参数: 读单个字节
** 说 明: reads a byte form the Sensibus and gives an acknowledge in case of "ack=1" 读字节并给一个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;
}
/**********************************************************************************************************
** 函数名称: s_transstart()
** 函数功能: 启动传输
** 入口参数: 无
** 出口参数: 无
** 说 明: 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;
}
/**********************************************************************************************************
** 函数名称: s_connectionreset()
** 函数功能: 复位SHT10 //复位通讯时序
** 入口参数: 无
** 出口参数: 无
** 说 明: reads a byte form the Sensibus and gives an acknowledge in case of "ack=1" 读字节并给一个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
}
/**********************************************************************************************************
** 函数名称: s_measure()
** 函数功能: SHT10测量温度 或者湿度 ,带校验
** 入口参数: 读出温湿度值存入地址,校验值存入地址,测量模式
** 出口参数: 测量出错次数
** 说 明: makes a measurement (humidity/temperature) with checksum 产生算法
*********************************************************************************************************/
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;
}
/**********************************************************************************************************
** 函数名称: s_write_byte_1()
** 函数功能: SHT10写单个字节, 写一个字节并输出ACK验证
** 入口参数: 写入单个字节
** 出口参数: 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
}
/**********************************************************************************************************
** 函数名称: s_read_byte_1()
** 函数功能: SHT10读单个字节,
** 入口参数: ACK验证
** 出口参数: 读单个字节
** 说 明: reads a byte form the Sensibus and gives an acknowledge in case of "ack=1" 读字节并给一个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;
}
/**********************************************************************************************************
** 函数名称: s_transstart_1()
** 函数功能: 启动传输
** 入口参数: 无
** 出口参数: 无
** 说 明: 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;
}
/**********************************************************************************************************
** 函数名称: s_connectionreset_1()
** 函数功能: 复位SHT10 ,复位通讯时序
** 入口参数: 无
** 出口参数: 无
** 说 明: reads a byte form the Sensibus and gives an acknowledge in case of "ack=1" 读字节并给一个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
}
/**********************************************************************************************************
** 函数名称: s_measure_1()
** 函数功能: SHT10测量温度 或者湿度 ,带校验
** 入口参数: 读出温湿度值存入地址,校验值存入地址,测量模式
** 出口参数: 测量出错次数
** 说 明: makes a measurement (humidity/temperature) with checksum 产生算法
*********************************************************************************************************/
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;
}
/**********************************************************************************************************
** 函数名称: calc_sht10()
** 函数功能: 计算温度和湿度
** 入口参数: 读出湿度值存入地址,读出温度值存入地址
** 出口参数: 无
** 说 明: 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;
} */
/**********************************************************************************************************
** 函数名称: calc_sht10()
** 函数功能: 计算温度和湿度
** 入口参数: 读出湿度值存入地址,读出温度值存入地址
** 出口参数: 无
** 说 明: 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]
}
/**********************************************************************************************************
** 函数名称: calc_dewpoint()
** 函数功能: 计算露点
** 入口参数: humidity [%RH], temperature [°C]
** 出口参数: 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;
}
/**********************************************************************************************************
** 函数名称: Temp_Humi_Check()
** 函数功能: 温度湿度检测
** 入口参数: 无
** 出口参数: 无
** 说 明:
*********************************************************************************************************/
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
}
}
}
/**********************************************************************************************************
** 函数名称: Temp_Humi_Init()
** 函数功能: 温度湿度检测
** 入口参数: 无
** 出口参数: 无
** 说 明: 检测到温度时 ,置 标志位
*********************************************************************************************************/
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;
}
}
复制代码
作者:
向日葵男人
时间:
2018-5-13 20:21
试试吧,看看用在stc上可以不
作者:
JHLSF
时间:
2022-1-19 13:03
向日葵男人 发表于 2018-5-13 20:21
试试吧,看看用在stc上可以不
STC89C52 OK
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1