/*******************************************************************
*【文 件 名】:SHT11.h *
*【建立日期】:7月5日 *
*【修改日期】:7月5日 *
*【文件作用】:温湿度传感器SHT11的驱动程序,提供了外界调用接口函数 *
*【说 明】: *
*------------------------------------------------------------------*
*【作 者】:郭鑫(ben) *
*【版 权】:国家创新性实验项目,编号GCS07001 *
*******************************************************************/
#ifndef _SHT11_08_07_5_
#define _SHT11 _08_07_5_
/***************************头文件部分*****************************/
#include
#define ACK 1
#define noACK 0
#define measure_temp 0x03 //测量温度命令
#define measure_humi 0x05 //测量湿度命令
#define RESET 0x1e //软启动
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
//-------------------------管脚定义--------------------------------
sbit DATA=P1^0;
sbit SCK=P1^1;
//------------------------数据结构体定义---------------------------
typedef union //保存所测得的温度&湿度值
{ uint i;
float f;
} value;
typedef struct __WENSHIDU__
{
uchar gewei;
uchar shiwei;
uchar DateString1[5];
uchar DateString2[6];
}WENSHIDU;
/***************************函数声明*******************************/
char write_byte(unsigned char value); // write a byte and checks the ack signal
char read_byte(unsigned char ack); //read a byte and checks the ack signal
void transstart(void);
void connectionreset(void);
char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode);
void calc_sth11(float *p_humidity ,float *p_temperature);
void DateToStr(WENSHIDU *Time,float datax,float datax1);
void call_sht11(void);
void sht11_window(void); //温湿度界面显示
//--------- write a byte and checks the ack signal-----------------
char write_byte(uchar value)
{
uchar i,error=0;
for (i=0x80;i>0;i/=2) /*连续向右移动8位*/
{
if (i & value) DATA=1; /*把相应的位送数据线*/
else DATA=0;
SCK=1; /*时序脉冲,应严格按着此标准*/
_nop_();
_nop_();
_nop_(); /*大约0.5us*/
SCK=0;
}
DATA=1; /*释放数据线*/
SCK=1; /*第9位作为响应位*/
error=DATA; /*检测响应情况,如果有响应数据线就会被SHT10拉低*/
SCK=0;
return error; /*返回1表示没响应*/
}
//--------- read a byte and checks the ack signal-----------------
char read_byte(uchar ack)
{
uchar i,val=0;
DATA=1; /*释放数据线*/
for (i=0x80;i>0;i/=2) /*连续向右移动8位*/
{
SCK=1; /*clk for SENSI-BUS*/
if (DATA) val=(val | i); /*read bit */
SCK=0;
}
DATA=!ack; /*当ack=1时拉低数据线*/
SCK=1; /*clk #9 for ack*/
_nop_();_nop_();_nop_(); /*pulswith approx. 5 us */
SCK=0;
DATA=1; /*释放数据线*/
return val;
}
/*******************************************************************
*【函 数 名】:transstart *
*【修改日期】:2008年7月5日 *
*【函数作用】:传输控制,发出传输开始命令 *
*------------------------------------------------------------------*
*【备 注】: *
*******************************************************************/
void transstart(void)
{
DATA=1;
SCK=0; //初始状态
_nop_();
SCK=1;
_nop_();
DATA=0;
_nop_();
SCK=0;
_nop_();_nop_();_nop_();
SCK=1;
_nop_();
DATA=1;
_nop_();
SCK=0;
}
/*******************************************************************
*【函 数 名】:connectionreset *
*【修改日期】:2008年7月5日 *
*【函数作用】:复位:当DATA线处于高低平时,触发SCK9次以上(含9次) *
* 此后应接发一个"传输开始"命令 *
*------------------------------------------------------------------*
*【备 注】: *
*******************************************************************/
void connectionreset(void)
{
unsigned char i;
DATA=1; SCK=0; //Initial state
for(i=0;i<9;i++) //9 SCK cycles
{
SCK=1;
SCK=0;
}
transstart(); //transmission start
}
//-------makes a measurement (humidity/temperature) with checksum-----
char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)
{
unsigned error=0;
uint i;
transstart(); //transmission start
switch(mode){ //send command to sensor*/
case 0 : error+=write_byte(measure_temp); break;
case 1 : error+=write_byte(measure_humi); break;
default : break;
}
for (i=0;i<65535;i++) if(DATA==0) break; //wait until sensor has finished the measurement
if(DATA) error+=1; //or timeout (~2 sec.) is reached
*(p_value) =read_byte(ACK); //read the first byte (MSB)
*(p_value+1)=read_byte(ACK); //read the second byte (LSB)
*p_checksum =read_byte(noACK); //read checksum
return error;
}
//---------------温湿度值标度变换及温度补偿-------
void calc_sth11(float *p_humidity ,float *p_temperature)
{
const float C1=-4.0; //for 12 Bit
const float C2=+0.0405; //for 12 Bit
const float C3=-0.0000028; //for 12 Bit
const float T1=+0.01; //for 14 Bit @ 5V
const float T2=+0.00008; //for 14 Bit @ 5V
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 [癈]
t_C=t*0.01 - 40; //calc. temperature from ticks to [癈]
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 [癈]
*p_humidity=rh_true; //return humidity[%RH]
}
/*******************************************************************
*【函 数 名】:DateToStr *
*【修改日期】:2008年7月5日 *
*【函数作用】:数值转换,供显示使用 *
*------------------------------------------------------------------*
*【备 注】: *
*******************************************************************/
void DateToStr(WENSHIDU *Time,float datax,float datax1)
{
uint i;
i=(int)datax;
Time->shiwei=i/10;
Time->gewei =i%10;
Time->DateString1[0] = Time->shiwei + '0';
Time->DateString1[1] = Time->gewei + '0';
i=(int)((datax-i)*10);
Time->DateString1[2] ='.';
Time->DateString1[3] = i + '0';
Time->DateString1[4] = '\0';
i=(int)datax1;
Time->shiwei=i/10;
Time->gewei =i%10;
Time->DateString2[0] = Time->shiwei + '0';
Time->DateString2[1] = Time->gewei + '0';
i=(int)((datax1-i)*10);
Time->DateString2[2] ='.';
Time->DateString2[3] = i + '0';
Time->DateString2[4] = '%';
Time->DateString2[5] = '\0';
}
/*******************************************************************
*【函 数 名】:call_sht11 *
*【修改日期】:2008年7月5日 *
*【函数作用】:sht11驱动调用,调用即可完成一次测量 *
*------------------------------------------------------------------*
*【备 注】: *
*******************************************************************/
void call_sht11(void)
{
WENSHIDU S;
value humi_val,temp_val;
unsigned char error,checksum;
unsigned int i;
error=0;
error+=s_measure((unsigned char*) &humi_val.i,&checksum,1); /*measure humidity*/
error+=s_measure((unsigned char*) &temp_val.i,&checksum,0); /*measure temperature*/
if(error!=0)
connectionreset(); /*in case of an error:connection reset*/
else
{
humi_val.f=(float)humi_val.i; /*converts integer to float*/
temp_val.f=(float)temp_val.i; /*converts integer to float*/
calc_sth11(&humi_val.f,&temp_val.f); /*calculate humidity,temperature*/
DateToStr(&S,temp_val.f,humi_val.f);
lcd_setposition(2,5);
lcd_str_w(S.DateString1);
lcd_setposition(3,5);
lcd_str_w(S.DateString2);
}
//----------wait approx. 0.8s to avoid heating up SHT10------------------------------ */
for (i=0;i<10000;i++); //(be sure that the compiler doesn't eliminate this line!)
//----------------------------------------------------------------------------------- */
}
//--------------------温湿度界面显示------------------------
void sht11_window(void)
{
lcd_cmd_w(0x01);
lcd_setposition(1,1);
lcd_str_w("温湿测量系统");
lcd_setposition(2,0);
lcd_str_w("当前温度:");
lcd_setposition(3,0);
lcd_str_w("当前湿度:");
}
#endif