一、SHT35 简介
SHT35 是一款高精度数字式温湿度传感器,采用 I²C 通信接口,可测量环境温度和相对湿度,温度测量范围为 −40~125℃,湿度测量范围为 0~100%RH,具有测量精度高、功耗低、体积小和稳定性好等特点。通过单片机发送测量命令并读取传感器数据,广泛应用于环境监测、智能家居及工业温湿度检测等领域

二、引脚功能
| 引脚 | 功能 |
|---|---|
| VCC | 电源正 3.3-5V |
| GND | 参考地 |
| SDA | 数据线 |
| SCL | 时钟线 |
三、驱动与数据说明
驱动说明
传感器上电后需等待小段时间,发送写命令 0x2400,等待 20ms 测量完成; 后读取 6 字节温湿度数据,再进行CRC检验

数据说明
温湿度数据计算 
CRC校验
CRC计算代码如下:
c
static uint8_t SHT35_CRC8(const uint8_t *data, uint8_t len)
{
uint8_t crc = 0xFF;
uint8_t i, j;
for (i = 0; i < len; i++)
{
crc ^= data[i];
for (j = 0; j < 8; j++)
{
if (crc & 0x80) {crc = (uint8_t)((crc << 1) ^ 0x31);}
else {crc = (uint8_t)(crc << 1);}
}
}
return crc;
}

四、程序
STM32
SHT35 .C
c
#include "sht35.h"
#include "delay.h"
#define SHT35_ADDR 0x44
#define I2C_TIMEOUT 100000U
static uint8_t I2C1_WaitEvent(uint32_t event)
{
uint32_t timeout = I2C_TIMEOUT;
while (!I2C_CheckEvent(I2C1, event))
{
if (--timeout == 0) return 0;
}
return 1;
}
static uint8_t I2C1_WaitFlag(uint32_t flag, FlagStatus status)
{
uint32_t timeout = I2C_TIMEOUT;
while (I2C_GetFlagStatus(I2C1, flag) != status)
{
if (--timeout == 0) return 0;
}
return 1;
}
static void I2C1_Stop(void)
{
I2C_GenerateSTOP(I2C1, ENABLE);
I2C_AcknowledgeConfig(I2C1, ENABLE);
}
static void I2C1_Init(void)
{
GPIO_InitTypeDef gpio;
I2C_InitTypeDef i2c;
RCC_APB2PeriphClockCmd(
RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(
RCC_APB1Periph_I2C1, ENABLE);
/* PB6 = SCL,PB7 = SDA */
gpio.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
gpio.GPIO_Speed = GPIO_Speed_50MHz;
gpio.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_Init(GPIOB, &gpio);
I2C_DeInit(I2C1);
I2C_StructInit(&i2c);
i2c.I2C_Mode = I2C_Mode_I2C;
i2c.I2C_DutyCycle = I2C_DutyCycle_2;
i2c.I2C_OwnAddress1 = 0;
i2c.I2C_Ack = I2C_Ack_Enable;
i2c.I2C_AcknowledgedAddress =
I2C_AcknowledgedAddress_7bit;
i2c.I2C_ClockSpeed = 100000;
I2C_Init(I2C1, &i2c);
I2C_Cmd(I2C1, ENABLE);
}
void SHT35_Init(void)
{
I2C1_Init();
}
static uint8_t SHT35_WriteCommand(uint16_t cmd)
{
if (!I2C1_WaitFlag(I2C_FLAG_BUSY, RESET)) return 0;
I2C_GenerateSTART(I2C1, ENABLE);
if (!I2C1_WaitEvent(I2C_EVENT_MASTER_MODE_SELECT)) goto error;
I2C_Send7bitAddress(I2C1, SHT35_ADDR << 1,I2C_Direction_Transmitter);
if (!I2C1_WaitEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) goto error;
I2C_SendData(I2C1, (uint8_t)(cmd >> 8));
if (!I2C1_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED)) goto error;
I2C_SendData(I2C1, (uint8_t)cmd);
if (!I2C1_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED)) goto error;
I2C1_Stop();
return 1;
error:
I2C1_Stop();
return 0;
}
static uint8_t SHT35_ReadBytes(uint8_t *data)
{
uint8_t i;
if (!I2C1_WaitFlag(I2C_FLAG_BUSY, RESET)) return 0;
I2C_AcknowledgeConfig(I2C1, ENABLE);
I2C_GenerateSTART(I2C1, ENABLE);
if (!I2C1_WaitEvent(I2C_EVENT_MASTER_MODE_SELECT)) goto error;
I2C_Send7bitAddress(I2C1, SHT35_ADDR << 1,I2C_Direction_Receiver);
if (!I2C1_WaitEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) goto error;
for (i = 0; i < 3; i++)
{
if (!I2C1_WaitFlag(I2C_FLAG_RXNE, SET)) goto error;
data[i] = I2C_ReceiveData(I2C1);
}
if (!I2C1_WaitFlag(I2C_FLAG_BTF, SET)) goto error;
I2C_AcknowledgeConfig(I2C1, DISABLE);
data[3] = I2C_ReceiveData(I2C1);
if (!I2C1_WaitFlag(I2C_FLAG_BTF, SET)) goto error;
I2C_GenerateSTOP(I2C1, ENABLE);
data[4] = I2C_ReceiveData(I2C1);
data[5] = I2C_ReceiveData(I2C1);
I2C_AcknowledgeConfig(I2C1, ENABLE);
return 1;
error:
I2C1_Stop();
return 0;
}
static uint8_t SHT35_CRC8(const uint8_t *data, uint8_t len)
{
uint8_t crc = 0xFF;
uint8_t i, j;
for (i = 0; i < len; i++)
{
crc ^= data[i];
for (j = 0; j < 8; j++)
{
if (crc & 0x80) {crc = (uint8_t)((crc << 1) ^ 0x31);}
else {crc = (uint8_t)(crc << 1);}
}
}
return crc;
}
uint8_t SHT35_ReadData(float *temperature, float *humidity)
{
uint8_t data[6];
uint16_t rawT, rawRH;
if (temperature == 0 || humidity == 0)
return 0;
if (!SHT35_WriteCommand(0x2400))
return 0;
Delay_ms(20);
if (!SHT35_ReadBytes(data))
return 0;
if (SHT35_CRC8(&data[0], 2) != data[2])
return 0;
if (SHT35_CRC8(&data[3], 2) != data[5])
return 0;
rawT = ((uint16_t)data[0] << 8) | data[1];
rawRH = ((uint16_t)data[3] << 8) | data[4];
*temperature = -45.0f + 175.0f * (float)rawT / 65535.0f;
*humidity = 100.0f * (float)rawRH / 65535.0f;
if (*humidity < 0.0f)
*humidity = 0.0f;
if (*humidity > 100.0f)
*humidity = 100.0f;
return 1;
}
main.C
c
#include "stm32f10x.h"
#include <stdio.h>
#include <Delay.h>
#include "sht35.h"
#include <stdint.h>
void USART1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_USART1,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE);
}
int fputc(int ch, FILE *f)
{
USART_SendData(USART1,(uint8_t)ch);
while (USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);
return ch;
}
int main(void)
{
float temperature = 0.0f;
float humidity = 0.0f;
int32_t t100;
uint32_t h100;
SystemInit();
USART1_Init();
SHT35_Init();
Delay_ms(500);
while (1)
{
if (SHT35_ReadData(&temperature, &humidity))
{
t100 = (int32_t)(temperature * 100.0f);
h100 = (uint32_t)(humidity * 100.0f);
if (t100 < 0)
{
printf("Temperature: -%ld.%02ld C, ",(long)(-t100 / 100),(long)(-t100 % 100));
}
else
{
printf("Temperature: %ld.%02ld C, ",(long)(t100 / 100),(long)(t100 % 100));
}
printf("Humidity: %lu.%02lu %%RH\r\n",(unsigned long)(h100 / 100),(unsigned long)(h100 % 100));
}
else
{
printf("Error!\r\n");
}
Delay_ms(1000);
}
}
五、测试
---------------------------------------------------接线--------------------------------------------------
- UART:
- PA9 -> TX
- PA10 -> RX
- IIC:
- PB6 -> SCL
- PB7 -> SDA
开发板串口输出如下:

以上内容个人理解,如有不正欢迎指正,需要资料及工程可留言邮箱