有谁用过SHT7X系列温湿度传感器

[复制链接]
2575|10
手机看帖
扫描二维码
随时随地手机跟帖
highhand|  楼主 | 2007-3-28 20:56 | 显示全部楼层 |阅读模式
感觉好像读写存储芯片那样,但是就是不能正常读取,哪位读取SHT7X系列的,能否提供一份参考程序,谢谢!有酬
mohanwei| | 2007-3-28 21:38 | 显示全部楼层

厂家就给出了例程……

用起来感觉非常方便。
注意它的接口只是看起来很想I2C而已,实际不是的……好好阅读一下手册。

使用特权

评论回复
yewuyi| | 2007-3-29 10:55 | 显示全部楼层

怎么个有酬法子?

呵呵,自己看看就知道了啊,也可以联系代理商,需要提醒你的是,这个东西精度确实不错,但因为要求功耗的原因,传输距离要注意

使用特权

评论回复
highhand|  楼主 | 2007-3-29 11:30 | 显示全部楼层

联系过了,还是没有解决

代理商只提供51的参考程序,存在的可能是IO方向问题,我也试过了,还是出不来,楼上的兄弟们如果做过的话就指点指点吧,谢谢你们了!

使用特权

评论回复
chenlung| | 2007-3-29 13:41 | 显示全部楼层

能不能把你的CPU连接和程序搞出来看下

只见你说有问题,这样哪里看得出来。

使用特权

评论回复
highhand|  楼主 | 2007-3-29 15:07 | 显示全部楼层

自己程序

PA2作为时钟线,PA3作为数据线。因为要用作定时输出,所以用到了定时中断程序,请各位帮我看看,程序可能乱了点,主要是看看SHT部分,PWM、定时那些都没有问题的了。不胜感激!!



#include  <pic.h>
#include  <pic16f81x.h>
#include  <math.h>
#include  <stdio.h>

char s_write_byte(unsigned char value);
char s_read_byte(unsigned char ack);
void s_transstart(void);
void s_connectionreset(void);
char s_softreset(void);
char s_read_statusreg(unsigned char *p_value, unsigned char *p_checksum);
char s_write_statusreg(unsigned char *p_value);
char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode);
void calc_sth11(float *p_humidity ,float *p_temperature);
float calc_dewpoint(float h,float t);
void PWM_Initial(void);
void PWM_Display(int PWMOut92, int PWMOut10);
void Timer1_Initial(void);
void interrupt isr(void);

static bit      SCK      @ (unsigned)&PORTA*8+2;
static bit      DATA     @ (unsigned)&PORTA*8+3;

//------------------------------------------------------------------------------
// modul-var
//------------------------------------------------------------------------------
enum {TEMP,HUMI};

#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

char PWM92,PWM10;
unsigned int n_Scan=0,pwm=0;
float dew_point;
unsigned char err,chksum;
unsigned int humi_vali=0,temp_vali=0;
float humi_valf,temp_valf;

main()
{
      TRISA = 0x00;            
    TRISB = 0x00;
    PORTB = 0x0FF;        
          
     PWM_Initial();       //  PWM Initial
     Timer1_Initial();    //  Timer1 Initial
    PEIE=1;              //  Enable Peripheral Interupts
    GIE =1;              //  Enable Global Interrupt
    
    s_connectionreset();
    while(1)
    {
    //
    }
}


void PWM_Initial(void)
{
    PR2=0x0F9;
    CCPR1L=0x7F;
    CCP1CON=0x20;
    TRISB=0x00;
    T2CON=0x05;
    CCP1CON|=0x0F;
}


void PWM_Display(int PWMOut92, int PWMOut10)
{
    CCPR1L=PWMOut92;
    CCP1CON&=0x0CF;
    CCP1CON|=PWMOut10;    
}    


void Timer1_Initial(void)
{
    OPTION=0x87;     //    Falling Edge of INT Pin,WDT Fosc/128
    PSA=1;            //    WDT Fosc/128
    T1CON=0x00;      //    Internal Clock(Fosc/4)
    TMR1H=0x0FC;     
    TMR1L=0x2E;      //    1ms
    TMR1IF=0;        //    Clear TIMER1 Interrupt Flag
    TMR1IE=1;        //    Enable TIMER1 Interrupt
    TMR1ON=1;        //    Start Timing
}


void interrupt isr(void)
{
    if (TMR1IF==1)       //  TIMER1 Interrupt Subroutine
    {
    TMR1IF=0;
    TMR1H=0x0FC;
    TMR1L=0x2E;
    n_Scan+=1;
    CLRWDT();            //  WDT Clear
    
    if (n_Scan==1000)      
    {
    PORTB=0x0FF;
    CLRWDT();            //  WDT Clear
    }
    
    if (n_Scan==1500)      
    {
    PORTB=0x01;
    //pwm=200;
    if(pwm==1000)
    {
    pwm=0;
    }
    PWM10=(char)(pwm&(0x03));
    PWM10=PWM10<<4;
    PWM92=pwm>>2;
    PWM_Display(PWM92,PWM10);
    }
    
    if (n_Scan==2000)      
    {
    PORTB=0x02;
    err=0;
    err+=s_measure((unsigned char*) &humi_vali,&chksum,HUMI);  //measure humidity
    //err+=s_measure((unsigned char*) &temp_vali,&chksum,TEMP);  //measure temperature
    //if(err!=0) 
    //{s_connectionreset();}
    if(err==0)
        {
        //humi_vali=1500;
        //temp_vali=10000; 
        humi_valf=(float)humi_vali;                   //converts integer to float
        temp_valf=(float)temp_vali;                   //converts integer to float
        calc_sth11(&humi_valf,&temp_valf);            //calculate humidity, temperature
        pwm=(unsigned int) (humi_valf*10);
    }
    }
    
    if (n_Scan==7000)      
    {
    PORTB=0x03;
    }
    
    if (n_Scan==8000)      
    {
    PORTB=0x04;
    }
    
    if (n_Scan==8999)    //  
    {
    PORTB=0x0;
    n_Scan=0;    
    }
    }
}


//----------------------------------------------------------------------------------
char s_write_byte(unsigned char value)
//----------------------------------------------------------------------------------
// writes a byte on the Sensibus and checks the acknowledge 

  unsigned char i,error=0;  
  for (i=0x80;i>0;i/=2)             //shift bit for masking
  { if (i & value) DATA=1;          //masking value with i , write to SENSI-BUS
    else DATA=0;                        
    SCK=1;                          //clk for SENSI-BUS
    NOP();NOP();NOP();              //pulswith approx. 5 us      
    SCK=0;
  }
  DATA=1;                           //release DATA-line
  SCK=1;                            //clk #9 for ack 
  error=DATA;                       //check ack (DATA will be pulled down by SHT11)
  SCK=0;
  return error;                     //error=1 in case of no acknowledge
}


//----------------------------------------------------------------------------------
char s_read_byte(unsigned char ack)
//----------------------------------------------------------------------------------
// reads a byte form the Sensibus and gives an acknowledge in case of "ack=1" 

  unsigned char i,val=0;
  DATA=1;                           //release DATA-line
  TRISA3=1;
  for (i=0x80;i>0;i/=2)             //shift bit for masking
  { SCK=1;                          //clk for SENSI-BUS
    if (DATA) val=(val | i);        //read bit  
    SCK=0;                       
  }
  TRISA3=0;
  DATA=!ack;                        //in case of "ack==1" pull down DATA-Line
  SCK=1;                            //clk #9 for ack
  NOP();NOP();NOP();                //pulswith approx. 5 us 
  SCK=0;                            
  DATA=1;                           //release DATA-line
  return val;
}


//----------------------------------------------------------------------------------
void s_transstart(void)
//----------------------------------------------------------------------------------
// generates a transmission start 
//       _____         ________
// DATA:      |_______|
//           ___     ___
// SCK : ___|   |___|   |______
{  
   DATA=1; SCK=0;                   //Initial state
   NOP();
   SCK=1;
   NOP();
   DATA=0;
   NOP();
   SCK=0;  
   NOP();NOP();NOP();
   SCK=1;
   NOP();
   DATA=1;           
   NOP();
   SCK=0;           
}


//----------------------------------------------------------------------------------
void s_connectionreset(void)
//----------------------------------------------------------------------------------
// communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
//       _____________________________________________________         ________
// DATA:                                                      |_______|
//          _    _    _    _    _    _    _    _    _        ___     ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______|   |___|   |______
{  
  unsigned char i; 
  DATA=1; SCK=0;                    //Initial state
  for(i=0;i<9;i++)                  //9 SCK cycles
  { SCK=1;
    SCK=0;
  }
  s_transstart();                   //transmission start
}


//----------------------------------------------------------------------------------
char s_softreset(void)
//----------------------------------------------------------------------------------
// resets the sensor by a softreset 

  unsigned char error=0;  
  s_connectionreset();              //reset communication
  error+=s_write_byte(RESET);       //send RESET-command to sensor
  return error;                     //error=1 in case of no response form the sensor
}


//----------------------------------------------------------------------------------
char s_read_statusreg(unsigned char *p_value, unsigned char *p_checksum)
//----------------------------------------------------------------------------------
// reads the status register with checksum (8-bit)

  unsigned char error=0;
  s_transstart();                   //transmission start
  error=s_write_byte(STATUS_REG_R); //send command to sensor
  *p_value=s_read_byte(ACK);        //read status register (8-bit)
  *p_checksum=s_read_byte(noACK);   //read checksum (8-bit)  
  return error;                     //error=1 in case of no response form the sensor
}


//----------------------------------------------------------------------------------
char s_write_statusreg(unsigned char *p_value)
//----------------------------------------------------------------------------------
// writes the status register with checksum (8-bit)

  unsigned char error=0;
  s_transstart();                   //transmission start
  error+=s_write_byte(STATUS_REG_W);//send command to sensor
  error+=s_write_byte(*p_value);    //send value of status register
  return error;                     //error>=1 in case of no response form the sensor
}

                                
//----------------------------------------------------------------------------------
char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)
//----------------------------------------------------------------------------------
// makes a measurement (humidity/temperature) with checksum

  unsigned error=0;
  unsigned int i;

  s_transstart();                   //transmission start
  PORTB=0x0;
  switch(mode){                     //send command to sensor
    case TEMP    : error+=s_write_byte(MEASURE_TEMP);
                  
                  break;
    case HUMI    : error+=s_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)  =s_read_byte(ACK);    //read the first byte (MSB)
  *(p_value+1)=s_read_byte(ACK);    //read the second byte (LSB)
  *p_checksum =s_read_byte(noACK);  //read checksum
  return error;
}


//----------------------------------------------------------------------------------------
void calc_sth11(float *p_humidity ,float *p_temperature)
//----------------------------------------------------------------------------------------
// calculates temperature [癈] and humidity [%RH] 
// input :  humi [Ticks] (12 bit) 
//          temp [Ticks] (14 bit)
// output:  humi [%RH]
//          temp [癈]
{ 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]
}


//--------------------------------------------------------------------
float calc_dewpoint(float h,float t)
//--------------------------------------------------------------------
// calculates dew point
// input:   humidity [%RH], temperature [癈]
// output:  dew point [癈]
{ 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;
}




使用特权

评论回复
lehao| | 2007-3-29 18:40 | 显示全部楼层

不懂c语言

  用汇编做过,我做的时候有个问题,一个是等待是否检测到变低的信号.得到这个信号了就说明通讯工作对了. 你要是迷惑,先做个程序检测这个低信号好了.

  没学过c语言,只能这么说下了.

  工作过程是容易:先发启动信号,在发命令,等待低信号,在就读数据好了.sht工作有周期,你的时间间隔不能太短,他本身的检测时间较长.

  希望能帮到你!

使用特权

评论回复
mohanwei| | 2007-3-29 22:03 | 显示全部楼层

今天太晚了,我明天再看看程序……

一般说来这种接口的驱动是最好写的,先按照手册上的读写流程图编写出程序框架,然后往下细化到read和write函数,最后参照读写时序图编写read和write的实现。

调试的时候不要急着直接编译整个项目,要先单独编几个测试函数先把接口完全调通。调试的时候最好能有硬件仿真器(其实我一般是用keil先进行软件仿真的……),结合万用表和示波器观察管脚电平变化,有一点不对也要分析清楚。

虽然这段文字看起来是纸上谈兵,但的确是我多年调程序总结出来的部分经验,我按照这个步骤来调接口,几乎没有浪费过时间。

使用特权

评论回复
highhand|  楼主 | 2007-3-29 22:22 | 显示全部楼层

非常感谢楼上的兄台

真心感谢你,我会再努力的,如果你又时间,也希望你帮帮忙看看,指点一下。

使用特权

评论回复
highhand|  楼主 | 2007-3-31 00:57 | 显示全部楼层

问题已经解决,谢谢大家提示

谢谢大家帮忙!非常感谢!

使用特权

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

本版积分规则

2

主题

7

帖子

0

粉丝