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

📄 sht11.c

📁 温湿度变送器的下位机代码
💻 C
字号:


#include "SysDef.h"
#include <math.h>    //Keil library  


#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 PinSDA          BIT3 
#define PinSCL          BIT4 

#define SHTXXDIR  P5DIR
#define SHTXXOUT  P5OUT 
#define SHTXXIN   P5IN 



#define SHT_DATA_In()		SHTXXDIR &=~ PinSDA
#define SHT_DATA_Out()		SHTXXDIR |= PinSDA
#define SHT_SCK_In()		SHTXXDIR &=~ PinSCL
#define SHT_SCK_Out()		SHTXXDIR |= PinSCL

#define SHT_SCK_CLR()		SHTXXOUT &=~ PinSCL
#define SHT_SCK_SET()		SHTXXOUT |= PinSCL
#define SHT_DATA_CLR()		SHTXXOUT &=~ PinSDA
#define SHT_DATA_SET()		SHTXXOUT |= PinSDA

#define Read_SHT_DATA()		SHTXXIN & PinSDA

#define _SHT_Shout_Time_	            1

#define TEMP      0x55
#define HUMI      0xAA

//extern fp32 Temp_Value,Humi_Value;		//温湿度值,可与外围接口

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



void Delay_us(uint value)
{
    while(value--);
}


//-----------------------------------------------------------------------------------------
//温度,湿度测量部分
//-----------------------------------------------------------------------------------
uint8 s_write_byte(uint8 value)
//----------------------------------------------------------------------------------
// writes a byte on the Sensibus and checks the acknowledge 
{ 
	uint8 i,error=0,flag = 0;;  
	for (i=0x80;i>0;i/=2) 
          {			//shift bit for masking
		if (i & value) 
                    {			//masking value with i , write to SENSI-BUS
			SHT_DATA_SET();
		}         
		else 
                    {
			SHT_DATA_CLR();
		}                        
		SHT_SCK_SET();					//clk for SENSI-BUS
		Delay_us(_SHT_Shout_Time_);		//pulswith approx. 5 us  	
		SHT_SCK_CLR();
		Delay_us(_SHT_Shout_Time_);
	}
	SHT_DATA_SET();						//release SHT_DATA-line
	Delay_us(_SHT_Shout_Time_);
	SHT_SCK_SET();						//clk #9 for ack 
	Delay_us(_SHT_Shout_Time_);
	
          SHT_DATA_In();
          flag = SHTXXIN & PinSDA;			
	if(flag == PinSDA) 
          {
		error = 1;
	}	
          SHT_DATA_Out();
	Delay_us(_SHT_Shout_Time_);
	SHT_SCK_CLR();
          Delay_us(_SHT_Shout_Time_);
	return error;					//error=1 in case of no acknowledge
}

//----------------------------------------------------------------------------------
uint8 s_read_byte(uint8 ack)
//----------------------------------------------------------------------------------
// reads a byte form the Sensibus and gives an acknowledge in case of "ack=1" 
{ 
	uint8 i,val=0;
	SHT_DATA_SET();						//release SHT_DATA-line
	SHT_DATA_In();						//SHT_DATA input
	Delay_us(_SHT_Shout_Time_);
	for (i=0x80;i>0;i/=2) 
          {			//shift bit for masking
		SHT_SCK_SET();					//clk for SENSI-BUS
		Delay_us(_SHT_Shout_Time_);
		if (Read_SHT_DATA()) 
                    {
			val=(val | i);			//read bit
		}  
		SHT_SCK_CLR();  		
		Delay_us(_SHT_Shout_Time_);			 
	}
	//SHT_DATA=!ack;					//in case of "ack==1" pull down SHT_DATA-Line
	if(ack) 
          {
		SHT_DATA_CLR();
	}
	else 
          {
		SHT_DATA_SET();
	}
	SHT_DATA_Out();
	Delay_us(_SHT_Shout_Time_);
	SHT_SCK_SET();						//clk #9 for ack
	Delay_us(_SHT_Shout_Time_);			//pulswith approx. 5 us 
	SHT_SCK_CLR();						    
	Delay_us(_SHT_Shout_Time_);
	SHT_DATA_SET();						//release SHT_DATA-line
	return val;
}

//----------------------------------------------------------------------------------
void s_transstart(void)
//----------------------------------------------------------------------------------
// generates a transmission start 
//       	 _____         ________
// SHT_DATA:      |_______|
//          	 ___     ___
// SHT_SCK : ___|   |___|   |______
{  
          SHTXXDIR |= PinSDA + PinSCL;
	SHT_DATA_SET(); 				//Initial state
	Delay_us(_SHT_Shout_Time_);
	SHT_SCK_CLR();			
	Delay_us(_SHT_Shout_Time_);
	SHT_SCK_SET();
	Delay_us(_SHT_Shout_Time_);
	SHT_DATA_CLR();
	Delay_us(_SHT_Shout_Time_);
	SHT_SCK_CLR();  
	Delay_us(_SHT_Shout_Time_);
	SHT_SCK_SET();
	Delay_us(_SHT_Shout_Time_);
	SHT_DATA_SET();		  
	Delay_us(_SHT_Shout_Time_);
	SHT_SCK_CLR();		   
}

//----------------------------------------------------------------------------------
void s_connectionreset(void)
//----------------------------------------------------------------------------------
// communication reset: SHT_DATA-line=1 and at least 9 SHT_SCK cycles followed by transstart
//       _____________________________________________________         ________
// SHT_DATA:                                                  |_______|
//              _    _    _    _    _    _    _    _    _        ___     ___
// SHT_SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______|   |___|   |______
{  
	uint8 i; 
            SHTXXDIR += PinSDA + PinSCL;
            
	SHT_DATA_SET();
	Delay_us(_SHT_Shout_Time_);
	SHT_SCK_CLR();					//Initial state
	Delay_us(_SHT_Shout_Time_);
	for(i=0;i<9;i++) 
          {				//9 SHT_SCK cycles
		SHT_SCK_SET();
		Delay_us(_SHT_Shout_Time_);
		SHT_SCK_CLR();
		Delay_us(_SHT_Shout_Time_);
	}
	s_transstart();					//transmission start
}
//----------------------------------------------------------------------------------
uint8 s_softreset(void)
//----------------------------------------------------------------------------------
// resets the sensor by a softreset 
{ 
	uint8 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
}

//----------------------------------------------------------------------------------
uint8 s_read_statusreg(uint8 *p_value, uint8 *p_checksum)
//----------------------------------------------------------------------------------
// reads the status register with checksum (8-bit)
{ 
	uint8 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
}

//----------------------------------------------------------------------------------
uint8 s_write_statusreg(uint8 *p_value)
//----------------------------------------------------------------------------------
// writes the status register with checksum (8-bit)
{ 
	uint8 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
}

//--------------------------------------------------------------------
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;
}


void SHT11Init()
{
      unsigned error=0;
      s_connectionreset();
      error+=s_write_byte(STATUS_REG_W);
      error+=s_write_byte(0x00);
      
      if(error!=0) 
      {
            s_connectionreset();                 //in case of an error: connection reset 
      }                    
}


/*名称:读取湿度                    */
/*输入:无                          */
/*返回:湿度值,数据是int型,湿度是 */
/*      从传感器读回来的值,未做处理*/
unsigned char ErrNum;
int read_rh(void)
{
  unsigned int ret_rh = 0x0000;
  unsigned char temp0 = 0x00;
  unsigned char temp1 = 0x00;
  unsigned long i;
  unsigned char flag;
  
  
      s_transstart();                   //transmission start
      s_write_byte(MEASURE_HUMI);
     
      SHT_DATA_In();
      //等待转换结束
      for(i=0;i<0xFFFFF0;i++)
      {
            flag = SHTXXIN & PinSDA;
            if(flag != PinSDA)
            {
                  i = 0xFFFFFF;
            break;
            }
      }
      flag = SHTXXIN & PinSDA;
      if(flag == PinSDA)
      {
            ErrNum ++; 
      }
            
      temp0  = s_read_byte(ACK);    //read the first byte (MSB)
      temp1  = s_read_byte(ACK);    //read the second byte (LSB)
      flag  = s_read_byte(noACK);
      
      ret_rh = (((unsigned int)(temp0 & 0x0F)) << 0x08) | ((unsigned int)temp1);
    
      return ret_rh;
}


/*名称:读取温度                     */
/*输入:无                           */
/*返回:温度值,数据是int型,温度是  */
/*      从传感器读回来的值,未做处理 */
int read_t(void)
{
  unsigned int ret_rh = 0x0000;
  unsigned char temp0 = 0x00;
  unsigned char temp1 = 0x00;
  unsigned long i;
  unsigned char flag;
  
  
  s_transstart();                   //transmission start
  //error += s_write_byte(MEASURE_TEMP);
      s_write_byte(MEASURE_TEMP);
             
      SHT_DATA_In();
      
      for(i=0;i<0xFFFFF0;i++)
      {
            flag = SHTXXIN & PinSDA;
            if(flag != PinSDA)
            {
                  i = 0xFFFFFF;
                  break;
            }
      }
      
      flag = SHTXXIN & PinSDA;
      if(flag == PinSDA)
      {
            ErrNum ++; 
      }
      
     
      
      temp0  = s_read_byte(ACK);     //read the first byte (MSB)
      temp1  = s_read_byte(ACK);     //read the second byte (LSB)
      flag  = s_read_byte(noACK);
      
      ret_rh = (((unsigned int)(temp0 & 0x3F)) << 0x08) | ((unsigned int)temp1);
      return ret_rh;
    
}



#define LBCS	5
float  TemperArrary[LBCS],RHArrary[LBCS];

void AddArry()
{
       //"向前推
        for(uchar i=0;i<(LBCS-1);i++)
        {
		TemperArrary[i] =     TemperArrary[i+1];
                    RHArrary[i]     =     RHArrary[i+1];
                    
        }
        
        TemperArrary[LBCS-1] = envionment_variables.temperature; 
        RHArrary[LBCS-1]     = envionment_variables.humidity;   
        
      uchar i;
      float sum=0;
      float max;
      float min;
      
        //"温度平均值
	max = min = TemperArrary[0];
	for(i=0;i<LBCS;i++)
	{
		if(max < TemperArrary[i])
		{
			max = TemperArrary[i];
		}
		else if(min > TemperArrary[i])
		{
			min = TemperArrary[i];
		}
		
		sum += TemperArrary[i];
	}
	sum -= max;
	sum -= min;
	sum /= LBCS-2;
	//envionment_variables.temperature = sum;
          envionment_variables.temperature = sum - envionment_variables.Zero_temperature; 
                              
          //"湿度平均值
	max = min = RHArrary[0];
	for(i=0;i<LBCS;i++)
	{
		if(max < RHArrary[i])
		{
			max = RHArrary[i];
		}
		else if(min > RHArrary[i])
		{
			min = RHArrary[i];
		}
		
		sum += RHArrary[i];
	}
	sum -= max;
	sum -= min;
	sum /= LBCS-2;
	//envionment_variables.humidity = sum;          
          envionment_variables.humidity  = sum - envionment_variables.Zero_humidity;        //湿度           

}



unsigned int TempAD;
void  MeasureSHT11Task()
{  
      unsigned int tem = 0x0000;
      unsigned int rh  = 0x0000;
      float rh_linear = 0.0;
      float rh_true = 0.0;
      float tem_true = 0.0;
      float dp = 0.0;
      
  
      ErrNum = 0 ;
      tem = read_t();
      rh  = read_rh();
      if(ErrNum != 0)   s_connectionreset();
     else
     {
            TempAD = tem;
            rh_linear = (0.0405 * (float)rh) + ((-2.8 * 0.000001) * rh * rh) - 4;
            tem_true  = (0.01 * (float)tem) - 39.64;
            rh_true   = ((float)tem_true - 25.0) * (0.01 + (0.00008 * (float)rh)) + rh_linear;
            dp =  calc_dewpoint(tem_true,rh_true);
      
           envionment_variables.temperature    =  tem_true;       //温度
           envionment_variables.humidity       = rh_true;        //湿度           
           envionment_variables.dew_point      = dp *100;
           if((envionment_variables.Zero_temperature > -10.0) && (envionment_variables.Zero_temperature < 10.0))
           {
                       envionment_variables.temperature    =  tem_true - envionment_variables.Zero_temperature;       //温度  
           }
           
           if((envionment_variables.Zero_humidity > -10.0) && (envionment_variables.Zero_humidity < 10.0))
           {
                       envionment_variables.humidity       = rh_true - envionment_variables.Zero_humidity;        //温度  
           }
            //envionment_variables.humidity       = rh_true - envionment_variables.Zero_humidity;        //湿度           
            //envionment_variables.dew_point      = dp ;
            
             //AddArry();
          // SHT_DATA_In();
           SHT_DATA_CLR();
                      
     }                                                
}
//=============================================================================================
//=============================================================================================


⌨️ 快捷键说明

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