⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sht10.c

📁 Sensiron SHT10 (Temperature and Humidity Sensor) by TI MSP430F2350
💻 C
字号:
/***********************************************************
                  SHT10 by MSP430F2350
Author: Tommy Hung, from The Chinese University of Hong Kong
************************************************************/

#include "io430.h"
#include "math.h"

//Standard
#define TEMP 1
#define HUMI 0

#define ACK 1
#define nACK 0

//Communication Signal
#define S_DAT_H P2DIR &= ~BIT1
#define S_DAT_L P2DIR |= BIT1

#define DAT_OUT_ZERO P2OUT &= ~BIT1

#define S_DAT_IN P2IN & BIT1

#define S_SCK_H P2OUT |= BIT2
#define S_SCK_L P2OUT &= ~BIT2

#define S_SCK_O P2DIR |= BIT2

//Port Function
#define S_DAT_SCK_IO P2SEL = 0


//Command Defination                 Add Command R/~W
#define S_RD_T    0x03            // 000   0001   1
#define S_RD_RH   0X05            // 000   0010   1      
#define S_RD_SREG 0X07            // 000   0011   1
#define S_WR_SREG 0X06            // 000   0011   0 
#define S_RESET   0X1E            // 000   1111   0

//Constant used for calculating Temperature and Humidity


typedef union
{
  unsigned int i;
  float f;
}value;

//Functions declaration
char S_WR_BYTE (unsigned char byte);
char S_RD_BYTE (unsigned char ack);
void S_START_TX (void);
void S_CON_RESET (void);
char S_SOFT_RESET (void);
char RD_SREG (unsigned char *sreg, unsigned char *checksum);
char WR_SREG (unsigned char *sreg);
char S_MEASURE (unsigned char *result, unsigned char *checksum, unsigned char mode);
void CAL_TEMP_HUMI(float *humidity,float *temperature);
float CAL_DEWP (float humi,float temp);

void main(void)
{  

  WDTCTL = WDTPW + WDTHOLD;       // Stop watchdog timer to prevent time out reset

  S_DAT_SCK_IO;                   //P2 is a normal I/O port
  S_SCK_O;                        //P2.2 = Output
  DAT_OUT_ZERO;                   //DATA always out logic Zero  

  P4SEL = 0;                      //LED testing Setting
  P4DIR = 0xFF;                    
  P4OUT = 0;                     
  
  value humi,temp;
  float dew_point;
  unsigned char error,checksum;
  unsigned int i;
  
  for (i=0;i<2000;i++)             //wait ~11ms////////////////////////////////////////////////////////
  {}
  
  S_CON_RESET();
  
  while (1)
  {
    error = 0;
    error += S_MEASURE((unsigned char*) &humi.i,&checksum,HUMI);
    error += S_MEASURE((unsigned char*) &temp.i,&checksum,TEMP);
    if (error !=0)
      S_CON_RESET();
    else
    {
      humi.f = (float) humi.i;
      temp.f = (float) temp.i;
      CAL_TEMP_HUMI(&humi.f,&temp.f);
      dew_point = CAL_DEWP(humi.f,temp.f);
      
      if (temp.f < 20)                         //LED Testing 
        P4OUT = 0x00;                          
      else if (temp.f < 22)
        P4OUT = 0x04;
      else if (temp.f < 24)
        P4OUT = 0x08;
      else if (temp.f < 26)
        P4OUT = 0x0C;
      else if (temp.f < 28)
        P4OUT = 0x10;
      else if (temp.f < 32)
        P4OUT = 0x14;
      else if (temp.f < 34)
        P4OUT = 0x18;
      else
        P4OUT = 0x1C;    
    }        
    for (i = 0 ; i < 40000 ; i++) {}
  }  
}

//Write a byte to SHT10 with acknowledge checking
char S_WR_BYTE (unsigned char byte)
{                  
  unsigned char i,error = 0;
  for (i = 0x80 ; i > 0 ; i /= 2)
  {
    if (i & byte)                 //Send the byte to the bus by bit
      S_DAT_H;                    //Close P2.1 so pull up high
    else
      S_DAT_L;                    //Open P2.1 for output zero
    
    S_SCK_H;                      //Clk signal for the bus
    asm("nop;nop;nop");
    S_SCK_L;  
  }
  
  S_DAT_H;                        //Release DATA Line
  S_SCK_H;                        //Clk #9 For Ack
   
  if (S_DAT_IN)                   //Check Ack
    error = 1;
  else
    error = 0;
 
  S_SCK_L;
  
  return error;                   //Return Ack
}

//Read a byte from SHT10 with acknowledge checking
char S_RD_BYTE (unsigned char ack)
{
  unsigned char i,byte = 0;
  
  S_DAT_H;                        //Release DATA Line
  
  for (i = 0x80 ; i > 0 ; i /= 2) //Read the byte by comapring each bit
  {
    S_SCK_H;
    
    if (S_DAT_IN)
      byte = ( byte | i );
    
    S_SCK_L;
  }

  if (!ack)                       //Checking whether do the ack or not
    S_DAT_H;                      //No
  else
    S_DAT_L;                      //Yes
  
  S_SCK_H;                        //Clk #9 For Acknowledgement
  asm("nop;nop;nop");
  S_SCK_L;
  
  S_DAT_H;                        //Release DATA Line
  
  return byte;                    //Return Reading
}

//Start transmission
//        _____         ________
// DATA:       |_______|
//            ___     ___
// SCK :  ___|   |___|   |______
void S_START_TX (void)
{
  S_DAT_H;  S_SCK_L;              //Initial State
  asm("nop");
  S_SCK_H;
  asm("nop");
  S_DAT_L;
  asm("nop");
  S_SCK_L;
  asm("nop;nop;nop");
  S_SCK_H;
  asm("nop");
  S_DAT_H;
  asm("nop");
  S_SCK_L;
}

//Connection Reset Signal
//       _____________________________________________________         ________
// DATA:                                                      |_______|
//          _    _    _    _    _    _    _    _    _        ___     ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______|   |___|   |______
void S_CON_RESET (void)
{
  unsigned char i; 
  S_DAT_H;  S_SCK_L;              //Initial State
    
  for ( i = 0 ; i < 9 ; i++ )       //generate 9 clk pulse
  {
    S_SCK_H;
    S_SCK_L;
  }
  
  S_START_TX();
}

//Sofe reset of the SHT10
char S_SOFT_RESET (void)
{
  unsigned char error = 0;
  
  S_CON_RESET();
  error += S_WR_BYTE(S_RESET);
  
  return error;
}

//Read the status register from SHT10
char RD_SREG (unsigned char *sreg, unsigned char *checksum)
{
  unsigned char error = 0;
  
  S_START_TX();  
  error = S_WR_BYTE(S_RD_SREG);
  *sreg = S_RD_BYTE(ACK);
  *checksum = S_RD_BYTE(nACK);
  
  return error;
}

//Write the status register to SHT10
char WR_SREG (unsigned char *sreg)
{
  unsigned char error = 0;
  
  S_START_TX();  
  error += S_WR_BYTE(S_WR_SREG);
  error += S_WR_BYTE(*sreg);
  
  return error;
}

//Measure the temperature and humidity
char S_MEASURE (unsigned char *result, unsigned char *checksum, unsigned char mode)
{
  unsigned error=0;
  unsigned int i;
  
  S_START_TX();
  
  switch (mode)                     //check the measuring target
  {
  case HUMI:
    error += S_WR_BYTE(S_RD_RH);   
    break;
  
  case TEMP:
    error += S_WR_BYTE(S_RD_T);
    break;
  
  default:
    break;
  }
  
  for (i = 0 ; i < 65535 ; i++ )     //check the data ready or til a period of time
  {    
    if (S_DAT_IN == 0)
      break;
  }
  
  if (S_DAT_IN)                      //Check break from time periode or data ready
    error += 1;                      //if break from time period = error
 
  *(result + 1) = S_RD_BYTE(ACK);    //Reading MSB //////////////////////////////////////////////////
  *(result) = S_RD_BYTE(ACK);        //Reading LSB //////////////////////////////////////////////////
  *checksum = S_RD_BYTE(nACK);       //Reading checksum
  
  return error;  
}

void CAL_TEMP_HUMI(float *humidity,float *temperature)
{  
  const float c1 = -4.0;
  const float c2 = 0.0405;
  const float c3 = -0.0000028;
  const float t1 = 0.01;
  const float t2 = 0.00008;
  
  float rh = *humidity;
  float t = *temperature;
  float rh_lin;
  float rh_true;
  float t_c;
  
  t_c = t * 0.01 - 39.6;
  rh_lin = c3 * rh * rh + c2 * rh + c1;
  rh_true = ( t_c - 25 ) * ( t1 + t2 * rh ) + rh_lin;
  if (rh_true > 100)    rh_true = 100;
  if (rh_true < 0.1)    rh_true = 0.1;
  
  *temperature = t_c;
  *humidity = rh_true;
}

float CAL_DEWP (float humi,float temp)
{
  float h,dp;
  h = (log10(humi) - 2) / 0.4343 + (17.62 * temp) / (243.12 + temp);
  dp = 243.12 * h / (17.62 - h);
  return dp;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -