stm32f103驱动SHT20( I2C )

2019-07-21 05:31发布

本帖最后由 mftang2016 于 2018-8-13 22:32 编辑

说明: 应用STM32驱动SHT20

I2C 部分驱动参考:http://www.openedv.com/forum.php?mod=viewthread&tid=100058

测试结果: 360截图20180813221625988.jpg

sht2x.c

[mw_shl_code=c,true]/** file

$Id: sht2x.c 40486 2018-08-12 13:50:21Z tangmingfei2013@126.com $

Copyright (c)tangmingfei2013@126.com Holding B.V.
All Rights Reserved.

This source code and any compilation or derivative thereof is the proprietary
information of mingfei.tang Lighting Holding B.V. and is confidential in nature.
Under no circumstances is this software to be combined with any
Open Source Software in any way or placed under an Open Source License
of any type without the express written permission of mingfei.tang Holding B.V.
*/

/*******************************************************************************
* EXPORT INCLUDE FILES
*******************************************************************************/
#include "I2C.h"
#include "Stm32hal.h"

/*******************************************************************************
* LOCAL INCLUDE FILES
*******************************************************************************/
#include "sht2x.h"

/******************************************************************************
* LOCAL MACROS AND DEFINITIONS
******************************************************************************/
#define I2C_ADDRESS (0x40 << 1)
#define POLY  0x131;  //P(x)=x^8+x^5+x^4+1 = 100110001

/******************************************************************************
* LOCAL FUNCTION DECLARATIONS
******************************************************************************/
static void i2c_Delay(uint16_t value );
static uint8_t sht2xdrv_CheckCrc(uint8_t data[], uint8_t nbrOfBytes, uint8_t checksum);
static uint8_t sht2xdrv_CheckOk(void);
static int32_t sht2xdrv_CalcTemperatureC(uint16_t u16sT);
static int32_t sht2xdrv_CalcRH(uint16_t u16sRH);

static void i2c_Delay(uint16_t value )
{
    uint16_t i;
    for (i = 0; i < value; i++);
}

static uint8_t sht2xdrv_CheckCrc(uint8_t data[], uint8_t nbrOfBytes, uint8_t checksum)
{
    uint8_t res = 0;
    uint8_t crc = 0;
    uint8_t byteCtr;
   
    //calculates 8-Bit checksum with given polynomial
    for (byteCtr = 0; byteCtr < nbrOfBytes; ++byteCtr)
    {
      crc ^= (data[byteCtr]);
      for (uint8_t bit = 8; bit > 0; --bit)
      {
        if (crc & 0x80)
        {
          crc = (crc << 1) ^ POLY;
        }
        else
        {
          crc = (crc << 1);
        }
      }
    }

    if (crc != checksum)
    {
      res = 1;
    }

    return res;
}

static uint8_t sht2xdrv_CheckOk(void)
{
    if (i2c_CheckDevice( I2C_ADDRESS ) == 0)
    {
         /* sensor is online*/
            return 1;
    }
    else
    {
          /* fail: send stop */
            i2c_Stop();
            return 0;
    }
}

static uint8_t sht2xdrv_ReadUserRegister( uint8_t *pRegisterValue )
{
    uint8_t ret = SHT2x_STATUS_OK;
    uint8_t cmd = USER_REG_R;
    i2c_Start();
   
    i2c_SendByte( I2C_ADDRESS | I2C_WR );  // Device address
    if (i2c_WaitAck() != 0)
    {
        goto cmd_fail;
    }
   
    i2c_SendByte( cmd);
    if (i2c_WaitAck() != 0)
    {
        goto cmd_fail;
    }
   
    //Read
    i2c_Start();
    i2c_SendByte(I2C_ADDRESS | I2C_RD);
    if (i2c_WaitAck() != 0)
    {
        goto cmd_fail;
    }
   
    *pRegisterValue = i2c_ReadByte();
    i2c_NAck();
   
    i2c_Stop();
    return ret;
   
cmd_fail:   
    i2c_Stop();
    ret = SHT2x_STATUS_ERR_BAD_DATA;
   
    return ret;
}

static int32_t sht2xdrv_CalcTemperatureC(uint16_t u16sT)
{
  int32_t temperatureC;       // variable for result

  u16sT &= ~0x0003;           // clear bits [1..0] (status bits)

  /*
     * Formula T = -46.85 + 175.72 * ST / 2^16 from data sheet 6.2,
     * optimized for integer fixed point (3 digits) arithmetic
  */

  temperatureC = (((uint32_t)17572 * u16sT) >> 16) - 4685;

  return (int32_t)temperatureC;
}

static int32_t sht2xdrv_CalcRH(uint16_t u16sRH)
{
  uint32_t humidityRH;       // variable for result

  u16sRH &= ~0x0003;          // clear bits [1..0] (status bits)

  /*
     * Formula RH = -6 + 125 * SRH / 2^16 from data sheet 6.1,
     * optimized for integer fixed point (3 digits) arithmetic
  */

  humidityRH = (((uint32_t)12500 * u16sRH) >> 16) - 600;

  return (int32_t)humidityRH;
}

uint8_t  sht2xdrv_GetTemp( int32_t *pMeasurand )
{
    uint8_t ret = SHT2x_STATUS_OK;
    uint8_t checksum;                   //checksum
    uint16_t rawdata;
    uint8_t cmd = TRIG_T_MEASUREMENT_HM;
    uint8_t data[3] = {0, 0, 0};        //data array for checksum v
   
    i2c_Start();
    i2c_SendByte( I2C_ADDRESS | I2C_WR );  // Device address
    if (i2c_WaitAck() != 0)
    {
        goto cmd_fail;
    }
   
    i2c_Delay( 100 );
    i2c_SendByte( cmd);
    if (i2c_WaitAck() != 0)
    {
        goto cmd_fail;
    }
   
    //Read
    i2c_Start();
    i2c_SendByte(I2C_ADDRESS | I2C_RD);
    if (i2c_WaitAck() != 0)
    {
        goto cmd_fail;
    }
   
    HAL_Delay( 70 );
    data[0] = i2c_ReadByte();
    i2c_Ack();        
    data[1] = i2c_ReadByte();
    i2c_Ack();        
    data[2] = i2c_ReadByte();
    i2c_NAck();
  
    i2c_Stop();
   
    rawdata = ((uint16_t)data[0] << 8) | data[1];
    checksum = data[2];

    ret = sht2xdrv_CheckCrc(data, 2, checksum);   
    if (ret != SHT2x_STATUS_OK)
    {
        return ret;
    }
    *pMeasurand = sht2xdrv_CalcTemperatureC(rawdata);
   
cmd_fail:
    i2c_Stop();
   
    return ret;
}

/******************************************************************************
* EXPORTED FUNCTIONS
******************************************************************************/
uint8_t  sht2xdrv_GetRH( int32_t *pMeasurand )
{
    uint8_t ret = SHT2x_STATUS_OK;
    uint8_t checksum;   //checksum
    uint16_t rawdata;
    uint8_t cmd = TRIG_RH_MEASUREMENT_POLL;
    uint8_t data[3] = {0, 0, 0}; //data array for checksum v
   
    i2c_Start();
    i2c_SendByte( I2C_ADDRESS | I2C_WR );  // Device address
    if (i2c_WaitAck() != 0)
    {
        goto cmd_fail;
    }
   
    i2c_SendByte( cmd);
    if (i2c_WaitAck() != 0)
    {
        goto cmd_fail;
    }
   
    //Read
    i2c_Start();
    HAL_Delay( 100 );
    i2c_SendByte(I2C_ADDRESS | I2C_RD);
    if (i2c_WaitAck() != 0)
    {
        goto cmd_fail;
    }
   
    HAL_Delay( 100 );
    data[0] = i2c_ReadByte();
    i2c_Ack();        
    data[1] = i2c_ReadByte();
    i2c_Ack();        
    data[2] = i2c_ReadByte();
    i2c_NAck();
     
    i2c_Stop();
   
    rawdata = ((uint16_t)data[0] << 8) | data[1];
    checksum = data[2];

    ret = sht2xdrv_CheckCrc(data, 2, checksum);   
    if (ret != SHT2x_STATUS_OK)
    {
        return ret;
    }
    *pMeasurand = sht2xdrv_CalcRH(rawdata);
   
cmd_fail:
    i2c_Stop();
   
    return ret;
}

uint8_t  sht2xdrv_ResetSht2x( void )
{
    uint8_t ret = SHT2x_STATUS_OK;
    uint8_t cmd = SOFT_RESET;
   
    i2c_Start();
    i2c_SendByte( I2C_ADDRESS | I2C_WR );  // Device address
    if (i2c_WaitAck() != 0)
    {
        goto cmd_fail;
    }
   
    i2c_SendByte( cmd);
    if (i2c_WaitAck() != 0)
    {
        goto cmd_fail;
    }
   
cmd_fail:
    i2c_Stop();
    ret = SHT2x_STATUS_ERR_TIMEOUT;
   
    return ret;
}

uint8_t  sht2xdrv_GetBatteryStatus(void)
{
  uint8_t reg;
  uint8_t error = SHT2x_STATUS_OK;

  error = sht2xdrv_ReadUserRegister(&#174;);

  if (error != SHT2x_STATUS_OK)
  {
    return error;
  }

  return (reg & 0x40);
}

uint8_t sht2xdrv_GetHeaterStatus(void)
{
  uint8_t reg;
  uint8_t error = SHT2x_STATUS_OK;

  error = sht2xdrv_ReadUserRegister(&#174;);

  if (error != SHT2x_STATUS_OK)
  {
    return error;
  }

  return (reg & 0x04);
}

uint8_t sht2xdrv_GetResolution(sht2xResolution_t *pResolution)
{
    uint8_t error = SHT2x_STATUS_OK;
    uint8_t reg = 0;

    error = sht2xdrv_ReadUserRegister(&#174;);
    if (error != SHT2x_STATUS_OK)
    {
        return error;
    }

    *pResolution = (sht2xResolution_t)(reg & SHT2x_RES_MASK);
    return error;
}

void sht2xdrv_Init( void )
{
    sht2xResolution_t sht2xResolutionvalue;
   
    sht2xdrv_CheckOk();
    sht2xdrv_GetBatteryStatus();   
    sht2xdrv_GetResolution( &sht2xResolutionvalue );
}

static int32_t s_TempData;
static int32_t s_RhData;
void SHT2X_test( void )
{  
    sht2xdrv_GetTemp( &s_TempData );
    sht2xdrv_GetRH( &s_RhData );
}

/* End of this file */[/mw_shl_code]

sht2x.h  文件:

[mw_shl_code=c,true]/** file

$Id: sht2x.h 40486 2018-08-12 13:50:21Z tangmingfei2013@126.com $

Copyright (c)tangmingfei2013@126.com Holding B.V.
All Rights Reserved.

This source code and any compilation or derivative thereof is the proprietary
information of mingfei.tang Lighting Holding B.V. and is confidential in nature.
Under no circumstances is this software to be combined with any
Open Source Software in any way or placed under an Open Source License
of any type without the express written permission of mingfei.tang Holding B.V.
*/
#ifndef __SHT2X_H
#define __SHT2X_H

/******************************************************************************
* C++ DECLARATION WRAPPER
******************************************************************************/

#ifdef __cplusplus
extern "C" {
#endif

/******************************************************************************
* EXPORTED MACROS AND DEFINITIONS
******************************************************************************/
typedef enum sht2xResolution_t
{
  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_t;

typedef enum sht2xStatusCode {
  SHT2x_STATUS_OK                = 0x00,
  SHT2x_STATUS_VALID_DATA        = 0x01,
  SHT2x_STATUS_NO_CHANGE         = 0x02,
  SHT2x_STATUS_ABORTED           = 0x03,
  SHT2x_STATUS_BUSY              = 0x04,
  SHT2x_STATUS_SUSPEND           = 0x05,
  SHT2x_STATUS_ERR_IO            = 0x06,
  SHT2x_STATUS_ERR_BAD_DATA      = 0x07,
  SHT2x_STATUS_ERR_TIMEOUT       = 0x08
}sht2xStatusCode;

// sensor command
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_t;

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

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.
} etSHT2xHeater;

// measurement signal selection
typedef enum{
  HUMIDITY,
  TEMP
}etSHT2xMeasureType;

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

/******************************************************************************
* EXPORTED FUNCTIONS
******************************************************************************/
uint8_t sht2xdrv_GetTemp( int32_t *pMeasurand );
uint8_t sht2xdrv_GetRH( int32_t *pMeasurand );
uint8_t sht2xdrv_ResetSht2x( void );
uint8_t sht2xdrv_GetBatteryStatus(void);
uint8_t sht2xdrv_GetHeaterStatus(void);
uint8_t sht2xdrv_GetResolution(sht2xResolution_t *pResolution);
void sht2xdrv_Init( void );

void SHT2X_test( void );
/******************************************************************************
* END OF C++ DECLARATION WRAPPER
******************************************************************************/

#ifdef __cplusplus
}
#endif

#endif /* __SHT2X_H */
[/mw_shl_code]

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
5条回答
mftang2016
1楼-- · 2019-07-21 06:35
硬件结构:
微信图片_20180813221917.jpg
ssssssssssss
2楼-- · 2019-07-21 07:18
压缩包呢
GAOSIY
3楼-- · 2019-07-21 12:45
 精彩回答 2  元偷偷看……
mftang2016
4楼-- · 2019-07-21 13:26
GAOSIY 发表于 2018-8-27 17:34
大佬,这个用的是GPIO软件模拟I2C吗

是的.................
andychen
5楼-- · 2019-07-21 18:36
优秀。。。大牛。

一周热门 更多>