高级会员
- 积分
- 563
- 金钱
- 563
- 注册时间
- 2016-9-28
- 在线时间
- 158 小时
|
本帖最后由 mftang2016 于 2024-1-18 15:35 编辑
说明: 应用STM32驱动SHT20
I2C 部分驱动参考:http://www.openedv.com/forum.php?mod=viewthread&tid=100058
测试结果:
sht2x.c
- /*******************************************************************************
- * 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
- #define DELAY_CNT 4500 //for N32G45, sleep time is 6.4 ms
- static shtOpt s_ShtOpt;
- /******************************************************************************
- * 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;
- // write address
- 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 register value
- 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_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;
- }
- static void sht2xdrv_readVal(uint8_t cmd, shtdrv *pShtdrv )
- {
- uint8_t checksum; //checksum
- uint8_t data[3] = {0, 0, 0}; //data array for checksum v
- uint8_t cmd_fail = 0;
-
- if( pShtdrv->finish )
- return;
-
- pShtdrv->ret = SHT2x_STATUS_ERR_BAD_DATA;
- switch( pShtdrv->_step )
- {
- default:
- case 0:
- i2c_Start();
- i2c_SendByte( I2C_ADDRESS | I2C_WR ); // Device address
- if (i2c_WaitAck() != 0)
- {
- cmd_fail = 1;
- break;
- }
- pShtdrv->_step = 1;
- break;
-
- case 1:
- // send command and prepare to reading data value
- i2c_SendByte( cmd);
- if (i2c_WaitAck() != 0)
- {
- cmd_fail = 1;
- break;
- }
- pShtdrv->_step = 2;
- pShtdrv->_tryCnt = 0;
- break;
-
- case 2:
- // set the address for reading data
- i2c_Start();
- i2c_SendByte(I2C_ADDRESS | I2C_RD);
- if (i2c_WaitAck() != 0)
- {
- pShtdrv->_tryCnt ++;
- if( pShtdrv->_tryCnt > 10 )
- {
- cmd_fail = 1;
- break;
- }
- }
- pShtdrv->_step = 3;
- pShtdrv->_tryCnt = 0;
- break;
-
- case 3:
- // Notes: convert time must >= 4 ms
- i2c_Delay( 3 );
- pShtdrv->_tryCnt ++;
- if( pShtdrv->_tryCnt > 4500 )
- {
- pShtdrv->_tryCnt = 0;
- pShtdrv->_step = 4;
- }
- break;
-
- case 4:
- // read sensor's data
- data[0] = i2c_ReadByte();
- i2c_Ack();
-
- data[1] = i2c_ReadByte();
- i2c_Ack();
-
- data[2] = i2c_ReadByte();
- i2c_NAck();
- i2c_Stop();
-
- checksum = data[2];
- pShtdrv->ret = sht2xdrv_CheckCrc(data, 2, checksum);
-
- if ( pShtdrv->ret != SHT2x_STATUS_OK)
- {
- pShtdrv->_step = 2;
- break;
- }
-
- pShtdrv->_binValue = ((uint16_t)data[0] << 8) | data[1];
- pShtdrv->_step = 0;
- pShtdrv->finish = 1;
- break;
- }
-
- if( cmd_fail )
- {
- pShtdrv->finish = 1;
- pShtdrv->_tryCnt =0;
- pShtdrv->_step = 0;
- pShtdrv->ret = SHT2x_STATUS_ERR_BAD_DATA;
- i2c_Stop();
- }
- }
- static void sht2xdrv_readTempOrRH( uint8_t cmd, shtdrv *pShtdrv )
- {
- switch( cmd )
- {
- case TRIG_T_MEASUREMENT_HM:
- sht2xdrv_readVal(cmd, pShtdrv);
- if( pShtdrv->ret == SHT2x_STATUS_OK)
- {
- pShtdrv->outValue = sht2xdrv_CalcTemperatureC( pShtdrv->_binValue );
- pShtdrv->dataValid = 1;
- }
- break;
-
- case TRIG_RH_MEASUREMENT_POLL:
- sht2xdrv_readVal(cmd, pShtdrv);
- if( pShtdrv->ret == SHT2x_STATUS_OK)
- {
- pShtdrv->outValue = sht2xdrv_CalcRH( pShtdrv->_binValue );
- pShtdrv->dataValid = 1;
- }
- break;
- }
- }
- static void _sht2xdrv_Init( shtOpt *pshtOpt )
- {
- sht2xResolution_t sht2xResolutionvalue;
-
- uint8_t _res = sht2xdrv_CheckOk();
- if( _res )
- {
- sht2xdrv_ResetSht2x();
- sht2xdrv_GetBatteryStatus();
- sht2xdrv_GetResolution( &sht2xResolutionvalue );
- return;
- }
-
- pshtOpt->errorCode |= SHT2x_RES_I2C_ERR;
- }
- /******************************************************************************
- * EXPORTED FUNCTIONS
- ******************************************************************************/
- void sht2xdrv_Init( void )
- {
- _sht2xdrv_Init( &s_ShtOpt );
- }
- shtOpt *sht2xdrv_getResult( void )
- {
- return &s_ShtOpt;
- }
- void sht2xdrv_ClearReadFlag( shtdrv *pShtdrv )
- {
- pShtdrv->dataValid = 0;
- }
- void sht2xdrv_readValue( shtOpt *pshtOpt )
- {
- static uint8_t _step = TRIG_T_MEASUREMENT_HM;
- shtdrv *pTempData = &pshtOpt->st_Temp;
- shtdrv *pRhData = &pshtOpt->st_RH;
-
- if( pshtOpt ->errorCode & SHT2x_RES_I2C_ERR )
- return;
-
- switch ( _step )
- {
- default:
- case TRIG_T_MEASUREMENT_HM:
- sht2xdrv_readTempOrRH( TRIG_T_MEASUREMENT_HM,pTempData );
- if( pTempData->finish )
- {
- _step = TRIG_RH_MEASUREMENT_POLL;
- pTempData->finish = 0;
- }
- break;
- case TRIG_RH_MEASUREMENT_POLL:
- sht2xdrv_readTempOrRH( TRIG_RH_MEASUREMENT_POLL, pRhData);
- if( pRhData->finish )
- {
- _step = TRIG_T_MEASUREMENT_HM;
- pRhData->finish = 0;
- }
- break;
- }
- }
- void SHT2X_test( void )
- {
- sht2xdrv_readValue( &s_ShtOpt );
- }
- /* End of this file */
复制代码
sht2x.h
- #ifndef __SHT2X_H
- #define __SHT2X_H
- /******************************************************************************
- * C++ DECLARATION WRAPPER
- ******************************************************************************/
- #ifdef __cplusplus
- extern "C" {
- #endif
- typedef enum sht2xOptErrorCode
- {
- SHT2x_RES_I2C_ERR = 0X01,
- }sht2xOptErrorCode;
- /******************************************************************************
- * 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;
- typedef struct {
- uint8_t _step;
- uint8_t ret;
-
- uint8_t finish; //1: finished, 0: idle
- uint8_t dataValid; //1: valid, 0: invalid
-
- int32_t _tryCnt;
- int32_t _binValue; // primordial value from sht20 register
- int32_t outValue; // true temperature or humidity
- } shtdrv;
- typedef struct {
- shtdrv st_Temp;
- shtdrv st_RH;
- int32_t errorCode;
- }shtOpt;
- /******************************************************************************
- * EXPORTED FUNCTIONS
- ******************************************************************************/
- void sht2xdrv_Init( void );
- void sht2xdrv_readValue( shtOpt *pshtOpt );
- shtOpt *sht2xdrv_getResult( void );
- void SHT2X_test( void );
- /******************************************************************************
- * END OF C++ DECLARATION WRAPPER
- ******************************************************************************/
- #ifdef __cplusplus
- }
- #endif
- #endif /* __SHT2X_H */
复制代码
|
|