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

📄 sht1x.c

📁 SHT10采集的温度和湿度
💻 C
字号:
/**************************************************
      温度湿度测量
采用: Sensirion SHT1x 温湿度传感器
通讯: IIC总线
***************************************************/
#include <msp430x14x.h>
#include <math.h>
#include "Global.h"
#include "ModbusSlaver.h"

/* ---- 引脚端口定义 ---- */
#define IIC_OUT       (P2OUT)
#define IIC_IN        (P2IN)
#define IIC_DIR       (P2DIR)
#define IIC_DAT       (BIT0)
#define IIC_SCK       (BIT1)
// DAT脚采用电阻上拉, 所以初始化让DAT输出0
// DAT线为1: 则把DAT切换为输入状态, DAT线被拉为1
// DAT线为0: 则把DAT切换为输出状态, DAT输出0
#define IIC_DAT_1     IIC_DIR &= ~IIC_DAT
#define IIC_DAT_0     IIC_DIR |=  IIC_DAT
// SCK先为单片机直接输出
#define IIC_SCK_1     IIC_OUT |=  IIC_SCK
#define IIC_SCK_0     IIC_OUT &= ~IIC_SCK
// 读取DAT线的高低(是否为0)
#define IIC_DAT_R     (IIC_IN & IIC_DAT)

/* ---- 命令定义 ---- */
#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 NO_ERROR      0
#define ERROR_NOACK   1


#define STATUS_OK                     (0)
#define STATUS_SENSORFAIL             (1)
unsigned char Flg_MeasureTcRH = FALSE;// 测量允许标志
unsigned char Status;                 // 状态
unsigned char Flg_BatteryLow;         // 电压低标志

#define ACK_TIME_OUT                  (30000)
#define DELAY_VALUE                   (20)
void SHT_Delay(unsigned int time)
{
  for(; time>0; time--){}
}



unsigned char SHT_WriteByte(unsigned char Value)
// writes a byte on the Sensibus and checks the acknowledge 
{ 
  unsigned char i;
  unsigned char Error = 0;  
  // Send 8bit Data
  for (i=0x80; i>0; i/=2)           //shift bit for masking
  { 
    if (i & Value) IIC_DAT_1;       //masking value with i , write to SENSI-BUS
    else IIC_DAT_0;  
    SHT_Delay(DELAY_VALUE);
    IIC_SCK_1;                      //clk for SENSI-BUS
    _NOP();_NOP();_NOP();_NOP();    //pulswith approx. 5 us  	
    SHT_Delay(DELAY_VALUE);
    IIC_SCK_0;
    SHT_Delay(DELAY_VALUE);
  }
  // Release Bus and wait for ACK signal
  IIC_DAT_1;                        //release DATA-line
  SHT_Delay(DELAY_VALUE);
  IIC_SCK_1;                        //clk #9 for ack 
  SHT_Delay(DELAY_VALUE);
  if (IIC_DAT_R) Error = ERROR_NOACK;
  else Error = NO_ERROR;             //check ack (DATA will be pulled down by SHT11)                  
  IIC_SCK_0; 
  // retuen Error      
  return Error;                     //error=1 in case of no acknowledge
}

unsigned char SHT_ReadByte(unsigned char Ack)
// reads a byte form the Sensibus and gives an acknowledge in case of "ack=1" 
{ 
  unsigned char i;
  unsigned char Value=0;
  
  // Read 8bit from Data-line
  IIC_DAT_1;                        //release DATA-line
  for (i=0x80; i>0; i/=2)           //shift bit for masking
  { 
    IIC_SCK_1;                      //clk for SENSI-BUS
    SHT_Delay(DELAY_VALUE);
    if (IIC_DAT_R) Value |= i;      //read bit  
    _NOP();_NOP();_NOP();_NOP();    // Edit By Bull
    SHT_Delay(DELAY_VALUE);
    IIC_SCK_0;  		
    SHT_Delay(DELAY_VALUE);			 
  }
  // Answer for Ack
  if (Ack) IIC_DAT_0;                //in case of "ack==1" pull down DATA-Line
  IIC_SCK_1;                        //clk #9 for ack
  SHT_Delay(DELAY_VALUE);
  _NOP();_NOP();_NOP();_NOP();      //pulswith approx. 5 us 
  IIC_SCK_0;
  SHT_Delay(DELAY_VALUE);
  IIC_DAT_1;                        //release DATA-line
  //retuen Byte
  return Value;
}


void SHT_TransStart(void)
// generates a transmission start 
//       _____         ________
// DATA:      |_______|
//           ___     ___
// SCK : ___|   |___|   |______
{  
   IIC_DAT_1; IIC_SCK_0;                   //Initial state
   SHT_Delay(DELAY_VALUE);
   IIC_SCK_1;
   SHT_Delay(DELAY_VALUE);
   IIC_DAT_0;
   SHT_Delay(DELAY_VALUE);
   IIC_SCK_0;  
   SHT_Delay(DELAY_VALUE);
   IIC_SCK_1;
   SHT_Delay(DELAY_VALUE);
   IIC_DAT_1;		   
   SHT_Delay(DELAY_VALUE);
   IIC_SCK_0;		   
}

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

unsigned char SHT_SoftReset(void)
// resets the sensor by a softreset 
{ 
  unsigned char Error=0;  
  SHT_ConnectionReset();            //reset communication
  Error += SHT_WriteByte(RESET);    //send RESET-command to sensor
  return Error;                     //error=1 in case of no response form the sensor
}

unsigned char SHT_ReadStatusReg(unsigned char *p_Value, unsigned char *p_CheckSum)
// reads the status register with checksum (8-bit)
{ 
  unsigned char Error = 0;
  SHT_TransStart();                   //transmission start
  Error       = SHT_WriteByte(STATUS_REG_R);    //send command to sensor
  *p_Value    = SHT_ReadByte(ACK);              //read status register (8-bit)
  *p_CheckSum = SHT_ReadByte(NOACK);            //read checksum (8-bit)  
  return Error;                     //error=1 in case of no response form the sensor
}

unsigned char SHT_WriteStatusReg(unsigned char *p_Value)
// writes the status register with checksum (8-bit)
{ 
  unsigned char Error=0;
  SHT_TransStart();                     //transmission start
  Error += SHT_WriteByte(STATUS_REG_W); //send command to sensor
  Error += SHT_WriteByte(*p_Value);     //send value of status register
  return Error;                         //error>=1 in case of no response form the sensor
}

/* ---- 温度湿度测量函数 Temperature & Humidity Measure function---- */
unsigned char SHT_Measure_Temperature(signed int *p_Value, unsigned char *p_CheckSum)
// makes a measurement (humidity/temperature) with checksum
{ 
  unsigned Error = 0;
  unsigned int i, j;
  unsigned char TempH;
  unsigned char TempL;
 
  SHT_TransStart();                       //transmission start
  Error += SHT_WriteByte(MEASURE_TEMP);   //send command to sensor

  for (i=0;i<ACK_TIME_OUT;i++)
  {
    for (j=0;j<10;j++){_NOP(); _NOP(); _NOP(); _NOP();}
    if(IIC_DAT_R==0) break; //wait until sensor has finished the measurement
    //Modbus_Deal();
  }
  if(IIC_DAT_R) Error+=1;                 // or timeout (~2 sec.) is reached
  //*(p_Value)    = SHT_ReadByte(ACK);    //read the first byte (MSB)
  //*(p_Value+1)  = SHT_ReadByte(ACK);    //read the second byte (LSB)
  TempH = SHT_ReadByte(ACK);
  TempL = SHT_ReadByte(ACK);
  *p_Value = TempH * 256 + TempL;
  *p_CheckSum   = SHT_ReadByte(NOACK);  //read checksum
  return Error;
}

unsigned char SHT_Measure_Humidity(signed int *p_Value, unsigned char *p_CheckSum)
// makes a measurement (humidity/temperature) with checksum
{ 
  unsigned Error = 0;
  unsigned int i;
  
  unsigned char TempH;
  unsigned char TempL;

  SHT_TransStart();                       //transmission start
  Error += SHT_WriteByte(MEASURE_HUMI);   //send command to sensor
  for (i=0;i<ACK_TIME_OUT;i++)
  {
    if(IIC_DAT_R==0) break; //wait until sensor has finished the measurement
    //Modbus_Deal();
  }
  if(IIC_DAT_R) Error+=1;                // or timeout (~2 sec.) is reached
  //*(p_Value)    = SHT_ReadByte(ACK);    //read the first byte (MSB)
  //*(p_Value+1)  = SHT_ReadByte(ACK);    //read the second byte (LSB)
  TempH = SHT_ReadByte(ACK);
  TempL = SHT_ReadByte(ACK);
  *p_Value = TempH * 256 + TempL;
  *p_CheckSum   = SHT_ReadByte(NOACK);  //read checksum
  return Error;
}

/* ---- SHT传感器初始化 ---- */
void SHT_Init(void)
{
  IIC_OUT &= ~IIC_DAT;
  IIC_DIR |=  IIC_SCK;
}

/* ---- 数据转换函数 ---- */
//----------------------------------------------------------------------------------------
void SHT_Calc_STH1x(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 SHT_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;
}


void SHT_MeasureTRHD(signed int *pTc, signed int *pRH, signed int *pDp)
{ 
  unsigned char Error = 0;
  unsigned char CheckSum;
  signed int    Sample_T;
  signed int    Sample_H;
  float         f_Tc;
  float         f_RH;
  float         f_Dp;
  unsigned char StatusReg;
  
  if (Flg_MeasureTcRH == FALSE) return;

  // Sampling
  Error += SHT_Measure_Temperature(&Sample_T, &CheckSum);
  Error += SHT_Measure_Humidity(&Sample_H, &CheckSum);   
  Error += SHT_ReadStatusReg(&StatusReg, &CheckSum);
  // Calc
  f_RH = (float) Sample_H;
  f_Tc = (float) Sample_T;
  SHT_Calc_STH1x(&f_RH, &f_Tc);
  f_Dp = SHT_Calc_Dewpoint(f_RH, f_Tc);
  
  // Save
  _DINT();
  *pTc = (signed int)(f_Tc * 10);
  *pRH = (signed int)(f_RH * 10);
  *pDp = (signed int)(f_Dp * 10);

  Status = STATUS_OK;
  if (Error != 0){Status = STATUS_SENSORFAIL;}
  else
  {
    if (StatusReg & BIT6)
    {
      Flg_BatteryLow = 1;
      Status = STATUS_SENSORFAIL;
    }
  }
  _EINT();
  // Sensor Status

  Flg_MeasureTcRH = FALSE;

}

void SHT_MeasureTRH(signed int *pTc, signed int *pRH)
{ 
  unsigned char Error = 0;
  unsigned char CheckSum;
  signed int    Sample_T;
  signed int    Sample_H;
  float         f_Tc;
  float         f_RH;
  unsigned char StatusReg;
  
  if (Flg_MeasureTcRH == FALSE) return;
  Flg_MeasureTcRH = FALSE;
  // Sampling
  Error += SHT_Measure_Temperature(&Sample_T, &CheckSum);
  Error += SHT_Measure_Humidity(&Sample_H, &CheckSum);   
  Error += SHT_ReadStatusReg(&StatusReg, &CheckSum);
  // Calc
  f_RH = (float) Sample_H;
  f_Tc = (float) Sample_T;
  SHT_Calc_STH1x(&f_RH, &f_Tc);
  // Save
  _DINT();
  *pTc = (signed int)(f_Tc * 10);
  *pRH = (signed int)(f_RH * 10);
  // Sensor Status
  Status = STATUS_OK;
  if (Error != 0){Status = STATUS_SENSORFAIL;}
  else
  {
    if (StatusReg & BIT6)
    {
      Flg_BatteryLow = 1;
      Status = STATUS_SENSORFAIL;
    }
  }
  _EINT();
}

⌨️ 快捷键说明

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