本帖最后由 mftang2016 于 2017-12-1 22:44 编辑
//系统硬件接口
PH4 -------I2C2_SCL
PH5--------I2C2_SDA
测试结果如下图:(注释:得到温湿度数据被放大100倍,换算成实际值需要乘以0.01)
和硬件相关接口代码:
#define I2C_GPIO_CLK_ENABLE() __HAL_RCC_GPIOH_CLK_ENABLE()
#define I2C_GPIO_CLK_DISABLE() __HAL_RCC_GPIOH_CLK_DISABLE()
#define GPIO_PORT_I2C GPIOH
#define I2C_SCL_PIN GPIO_PIN_4
#define I2C_SDA_PIN GPIO_PIN_5
#define I2C_SCL_1() HAL_GPIO_WritePin( GPIO_PORT_I2C, I2C_SCL_PIN, GPIO_PIN_SET) /* SCL = 1 */
#define I2C_SCL_0() HAL_GPIO_WritePin( GPIO_PORT_I2C, I2C_SCL_PIN, GPIO_PIN_RESET) /* SCL = 0 */
#define I2C_SDA_1() HAL_GPIO_WritePin( GPIO_PORT_I2C, I2C_SDA_PIN, GPIO_PIN_SET) /* SDA = 1 */
#define I2C_SDA_0() HAL_GPIO_WritePin( GPIO_PORT_I2C, I2C_SDA_PIN, GPIO_PIN_RESET) /* SDA = 0 */
#define I2C_SDA_READ() ((GPIO_PORT_I2C->IDR & I2C_SDA_PIN) != 0) /* read SDA status */
#define I2C_SCL_READ() ((GPIO_PORT_I2C->IDR & I2C_SCL_PIN) != 0) /* read SCLs tatus */
void board_i2cInit( void )
{
GPIO_InitTypeDef GPIO_InitStruct;
/* Enable the GPIO_I2C clock */
I2C_GPIO_CLK_ENABLE();
/* Configure the GPIO_I2C pin */
GPIO_InitStruct.Pin = I2C_SCL_PIN|I2C_SDA_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
HAL_GPIO_Init(GPIO_PORT_I2C, &GPIO_InitStruct);
}
相关文档
Sensirion_Humidity_SHT20_Datasheet_V3_8395437268751607934.pdf
(573.72 KB, 下载次数: 217)
2017-11-28 22:21 上传
点击文件名下载附件
完整驱动代码:
sht2x.zip
(7.49 KB, 下载次数: 362)
2017-11-28 22:10 上传
点击文件名下载附件
关键代码:应用i2c 驱动sht20
sht20 driver
[mw_shl_code=c,true]/**
******************************************************************************
* @file BSP/Components/sht2x.c
*
@Author mingfei tang
* @brief Main program body
******************************************************************************
* @attention
*
* <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h"
#include "adafruit_i2c.h"
#include "sht2x.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define I2C_ADDRESS (0x40 << 1)
#define POLY 0x131; //P(x)=x^8+x^5+x^4+1 = 100110001
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
static void i2c_Delay(uint16_t value );
static uint8_t sht2xdrv_CheckCrc(uint8_t data[], uint8_t nbrOfBytes, uint8_t checksum);
static uint8_t SHT2X_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 SHT2X_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;
}
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(®);
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(®);
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(®);
if (error != SHT2x_STATUS_OK)
{
return error;
}
*pResolution = (sht2xResolution_t)(reg & SHT2x_RES_MASK);
return error;
}
uint8_t regVal;
static int32_t s_TempData;
static int32_t s_RhData;
sht2xResolution_t sht2xResolutionvalue;
void SHT2X_test( void )
{
i2c_Init();
SHT2X_CheckOk();
sht2xdrv_GetBatteryStatus();
sht2xdrv_GetResolution( &sht2xResolutionvalue );
sht2xdrv_GetTemp( &s_TempData );
sht2xdrv_GetRH( &s_RhData );
}
/* End of this file */[/mw_shl_code]
i2c 部分
[mw_shl_code=c,true]/**
******************************************************************************
* @file BSP/Armfly_Discovery/armfly_i2c.c
* @author mingfei tang
* @brief Main program body
******************************************************************************
* @attention
*
* <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h"
#include "armfly_board.h"
#include "adafruit_i2c.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
static void i2c_Delay(void)
{
uint8_t i;
for (i = 0; i < 30; i++);
}
void i2c_Init(void)
{
board_i2cInit(); /* i2c port init */
i2c_Stop();
}
void i2c_Start(void)
{
I2C_SDA_1();
I2C_SCL_1();
i2c_Delay();
I2C_SDA_0();
i2c_Delay();
I2C_SCL_0();
i2c_Delay();
}
void i2c_Stop(void)
{
I2C_SDA_0();
I2C_SCL_1();
i2c_Delay();
I2C_SDA_1();
}
void i2c_SendByte(uint8_t _ucByte)
{
uint8_t i;
for (i = 0; i < 8; i++)
{
if (_ucByte & 0x80)
{
I2C_SDA_1();
}
else
{
I2C_SDA_0();
}
i2c_Delay();
I2C_SCL_1();
i2c_Delay();
I2C_SCL_0();
if (i == 7)
{
I2C_SDA_1();
}
_ucByte <<= 1;
i2c_Delay();
}
}
uint8_t i2c_ReadByte(void)
{
uint8_t i;
uint8_t value;
value = 0;
for (i = 0; i < 8; i++)
{
value <<= 1;
I2C_SCL_1();
i2c_Delay();
if (I2C_SDA_READ())
{
value++;
}
I2C_SCL_0();
i2c_Delay();
}
return value;
}
/**
* @brief wait for i2c ack.
* @retval result:
*/
i2c_TypeDef i2c_WaitAck(void)
{
i2c_TypeDef re = I2C_OK;
I2C_SDA_1();
i2c_Delay();
I2C_SCL_1();
i2c_Delay();
if (I2C_SDA_READ())
{
re = I2C_FAIL;
}
I2C_SCL_0();
i2c_Delay();
return re;
}
void i2c_Ack(void)
{
I2C_SDA_0();
i2c_Delay();
I2C_SCL_1();
i2c_Delay();
I2C_SCL_0();
i2c_Delay();
I2C_SDA_1();
}
void i2c_NAck(void)
{
I2C_SDA_1();
i2c_Delay();
I2C_SCL_1();
i2c_Delay();
I2C_SCL_0();
i2c_Delay();
}
i2c_TypeDef i2c_CheckDevice(uint8_t _Address)
{
i2c_TypeDef ucAck = I2C_FAIL;
if (I2C_SDA_READ() && I2C_SCL_READ())
{
i2c_Start();
i2c_SendByte(_Address | I2C_WR);
ucAck = i2c_WaitAck();
i2c_Stop();
}
return ucAck;
}
/* End of this file */[/mw_shl_code]
一周热门 更多>