SHT20温湿度传感器STM32单片机驱动程序源码

#ifndef __SHT2X_H
#define __SHT2X_H             

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#define CHECKSUM_ERROR 0x04

typedef enum{
  TRIG_T_MEASUREMENT_HM    = 0xE3, // command trig. temp meas. hold master
  TRIG_RH_MEASUREMENT_HM   = 0xE5, // command trig. humidity meas. hold master
  TRIG_T_MEASUREMENT_POLL  = 0xF3, // command trig. temp meas. no hold master
  TRIG_RH_MEASUREMENT_POLL = 0xF5, // command trig. humidity meas. no hold master
  USER_REG_W               = 0xE6, // command writing user register
  USER_REG_R               = 0xE7, // command reading user register
  SOFT_RESET               = 0xFE  // command soft reset
}SHT2xCommand;

typedef enum {
  SHT2x_RES_12_14BIT       = 0x00, // RH=12bit, T=14bit
  SHT2x_RES_8_12BIT        = 0x01, // RH= 8bit, T=12bit
  SHT2x_RES_10_13BIT       = 0x80, // RH=10bit, T=13bit
  SHT2x_RES_11_11BIT       = 0x81, // RH=11bit, T=11bit
  SHT2x_RES_MASK           = 0x81  // Mask for res. bits (7,0) in user reg.
} SHT2xResolution;

typedef enum {
  SHT2x_EOB_ON             = 0x40, // end of battery
  SHT2x_EOB_MASK           = 0x40, // Mask for EOB bit(6) in user reg.
} SHT2xEob;

typedef enum {
  SHT2x_HEATER_ON          = 0x04, // heater on
  SHT2x_HEATER_OFF         = 0x00, // heater off
  SHT2x_HEATER_MASK        = 0x04, // Mask for Heater bit(2) in user reg.
} SHT2xHeater;


typedef enum{
  HUMIDITY,
  TEMP
}SHT2xMeasureType;

typedef enum{
  I2C_ADR_W                = 128,   // sensor I2C address + write bit
  I2C_ADR_R                = 129    // sensor I2C address + read bit
}I2cHeader;

FunctionalState SHT2X_IIC_WriteByte(uint8_t WriteAddress,uint8_t SendByte);
FunctionalState SHT2X_IIC_ReadByte( uint8_t ReadAddress, uint16_t length  ,uint8_t* pBuffer);
FunctionalState SHT2x_CheckCrc(u8 data[],u8 startBytes,u8 number, u8 checksum);
u8 SHT2x_ReadUserRegister(void);
FunctionalState SHT2x_WriteUserRegister(u8 userdata);
FunctionalState SHT2x_SoftReset(void);
FunctionalState SHT2x_Calc_T(void);
FunctionalState SHT2x_Calc_RH(void);
u8 SHT2x_GetSerialNumber(u8 *pBuffer1,u8 *pBuffer2);
void SHT2X_TEST(void);
void SHT2X_Init(void);

#endif 
/*********************************************************************************************************
      END FILE
*********************************************************************************************************/
 

//头文件
#include "SHT2X.h"
#include "usart.h"
#include "math.h"
#include "i2c.h"


 float temperatureC;
 float humidityRH;
 
 u8 sndata1[8];
 u8 sndata2[6];
 u32 SN1; 
 u32 SN2; 

 /**
  * @file   Delay_us(不精确)
  * @brief  微妙延时 time_ms ms
  * @param  time_us 延时时间
  * @retval NO
  */
static void delay_us( uint16_t time_us )
{
  uint16_t i,j;
  for( i=0;i<time_us;i++ )
  {
        for( j=0;j<11;j++ );//1us
  }
}
 /**
  * @file   Delay_Ms(不精确)
  * @brief  毫秒延时 time_ms ms
  * @param  time_ms 延时时间
  * @retval NO
  */
static void delay_ms(uint16_t time_ms)
{
     uint16_t i,j;
  for( i=0;i<time_ms;i++ )
  {
        delay_us(11000);
  }
    
}
/**
  * @file   SHT2X_IIC_WriteByte
  * @brief  向SHT20写一字节数据
  * @param  
    *          - SendByte: 待写入数据
    *          - WriteAddress: 待写入地址
  * @retval 返回为:=1成功写入,=0失败
  */
FunctionalState SHT2X_IIC_WriteByte(uint8_t WriteAddress,uint8_t SendByte)
{        
    if(!I2C_Start())return DISABLE;
    I2C_SendByte(0x80); 
    if(!I2C_WaitAck()){I2C_Stop(); return DISABLE;}
    I2C_SendByte(WriteAddress);   /* 设置低起始地址 */      
    I2C_WaitAck();    
    I2C_SendByte(SendByte);
    I2C_WaitAck();   
    I2C_Stop(); 
    return ENABLE;
}    
 /**
  * @file   SHT2X_IIC_ReadByte
  * @brief  从SHT20读取一串数据
  * @param  
    *                    - pBuffer: 存放读出数据
    *           - length: 待读出长度
    *         - ReadAddress: 待读出地址
  * @retval 返回为:=1成功读入,=0失败
  */
FunctionalState SHT2X_IIC_ReadByte( uint8_t ReadAddress, uint16_t length  ,uint8_t* pBuffer)
{        
      if(!I2C_Start())return DISABLE;
    I2C_SendByte(0x80); /* 设置高起始地址+器件地址 */ 
    if(!I2C_WaitAck())
        {I2C_Stop(); return DISABLE;}
    I2C_SendByte(ReadAddress);   /* 设置低起始地址 */      
    I2C_WaitAck();
    I2C_Start();
    I2C_SendByte(0x81);
    I2C_WaitAck();
    while(length)
    {
            *pBuffer = I2C_ReceiveByte();
            if(length == 1)
            I2C_NoAck();
            else I2C_Ack(); 
            pBuffer++;
            length--;
    }
    I2C_Stop();
    return ENABLE;

 /**
  * @file   SHT2x_CheckCrc
  * @brief  calculates checksum for n bytes of data and compares it with expected
  * @param  
    *                    - data[]: 等待检验的数据
    *           - startByte: 开始数组的标号
    *         - nbrOfBytes: 检验个数
    *         - checksum: 接收到的CRC数据
  * @retval 返回为:=1检测成功,=0检测失败
  */
FunctionalState SHT2x_CheckCrc(u8 data[],u8 startBytes,u8 number, u8 checksum)
{
    u8 bit=0;
    u8 crc = 0;    
  u8 byteCtr;
  //calculates 8-Bit checksum with given polynomial
  for (byteCtr = startBytes; byteCtr < startBytes+number; ++byteCtr)
  { crc ^= (data[byteCtr]);
    for (bit = 8; bit > 0; --bit)
    { if (crc & 0x80) crc = (crc << 1) ^ 0x131;
      else crc = (crc << 1);
    }
  }
  if (crc ==checksum) 
    return ENABLE;
  else
    return DISABLE;
}
 /**
  * @file   SHT2x_ReadUserRegister
  * @brief  reads the SHT2x user register 
  * @param  no
  * @retval 返回读取到的参数值
  */
u8 SHT2x_ReadUserRegister(void)
{
    u8 data[1]={0};
  SHT2X_IIC_ReadByte( USER_REG_R, 1 ,data);
  return data[0];    
}
 /**
  * @file   SHT2x_WriteUserRegister
  * @brief  writes the SHT2x user register (8bit)
  * @param  userdata:要写的参数
  * @retval ENABLE:成功,DISABLE:失败
  */
FunctionalState SHT2x_WriteUserRegister(u8 userdata)
{
    SHT2X_IIC_WriteByte(USER_REG_W ,userdata);
    if(userdata==SHT2x_ReadUserRegister())
    return ENABLE;
    else 
    return DISABLE;
}

 /**
  * @file   SHT2x_Calc_T
  * @brief  计算温度
  * @param  NO
  * @retval 返回温度值
  */
FunctionalState SHT2x_Calc_T(void)
{
     u8 length=0;
     u8 Tdata[3]={0};
     if(!I2C_Start())return DISABLE;
    I2C_SendByte(I2C_ADR_W); 
    if(!I2C_WaitAck())
        {I2C_Stop(); return DISABLE;}
    I2C_SendByte(TRIG_T_MEASUREMENT_POLL);      
    I2C_WaitAck();
        delay_us(20);
      I2C_Stop();
        do
        {
        I2C_Start();
    I2C_SendByte(I2C_ADR_R);
        }
        while(!I2C_WaitAck());
        for(length=0;length<=3;length++)
        {
            Tdata[length]=I2C_ReceiveByte();
            I2C_Ack();         
        };
        I2C_NoAck();        
        I2C_Stop();        
        if(((Tdata[0]+Tdata[1]+Tdata[2])>0)&&SHT2x_CheckCrc(Tdata,0,2,Tdata[2]))    
    temperatureC= (-46.85 + (175.72/65536 )*((float)((((u16)Tdata[0]<<8)+(u16)Tdata[1])&0xfffc)));
        else
        return DISABLE;
      return ENABLE;
}


 /**
  * @file   SHT2x_Calc_RH
  * @brief  计算湿度
  * @param  NO
  * @retval 返回湿度值
  */
FunctionalState SHT2x_Calc_RH(void)
{    
   u8 length=0;
     u8 RHdata[3]={0};
     if(!I2C_Start())return DISABLE;
    I2C_SendByte(I2C_ADR_W); 
    if(!I2C_WaitAck())
        {I2C_Stop(); return DISABLE;}
    I2C_SendByte(TRIG_RH_MEASUREMENT_POLL);      
    I2C_WaitAck();
        delay_us(20);
      I2C_Stop();
        do
        {
        I2C_Start();
    I2C_SendByte(I2C_ADR_R);
        }
        while(!I2C_WaitAck());
        for(length=0;length<=3;length++)
        {
            RHdata[length]=I2C_ReceiveByte();
            I2C_Ack();         
        };
        I2C_NoAck();        
        I2C_Stop();
        if(((RHdata[0]+RHdata[1]+RHdata[2])>0)&&SHT2x_CheckCrc(RHdata,0,2,RHdata[2]))        
      humidityRH = -6.0 + 125.0/65536 * ((float)((((u16)RHdata[0]<<8)+(u16)RHdata[1])&0xfff0)); 
        else
        return DISABLE;
      return ENABLE;
}
 /**
  * @file   SHT2x_SoftReset
  * @brief  软件复位
  * @param  NO
  * @retval NO
  */
FunctionalState SHT2x_SoftReset(void)
{
     if(!I2C_Start())return DISABLE;
    I2C_SendByte(0x80); 
    if(!I2C_WaitAck()){I2C_Stop(); return DISABLE;}
    I2C_SendByte(SOFT_RESET);       
    I2C_WaitAck();      
    I2C_Stop(); 
      delay_ms(1500);
        return ENABLE;    
}

 /**
  * @file   SHT2x_GetSerialNumber
  * @brief  得到SHT20的序列号
  * @param  
  * @retval 
  */
u8 SHT2x_GetSerialNumber(u8 *pBuffer1,u8 *pBuffer2)
{   u8 length=8;
      if(!I2C_Start())return DISABLE;
    I2C_SendByte(0x80); 
    if(!I2C_WaitAck()){I2C_Stop(); return DISABLE;}
    I2C_SendByte(0xfa);       
    I2C_WaitAck();    
    I2C_SendByte(0x0f);
    I2C_WaitAck();   
        if(!I2C_Start())return DISABLE;
    I2C_SendByte(0x81); 
    if(!I2C_WaitAck()){I2C_Stop(); return DISABLE;}
    while(length)
    {
      *pBuffer1 = I2C_ReceiveByte();
      if(length == 1)
                I2C_NoAck();
      else I2C_Ack(); 
      pBuffer1++;
      length--;
    }
     I2C_Stop();
        length=6;
      if(!I2C_Start())return DISABLE;
    I2C_SendByte(0x80); 
    if(!I2C_WaitAck()){I2C_Stop(); return DISABLE;}
    I2C_SendByte(0xfc);     
    I2C_WaitAck();    
    I2C_SendByte(0xc9);
    I2C_WaitAck();   
        if(!I2C_Start())return DISABLE;
    I2C_SendByte(0x81); 
    if(!I2C_WaitAck()){I2C_Stop(); return DISABLE;}
    while(length)
    {
      *pBuffer2 = I2C_ReceiveByte();
      if(length == 1)
                I2C_NoAck();
      else I2C_Ack(); 
      pBuffer2++;
      length--;
    }
     I2C_Stop();    
    return ENABLE;
}
 /**
  * @file   SHT2X_Init
  * @brief  SHT20初始化
  * @param  NO
  * @retval NO
  */
void SHT2X_Init(void)
{
        SHT2x_GetSerialNumber(sndata1,sndata2);
        if((sndata1[0]+sndata1[1]+sndata1[3]+sndata1[4]+sndata1[5]+sndata1[6]+sndata1[7])>0)
        {        
        if(
        SHT2x_CheckCrc(sndata1,0,1,sndata1[1])&&
        SHT2x_CheckCrc(sndata1,2,1,sndata1[3])&&
        SHT2x_CheckCrc(sndata1,4,1,sndata1[5])&&
        SHT2x_CheckCrc(sndata1,6,1,sndata1[7])&&
        SHT2x_CheckCrc(sndata2,0,2,sndata2[2])&&
        SHT2x_CheckCrc(sndata2,3,2,sndata2[5])
        )
        {
        printf("SHT2X CRC ok\r\n");
        SN1=((sndata2[3]<<24)+(sndata2[4]<<16)+(sndata1[0]<<8)+sndata1[2]);
        SN2=((sndata1[4]<<24)+(sndata1[6]<<16)+(sndata2[0]<<8)+sndata2[1]);
        printf("SHT2X SN:0x%x%x\r\n",SN1,SN2);
        }
        else
        printf("SHT2X CRC error\r\n");    
        }
        else
        {
        SHT2x_GetSerialNumber(sndata1,sndata2);
        printf("SHT2X通信错误\r\n");
        };

        if(SHT2x_WriteUserRegister(0x3a))
        printf("设置成功\r\n");
        else 
        printf("设置错误\r\n");
}
 /**
  * @file   SHT2X_TEST
  * @brief  SHT20测试
  * @param  NO
  * @retval NO
  */
void SHT2X_TEST(void)
{
        if(SHT2x_Calc_T())
        { 
             printf("温度:%f\r\n",temperatureC);
           //OLED_shuji(38,17,(s8)(temperatureC));
        }
    /*湿度测试*/
        if(SHT2x_Calc_RH())
        {
            printf("湿度:%f%%\r\n",humidityRH);
        }
    

}

  • 12
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GJZGRB

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值