打印

请教温湿度传感器SHT1X系列问题!

[复制链接]
2230|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
沙发
libers| | 2013-5-1 17:55 | 只看该作者
?没人回答

使用特权

评论回复
板凳
tyw| | 2013-5-1 20:23 | 只看该作者
本帖最后由 tyw 于 2013-5-1 20:26 编辑

SHT1xV5湿度传感器手册.pdf (436.23 KB)






SHT10温湿度传感器测试程序  
    SHT10是一个数字式的传感器,可以同时测量温度和湿度。市场价40元左右。由于现在做的项目需要满足-40度的测量才选的它,如果只需要测量0度以上的温度,用DHT1x系列就行了,据说它们和SHT1x系列是兼容的,但便宜了不少,其中DHT11才7块钱。

    一开始直接将官方的51例程往AVR上移植,但是不好使,无奈之下自己照着数据手册写了时序。其中的一些标识符(函数名等)沿用了官方例程中的命名,一些不涉及硬件的程序(例如温湿度的修正函数)是直接复制过来用的。

    由于只是用于测试,我没做CRC-8的校验。

    SHT10的DATA接的PA0,SCK接PA1。







//***************************************
//SHT10测试程序
//李木玄
//MCU:ATmega16
//晶振:8M
//编译器:ICCAVR
//创建于:2010/6/22
//*****************************************

#include <iom16v.h>
#include <math.h>
#include "avrlcd3.1.c"  //这是我自己写的液晶显示函数
//=====宏定义=======================================
#define DATA_1 PORTA|=0X01
#define DATA_0 PORTA&=0XFE
#define SCK_1 PORTA|=0X02
#define SCK_0 PORTA&=0XFD
#define DATA_SETINPUT DDRA&=0XFE;PORTA|=0X01
#define DATA_SETOUTPUT DDRA|=0X01
#define SCK_SETINPUT DDRA&=0XFD;PORTA|=0X02
#define SCK_SETOUTPUT DDRA|=0X02
#define DATA_IN (PINA&0X01)
#define noACK 0
#define ACK 1
       //adr command r/w
#define STATUS_REG_W 0x06  //000   0011   0
#define STATUS_REG_R 0x07  //000   0011   1
#define MEASURE_TEMP 0x03  //000   0001   1
#define MEASURE_HUMI 0x05  //000   0010   1
#define RESET 0x1e    //000   1111   0

#define TEMP 0
#define HUMI 1
//=====函数声明===============================================
void delay_ms(int t);
void s_transstart(void);
char s_write_byte(unsigned char value);  //写入一个字节的命令,并且检查传感器是否正确接收了这个数据,返回值为0表示正确接收
char s_read_byte(unsigned char ack);  //读一个字节的数据,并且向传感器发出一个字节的“已接收”信号
int s_measure(unsigned char mode);   //进行一次测量
void calc_sth11(float *p_humidity ,float *p_temperature);//测量结果修正

//-----主函数-----------------------------------------------------------
void main(void)
{
float temp,humi;
while(1)
{
  temp = s_measure(TEMP);
  humi = s_measure(HUMI);
  calc_sth11(&humi,&temp);
  printf("t=%f C\nh=%f %",temp,humi);//将检测结果输出到液晶屏上,
                                  //这个函数是我自己写的,用于液晶屏的显示,不是stdio.h里的那个  
  delay_ms(2000);
}

}


//=====函数定义========================================
//********************************
//延时若干毫秒
//********************************
void delay_ms(int t)
{
   int i,j;
  for(i=0;i<t;i++)
     for(j=0;j<1141;j++);
}
//*******************************
//短延时
//*******************************
void delay_little(void)
{
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
}
//********************************************
//启动传输
//***********************************************
void s_transstart(void)
{
DATA_SETOUTPUT;
SCK_SETOUTPUT;

DATA_1;
SCK_0;
delay_little();
SCK_1;
delay_little();
DATA_0;
delay_little();
SCK_0;
delay_little();
SCK_1;
delay_little();
DATA_1;
delay_little();
SCK_0;
}
//********************************
//写入一个字节的命令,并且检查传感器是否正确接收了这个数据,返回值为0表示正确接收
//*******************************
char s_write_byte(unsigned char value)
{
unsigned char i;
char error;
DATA_SETOUTPUT;
SCK_SETOUTPUT;

SCK_0;
DATA_0;
for(i=0;i<8;i++)  //发送8位数据,丛机将在上升沿读取数据
{
  SCK_0;
  if(value&(0x80>>i))
   DATA_1;
  else
   DATA_0;
  delay_little();
  SCK_1;
  delay_little();
}

SCK_0;     //在接下来的上升沿读取从机发送的“已收到”信号。
DATA_SETINPUT;
delay_little();
SCK_1;
delay_little();
error = (DATA_IN?1:0);
delay_little();
SCK_0;

DATA_SETOUTPUT;

return error;

}
//********************************************
//读一个字节的数据,并且向传感器发出一个字节的“已接收”信号
//********************************************
char s_read_byte(unsigned char ack)
{
unsigned char i,val=0;

DATA_SETINPUT;
//SCK_SETOUTPUT;

SCK_0;
for (i=0x80;i>0;i>>=1)       //接收8位数据
{
  SCK_1;         
  delay_little();
  if (DATA_IN)
   val=(val | i);      //read bit
  SCK_0;
  delay_little();
}

if(ack)
  DATA_1;
else
  DATA_0;
DATA_SETOUTPUT;  //发送一个ack位(0),表示是否接收到数据

delay_little();
SCK_1;
delay_little();
return val;
}
//***************************************************
//温湿度的计算和修正
//************************************************
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
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]
}
//************************************************
// makes a measurement (humidity/temperature) with checksum
//测量一次温度/湿度,无校验
//参数:0表示温度,1表示湿度
//**************************************************
int s_measure(unsigned char mode)
{
unsigned char a,b;
s_transstart();  //启动传输
switch(mode)    //发送开始测量命令
{
  case 0 : s_write_byte(MEASURE_TEMP); break;
  case 1 : s_write_byte(MEASURE_HUMI); break;
  default : break;
}

DATA_SETINPUT;
while(DATA_IN);   //等待检测完成

//读取两个字节的数据
a=s_read_byte(0);
b=s_read_byte(1);

return (((int)a)<<8)+b;



使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

9

主题

87

帖子

1

粉丝