OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 8036|回复: 13

stm32f103驱动SHT20( I2C )

[复制链接]

44

主题

187

帖子

0

精华

高级会员

Rank: 4

积分
563
金钱
563
注册时间
2016-9-28
在线时间
158 小时
发表于 2018-8-13 22:14:30 | 显示全部楼层 |阅读模式
本帖最后由 mftang2016 于 2024-1-18 15:35 编辑

说明: 应用STM32驱动SHT20

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

测试结果: 360截图20180813221625988.jpg

sht2x.c
  1. /*******************************************************************************
  2. * LOCAL INCLUDE FILES
  3. *******************************************************************************/
  4. #include "sht2x.h"

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

  10. #define DELAY_CNT            4500          //for N32G45, sleep time is 6.4 ms

  11. static shtOpt s_ShtOpt;
  12. /******************************************************************************
  13. * LOCAL FUNCTION DECLARATIONS
  14. ******************************************************************************/
  15. static void i2c_Delay(uint16_t value );
  16. static uint8_t sht2xdrv_CheckCrc(uint8_t data[], uint8_t nbrOfBytes, uint8_t checksum);
  17. static uint8_t sht2xdrv_CheckOk(void);
  18. static int32_t sht2xdrv_CalcTemperatureC(uint16_t u16sT);
  19. static int32_t sht2xdrv_CalcRH(uint16_t u16sRH);

  20. static void i2c_Delay(uint16_t value )
  21. {
  22.     uint16_t i;
  23.     for (i = 0; i < value; i++);
  24. }

  25. static uint8_t sht2xdrv_CheckCrc(uint8_t data[], uint8_t nbrOfBytes, uint8_t checksum)
  26. {
  27.     uint8_t res = 0;
  28.     uint8_t crc = 0;
  29.     uint8_t byteCtr;
  30.    
  31.     //calculates 8-Bit checksum with given polynomial
  32.     for (byteCtr = 0; byteCtr < nbrOfBytes; ++byteCtr)
  33.     {
  34.       crc ^= (data[byteCtr]);
  35.       for (uint8_t bit = 8; bit > 0; --bit)
  36.       {
  37.         if (crc & 0x80)
  38.         {
  39.           crc = (crc << 1) ^ POLY;
  40.         }
  41.         else
  42.         {
  43.           crc = (crc << 1);
  44.         }
  45.       }
  46.     }

  47.     if (crc != checksum)
  48.     {
  49.       res = 1;
  50.     }

  51.     return res;
  52. }

  53. static uint8_t sht2xdrv_CheckOk(void)
  54. {
  55.     if (i2c_CheckDevice( I2C_ADDRESS ) == 0)
  56.     {
  57.          /* sensor is online*/
  58.             return 1;
  59.     }
  60.     else
  61.     {
  62.           /* fail: send stop */
  63.             i2c_Stop();
  64.             return 0;
  65.     }
  66. }

  67. static uint8_t sht2xdrv_ReadUserRegister( uint8_t *pRegisterValue )
  68. {
  69.     uint8_t ret = SHT2x_STATUS_OK;
  70.     uint8_t cmd = USER_REG_R;

  71.     // write address
  72.     i2c_Start();
  73.     i2c_SendByte( I2C_ADDRESS | I2C_WR );  // Device address
  74.     if (i2c_WaitAck() != 0)
  75.     {
  76.         goto cmd_fail;
  77.     }
  78.    
  79.     i2c_SendByte( cmd);
  80.     if (i2c_WaitAck() != 0)
  81.     {
  82.         goto cmd_fail;
  83.     }
  84.    
  85.     //Read register value
  86.     i2c_Start();
  87.     i2c_SendByte(I2C_ADDRESS | I2C_RD);
  88.     if (i2c_WaitAck() != 0)
  89.     {
  90.         goto cmd_fail;
  91.     }
  92.    
  93.     *pRegisterValue = i2c_ReadByte();
  94.     i2c_NAck();
  95.    
  96.     i2c_Stop();
  97.     return ret;
  98.    
  99. cmd_fail:   
  100.     i2c_Stop();
  101.     ret = SHT2x_STATUS_ERR_BAD_DATA;
  102.    
  103.     return ret;
  104. }

  105. static int32_t sht2xdrv_CalcTemperatureC(uint16_t u16sT)
  106. {
  107.   int32_t temperatureC;       // variable for result

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

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

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

  114.   return (int32_t)temperatureC;
  115. }

  116. static int32_t sht2xdrv_CalcRH(uint16_t u16sRH)
  117. {
  118.   uint32_t humidityRH;       // variable for result

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

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

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

  125.   return (int32_t)humidityRH;
  126. }

  127. uint8_t  sht2xdrv_ResetSht2x( void )
  128. {
  129.     uint8_t ret = SHT2x_STATUS_OK;
  130.     uint8_t cmd = SOFT_RESET;
  131.    
  132.     i2c_Start();
  133.     i2c_SendByte( I2C_ADDRESS | I2C_WR );  // Device address
  134.     if (i2c_WaitAck() != 0)
  135.     {
  136.         goto cmd_fail;
  137.     }
  138.    
  139.     i2c_SendByte( cmd);
  140.     if (i2c_WaitAck() != 0)
  141.     {
  142.         goto cmd_fail;
  143.     }
  144.    
  145. cmd_fail:
  146.     i2c_Stop();
  147.     ret = SHT2x_STATUS_ERR_TIMEOUT;
  148.    
  149.     return ret;
  150. }

  151. uint8_t  sht2xdrv_GetBatteryStatus(void)
  152. {
  153.   uint8_t reg;
  154.   uint8_t error = SHT2x_STATUS_OK;

  155.   error = sht2xdrv_ReadUserRegister(&174;);

  156.   if (error != SHT2x_STATUS_OK)
  157.   {
  158.     return error;
  159.   }

  160.   return (reg & 0x40);
  161. }

  162. uint8_t sht2xdrv_GetHeaterStatus(void)
  163. {
  164.   uint8_t reg;
  165.   uint8_t error = SHT2x_STATUS_OK;

  166.   error = sht2xdrv_ReadUserRegister(&174;);

  167.   if (error != SHT2x_STATUS_OK)
  168.   {
  169.     return error;
  170.   }

  171.   return (reg & 0x04);
  172. }

  173. uint8_t sht2xdrv_GetResolution(sht2xResolution_t *pResolution)
  174. {
  175.     uint8_t error = SHT2x_STATUS_OK;
  176.     uint8_t reg = 0;

  177.     error = sht2xdrv_ReadUserRegister(&174;);
  178.     if (error != SHT2x_STATUS_OK)
  179.     {
  180.         return error;
  181.     }

  182.     *pResolution = (sht2xResolution_t)(reg & SHT2x_RES_MASK);
  183.     return error;
  184. }


  185. static void sht2xdrv_readVal(uint8_t cmd, shtdrv *pShtdrv )
  186. {
  187.     uint8_t checksum;                   //checksum
  188.     uint8_t data[3] = {0, 0, 0};        //data array for checksum v
  189.     uint8_t cmd_fail = 0;
  190.    
  191.     if(  pShtdrv->finish )
  192.          return;
  193.    
  194.     pShtdrv->ret = SHT2x_STATUS_ERR_BAD_DATA;
  195.     switch( pShtdrv->_step )
  196.     {
  197.         default:
  198.         case 0:
  199.             i2c_Start();
  200.             i2c_SendByte( I2C_ADDRESS | I2C_WR );  // Device address
  201.             if (i2c_WaitAck() != 0)
  202.             {
  203.                 cmd_fail = 1;
  204.                 break;
  205.             }
  206.             pShtdrv->_step = 1;
  207.             break;
  208.             
  209.         case 1:
  210.             // send command and prepare to reading data value
  211.             i2c_SendByte( cmd);
  212.             if (i2c_WaitAck() != 0)
  213.             {
  214.                 cmd_fail = 1;
  215.                 break;
  216.             }
  217.             pShtdrv->_step = 2;
  218.             pShtdrv->_tryCnt = 0;
  219.             break;
  220.             
  221.         case 2:
  222.            // set the address for reading data
  223.             i2c_Start();
  224.             i2c_SendByte(I2C_ADDRESS | I2C_RD);
  225.             if (i2c_WaitAck() != 0)
  226.             {
  227.                 pShtdrv->_tryCnt ++;
  228.                 if( pShtdrv->_tryCnt > 10 )
  229.                 {
  230.                     cmd_fail = 1;
  231.                     break;
  232.                 }
  233.             }
  234.             pShtdrv->_step = 3;
  235.             pShtdrv->_tryCnt = 0;
  236.             break;
  237.             
  238.         case 3:
  239.             // Notes: convert time must >= 4 ms
  240.             i2c_Delay( 3 );
  241.             pShtdrv->_tryCnt ++;
  242.             if( pShtdrv->_tryCnt > 4500 )
  243.             {
  244.                 pShtdrv->_tryCnt = 0;
  245.                 pShtdrv->_step = 4;
  246.             }
  247.             break;
  248.         
  249.         case 4:
  250.             // read sensor's data
  251.             data[0] = i2c_ReadByte();
  252.             i2c_Ack();
  253.             
  254.             data[1] = i2c_ReadByte();
  255.             i2c_Ack();
  256.             
  257.             data[2] = i2c_ReadByte();
  258.             i2c_NAck();

  259.             i2c_Stop();
  260.             
  261.             checksum = data[2];
  262.             pShtdrv->ret = sht2xdrv_CheckCrc(data, 2, checksum);
  263.          
  264.             if ( pShtdrv->ret != SHT2x_STATUS_OK)
  265.             {
  266.                 pShtdrv->_step = 2;
  267.                 break;
  268.             }
  269.             
  270.             pShtdrv->_binValue = ((uint16_t)data[0] << 8) | data[1];
  271.             pShtdrv->_step = 0;
  272.             pShtdrv->finish = 1;
  273.             break;
  274.     }
  275.    
  276.     if( cmd_fail )
  277.     {
  278.         pShtdrv->finish = 1;
  279.         pShtdrv->_tryCnt =0;
  280.         pShtdrv->_step = 0;
  281.         pShtdrv->ret = SHT2x_STATUS_ERR_BAD_DATA;
  282.         i2c_Stop();
  283.     }
  284. }

  285. static void sht2xdrv_readTempOrRH(  uint8_t cmd, shtdrv *pShtdrv )
  286. {
  287.     switch( cmd )
  288.     {
  289.         case  TRIG_T_MEASUREMENT_HM:
  290.              sht2xdrv_readVal(cmd, pShtdrv);
  291.              if( pShtdrv->ret == SHT2x_STATUS_OK)
  292.              {
  293.                 pShtdrv->outValue = sht2xdrv_CalcTemperatureC( pShtdrv->_binValue );
  294.                 pShtdrv->dataValid = 1;
  295.              }
  296.             break;
  297.             
  298.         case  TRIG_RH_MEASUREMENT_POLL:
  299.              sht2xdrv_readVal(cmd, pShtdrv);
  300.              if( pShtdrv->ret == SHT2x_STATUS_OK)
  301.              {
  302.                 pShtdrv->outValue = sht2xdrv_CalcRH( pShtdrv->_binValue );
  303.                 pShtdrv->dataValid = 1;
  304.              }
  305.             break;
  306.     }
  307. }


  308. static void _sht2xdrv_Init( shtOpt *pshtOpt )
  309. {
  310.     sht2xResolution_t sht2xResolutionvalue;
  311.    
  312.     uint8_t _res = sht2xdrv_CheckOk();
  313.     if( _res )
  314.     {
  315.         sht2xdrv_ResetSht2x();
  316.         sht2xdrv_GetBatteryStatus();
  317.         sht2xdrv_GetResolution( &sht2xResolutionvalue );
  318.         return;
  319.     }
  320.    
  321.     pshtOpt->errorCode |= SHT2x_RES_I2C_ERR;
  322. }

  323. /******************************************************************************
  324. * EXPORTED FUNCTIONS
  325. ******************************************************************************/
  326. void sht2xdrv_Init( void )
  327. {
  328.    _sht2xdrv_Init( &s_ShtOpt );
  329. }

  330. shtOpt *sht2xdrv_getResult( void )
  331. {
  332.       return &s_ShtOpt;
  333. }

  334. void sht2xdrv_ClearReadFlag( shtdrv *pShtdrv )
  335. {
  336.     pShtdrv->dataValid = 0;
  337. }

  338. void sht2xdrv_readValue( shtOpt *pshtOpt )
  339. {
  340.     static uint8_t _step = TRIG_T_MEASUREMENT_HM;
  341.     shtdrv *pTempData = &pshtOpt->st_Temp;
  342.     shtdrv *pRhData = &pshtOpt->st_RH;
  343.    
  344.     if( pshtOpt ->errorCode & SHT2x_RES_I2C_ERR )
  345.         return;
  346.    
  347.     switch ( _step )
  348.     {
  349.         default:
  350.         case TRIG_T_MEASUREMENT_HM:
  351.             sht2xdrv_readTempOrRH( TRIG_T_MEASUREMENT_HM,pTempData );
  352.             if( pTempData->finish )
  353.             {
  354.                _step = TRIG_RH_MEASUREMENT_POLL;
  355.                pTempData->finish  = 0;
  356.             }
  357.             break;
  358.         case TRIG_RH_MEASUREMENT_POLL:
  359.             sht2xdrv_readTempOrRH( TRIG_RH_MEASUREMENT_POLL, pRhData);
  360.             if( pRhData->finish )
  361.             {
  362.                _step = TRIG_T_MEASUREMENT_HM;
  363.                pRhData->finish  = 0;
  364.             }
  365.             break;
  366.     }
  367. }


  368. void SHT2X_test( void )
  369. {
  370.     sht2xdrv_readValue( &s_ShtOpt );
  371. }


  372. /* End of this file */

复制代码

sht2x.h
  1. #ifndef __SHT2X_H
  2. #define __SHT2X_H

  3. /******************************************************************************
  4. * C++ DECLARATION WRAPPER
  5. ******************************************************************************/

  6. #ifdef __cplusplus
  7. extern "C" {
  8. #endif

  9. typedef enum sht2xOptErrorCode
  10. {
  11.     SHT2x_RES_I2C_ERR = 0X01,
  12. }sht2xOptErrorCode;

  13. /******************************************************************************
  14. * EXPORTED MACROS AND DEFINITIONS
  15. ******************************************************************************/
  16. typedef enum sht2xResolution_t
  17. {
  18.   SHT2x_RES_12_14BIT       = 0x00, // RH=12bit, T=14bit
  19.   SHT2x_RES_8_12BIT        = 0x01, // RH= 8bit, T=12bit
  20.   SHT2x_RES_10_13BIT       = 0x80, // RH=10bit, T=13bit
  21.   SHT2x_RES_11_11BIT       = 0x81, // RH=11bit, T=11bit
  22.   SHT2x_RES_MASK           = 0x81  // Mask for res. bits (7,0) in user reg.
  23. } sht2xResolution_t;

  24. typedef enum sht2xStatusCode {
  25.   SHT2x_STATUS_OK                = 0x00,
  26.   SHT2x_STATUS_VALID_DATA        = 0x01,
  27.   SHT2x_STATUS_NO_CHANGE         = 0x02,
  28.   SHT2x_STATUS_ABORTED           = 0x03,
  29.   SHT2x_STATUS_BUSY              = 0x04,
  30.   SHT2x_STATUS_SUSPEND           = 0x05,
  31.   SHT2x_STATUS_ERR_IO            = 0x06,
  32.   SHT2x_STATUS_ERR_BAD_DATA      = 0x07,
  33.   SHT2x_STATUS_ERR_TIMEOUT       = 0x08
  34. }sht2xStatusCode;

  35. // sensor command
  36. typedef enum{
  37.   TRIG_T_MEASUREMENT_HM    = 0xE3, // command trig. temp meas. hold master
  38.   TRIG_RH_MEASUREMENT_HM   = 0xE5, // command trig. humidity meas. hold master
  39.   TRIG_T_MEASUREMENT_POLL  = 0xF3, // command trig. temp meas. no hold master
  40.   TRIG_RH_MEASUREMENT_POLL = 0xF5, // command trig. humidity meas. no hold master
  41.   USER_REG_W               = 0xE6, // command writing user register
  42.   USER_REG_R               = 0xE7, // command reading user register
  43.   SOFT_RESET               = 0xFE  // command soft reset
  44. }sht2xCommand_t;

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

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

  54. // measurement signal selection
  55. typedef enum{
  56.   HUMIDITY,
  57.   TEMP
  58. }etSHT2xMeasureType;

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


  63. typedef struct {
  64.     uint8_t _step;
  65.     uint8_t ret;
  66.    
  67.     uint8_t finish;     //1: finished, 0: idle
  68.     uint8_t dataValid;  //1: valid, 0: invalid
  69.    
  70.     int32_t _tryCnt;
  71.     int32_t _binValue;   // primordial value from sht20 register
  72.     int32_t outValue;    // true temperature or humidity
  73. } shtdrv;

  74. typedef struct {
  75.     shtdrv st_Temp;
  76.     shtdrv st_RH;
  77.     int32_t errorCode;
  78. }shtOpt;

  79. /******************************************************************************
  80. * EXPORTED FUNCTIONS
  81. ******************************************************************************/
  82. void sht2xdrv_Init( void );
  83. void sht2xdrv_readValue( shtOpt *pshtOpt );
  84. shtOpt *sht2xdrv_getResult( void );

  85. void SHT2X_test( void );
  86. /******************************************************************************
  87. * END OF C++ DECLARATION WRAPPER
  88. ******************************************************************************/

  89. #ifdef __cplusplus
  90. }
  91. #endif

  92. #endif /* __SHT2X_H */
复制代码


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

44

主题

187

帖子

0

精华

高级会员

Rank: 4

积分
563
金钱
563
注册时间
2016-9-28
在线时间
158 小时
 楼主| 发表于 2018-8-13 22:22:01 | 显示全部楼层
回复 支持 反对

使用道具 举报

160

主题

966

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2095
金钱
2095
注册时间
2014-3-7
在线时间
490 小时
发表于 2018-8-14 08:48:13 | 显示全部楼层
压缩包呢
回复 支持 反对

使用道具 举报

6

主题

55

帖子

0

精华

初级会员

Rank: 2

积分
96
金钱
96
注册时间
2018-8-23
在线时间
12 小时
发表于 2018-8-27 17:34:32 | 显示全部楼层
大佬,这个用的是GPIO软件模拟I2C吗
回复 支持 反对

使用道具 举报

44

主题

187

帖子

0

精华

高级会员

Rank: 4

积分
563
金钱
563
注册时间
2016-9-28
在线时间
158 小时
 楼主| 发表于 2018-8-27 22:13:56 | 显示全部楼层
GAOSIY 发表于 2018-8-27 17:34
大佬,这个用的是GPIO软件模拟I2C吗

是的.................
回复 支持 反对

使用道具 举报

19

主题

97

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
313
金钱
313
注册时间
2017-9-5
在线时间
78 小时
发表于 2019-1-27 13:25:52 | 显示全部楼层
优秀。。。大牛。
回复 支持 反对

使用道具 举报

1

主题

4

帖子

0

精华

新手上路

积分
28
金钱
28
注册时间
2017-11-22
在线时间
5 小时
发表于 2019-10-22 12:39:34 | 显示全部楼层
在哪里下载?
回复 支持 反对

使用道具 举报

5

主题

75

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
270
金钱
270
注册时间
2013-9-11
在线时间
39 小时
发表于 2020-4-8 09:17:17 | 显示全部楼层
1111111
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手上路

积分
42
金钱
42
注册时间
2019-3-31
在线时间
12 小时
发表于 2020-7-2 16:49:19 | 显示全部楼层
在哪下载
回复 支持 反对

使用道具 举报

0

主题

4

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2019-9-12
在线时间
6 小时
发表于 2021-2-1 13:40:18 | 显示全部楼层
优秀。。。大佬
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
6
金钱
6
注册时间
2021-10-26
在线时间
1 小时
发表于 2021-10-26 00:06:36 | 显示全部楼层
前辈您好,请问您发的关于SHT20的驱动代码中  error = Sht2xDrv_ReadUserRegister(&#174;);中的形参&#174;是什么意思
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
6
金钱
6
注册时间
2021-10-26
在线时间
1 小时
发表于 2021-10-26 00:07:49 | 显示全部楼层
前辈您好,请问您发的关于SHT20的驱动代码中  error = Sht2xDrv_ReadUserRegister(&#174;);中的形参&#174;是什么意思
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
6
金钱
6
注册时间
2021-10-26
在线时间
1 小时
发表于 2021-10-26 00:08:14 | 显示全部楼层
前辈您好,请问您发的关于SHT20的驱动代码中  error = Sht2xDrv_ReadUserRegister(&#174;);中的形参&#174;是什么意思
回复 支持 反对

使用道具 举报

44

主题

187

帖子

0

精华

高级会员

Rank: 4

积分
563
金钱
563
注册时间
2016-9-28
在线时间
158 小时
 楼主| 发表于 2024-1-18 15:33:09 | 显示全部楼层
Helios01 发表于 2021-10-26 00:08
前辈您好,请问您发的关于SHT20的驱动代码中  error = Sht2xDrv_ReadUserRegister(&#174;);中的形参&#174; ...

这个估计是你,复制代码的问题, 因为不符合C语言语法
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-23 12:54

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表