目录
一、SHT20 温湿度传感器 1、SHT20 的 I2C 地址 2、SHT20 的指令集 3、启动传感器 4、主机/非主机模式
5、软复位 6、用户寄存器(User Register) 7、SHT20 分辨率 8、CRC 校验和 9、原始数据转换
二、硬件设计
三、程序设计 1、读取温湿度数据的步骤 2、sht2x.h 3、sht2.c 4、main.c
四、功能展示
SHT20 采用第 4C 代 CMOSens® 芯片,除了包含一个电容式湿度传感器、一个带隙温度传感器外,该芯片还包含放大器、A/D 转换器、OTP 存储器和数字处理单元。每一个传感器都经过单独校准和测试。传感器表面有印制的批号。 SHT20 通过 I2C 总线与主控制器进行通信,支持低功耗模式,适用于电池供电设备。SHT20 默认测量分辨率为 14bit(温度)/12bit(湿度)。可以通过命令将测量分辨率降低至 12/8bit、11/11bit 或 13/10bit。传感器带有 CRC 校验和,有助于提高通信的可靠性。
SHT20 ___I2C__7">1、SHT20 的 I2C 地址
I2C 标头由 7 位 I2C 设备地址 ‘1000’000’ 和一个 SDA 方向位(读 R:‘1’,写 W:‘0’)组成。 8 位写地址:‘1000’0000’ (0x80);8 位读地址:‘1000’0001’ (0x81)。
命令 说明 代码(二进制) 代码(十六进制) Trigger T measurement 主机模式下触发温度测量 1110’0011 0xE3 Trigger RH measurement 主机模式下触发湿度测量 1110’0101 0xE5 Trigger T measurement 非主机模式下触发温度测量 1111’0011 0xF3 Trigger RH measurement 非主机模式下触发湿度测量 1111’0101 0xF5 Trigger RH measurement 写用户寄存器 1110’0110 0xE6 Write user register 读用户寄存器 1110’0111 0xE7 Soft reset 软复位 1111’1110 0xFE
3、启动传感器
上电后,传感器最多需要 15ms(SCL 为高电平)才能进入空闲状态,即准备好接受来自主设备(MCU)的命令。 启动期间的最大电流消耗为 350µA。 只要传感器上电但不进行测量或通信,它就会自动处于空闲状态(睡眠模式)。
4、主机/非主机模式
支持两种不同的操作模式与 SHT20 进行通信:主机模式或非主机模式。 主机模式下,SHT2x 在测量时拉低 SCL 线以强制主设备进入等待状态(由传感器进行控制)。 传感器通过释放 SCL 线,指示内部处理已终止并且可以继续传输。 非主机模式下,SCL 线在传感器处理测量时保持打开状态,允许主设备(MCU)在传感器测量时处理总线上的其他 I2C 通信任务。 对于这两种模式,由于测量的最大分辨率为 14 位,因此最后两个最低有效位(LSB,位 43 和 44)用于传输状态信息。 两个 LSB 中的位 1 表示测量类型(“0”:温度,“1”:湿度)。位 0 目前未分配。 每个传输时序都以起始条件(S)开始,以停止条件(P)结束。 起始条件(S):I2C 起始信号;停止条件(P):I2C 停止信号。 注意:I2C 通信允许重复启动条件(S),而无需使用停止条件(P)关闭先前的序列 - 比较图 15、16 和 18。 不过,任何具有相邻启动条件的序列都可以用停止条件来关闭。 灰色块由 SHT20 进行控制。
①、主机模式下通信时序
②、非主机模式下通信时序
5、软复位
此命令用在无需关闭后再打开电源的情况下,重新启动传感器系统。 收到此命令后,传感器系统将重新初始化,并根据默认设置开始运行(用户寄存器中的加热器位除外)。 软复位所需时间不到 15ms。
6、用户寄存器(User Register)
注意:保留位不得更改。因此,对于任何写入用户寄存器的操作,必须先读取保留位的默认值。
测量的最大持续时间取决于所选的测量类型和分辨率。MCU 通信时应选择最大值。
8、CRC 校验和
SHT20 提供 CRC-8 校验和用于错误检测。使用的多项式为 x8 + x5 + x4 +1。
9、原始数据转换
SHT20 返回的温湿度数据为 16 位原始数据,需要经过线性转换才能得到实际的温湿度值。对于温度,公式为:T = -46.85 + 175.72 * (温度数据 / 65536) 对于湿度,公式为:RH = -6 + 125 * (湿度数据 / 65536)
二、硬件设计
1、接线说明
SHT20 STM32F407ZGT6 引脚定义 G GND 电源负极 GND V 3.3V 电源正极 VCC SCL B9 IIC 接口 SDA 数据引脚 SDA B8 IIC 接口 SCL 时钟引脚
2、原理图设计
芯片焊盘(中心焊盘)内部连接到 VSS。 NC 焊盘必须保持浮动(悬空,不连接)。 电源引脚(VDD、VSS)必须使用 100nF 电容去耦。 为避免信号争用,微控制器单元(MCU)必须仅将 SDA 和 SCL 驱动为低电平。需要外部上拉电阻(例如 10kΩ)来将信号拉高。 不要使用热风枪对着芯片表面进行焊接!!!
三、程序设计
1、读取温湿度数据的步骤
1、初始化 SHT20 传感器:通过软件 I2C 发送软复位命令,确保传感器进入初始状态。 2、发送读取命令:发送温度读取或湿度读取命令(0xE3、0xE5 或 0xF3、0xF5)。 3、读取数据:接收传感器返回的 16 位数据并进行 CRC 校验。 4、数据转换:将 16 位数据通过公式转换为实际的温度和湿度值。 5、数据显示:可以通过串口或 OLED 屏幕显示实际的温湿度值。
2、sht2x.h
# ifndef __SHT2X_H
# define __SHT2X_H
# include "./SYSTEM/sys/sys.h"
typedef enum {
SHT20 _Address_Write = 0x80 ,
SHT20 _Address_Read = 0x81
} thSHT2xIICAddress;
typedef enum {
SHT2x_Trig_T_Measurement_HM = 0xE3 ,
SHT2x_Trig_RH_Measurement_HM = 0xE5 ,
SHT2x_Trig_T_Measurement_POLL = 0xF3 ,
SHT2x_Trig_RH_Measurement_POLL = 0xF5 ,
SHT2x_Write_User_Reg = 0xE6 ,
SHT2x_Read_User_Reg = 0xE7 ,
SHT2x_Soft_Reset = 0xFE
} thSHT2xCommand;
typedef enum {
SHT2x_RES_12_14BIT = 0x00 ,
SHT2x_RES_8_12BIT = 0x01 ,
SHT2x_RES_10_13BIT = 0x80 ,
SHT2x_RES_11_11BIT = 0x81 ,
SHT2x_RES_MASK = 0x81
} thSHT2xResolution;
typedef enum {
SHT2x_EOB_ON = 0x40 ,
SHT2x_EOB_MASK = 0x40
} thSHT2xEOB;
typedef enum {
SHT2x_HEATER_ON = 0x04 ,
SHT2x_HEATER_OFF = 0x00 ,
SHT2x_HEATER_MASK = 0x04
} thSHT2xHeater;
typedef enum {
SHT2x_OTP_Reload_ON = 0x02 ,
SHT2x_OTP_Reload_OFF = 0x00 ,
SHT2x_OTP_Reload_MASK = 0x02
} thSHT2xOTP;
void SHT2x_Init_SoftIIC ( void ) ;
uint8_t SHT2x_CheckCRC ( uint8_t data[ ] , uint8_t nbrOfBytes, uint8_t checksum) ;
uint8_t SHT2x_ReadReg_Data ( uint8_t read_address, uint8_t reg) ;
void SHT2x_WriteReg_Data ( uint8_t write_address, uint8_t reg, uint8_t data) ;
uint8_t SHT2x_Read_UserReg_Data ( uint8_t read_address) ;
void SHT2x_Write_UserReg_Data ( uint8_t read_address, uint8_t data) ;
void SHT2x_SoftReset ( uint8_t write_address) ;
uint16_t SHT2x_Measure_HW ( uint8_t read_address, uint8_t reg) ;
uint16_t SHT2x_Measure_POLL ( uint8_t read_address, uint8_t reg) ;
uint16_t SHT2x_Measure_Temp_HW ( void ) ;
uint16_t SHT2x_Measure_Humidity_HW ( void ) ;
uint16_t SHT2x_Measure_Temp_POLL ( void ) ;
uint16_t SHT2x_Measure_Humidity_POLL ( void ) ;
float SHT2x_Calclates_Temperature ( uint16_t temp) ;
float SHT2x_Calclates_Humidity ( uint16_t temp) ;
# endif
3、sht2.c
# include "./SYSTEM/delay/delay.h"
# include "./SYSTEM/usart/usart.h"
# include "./BSP/SoftIIC/softiic.h"
# include "./BSP/SHT2x/sht2x.h"
const uint16_t SHT2x_POLYNOMIAL = 0x131 ;
void SHT2x_Init_SoftIIC ( void )
{
SoftIIC_Init ( ) ;
SHT2x_SoftReset ( SHT20 _Address_Write) ;
delay_ms ( 15 ) ;
}
uint8_t SHT2x_CheckCRC ( uint8_t data[ ] , uint8_t nbrOfBytes, uint8_t checksum)
{
uint8_t byteCtr;
uint8_t bit;
uint8_t crc = 0 ;
for ( byteCtr = 0 ; byteCtr < nbrOfBytes; ++ byteCtr)
{
crc ^= ( data[ byteCtr] ) ;
for ( bit = 8 ; bit > 0 ; -- bit)
{
if ( crc & 0x80 )
{
crc = ( crc << 1 ) ^ SHT2x_POLYNOMIAL;
}
else crc = ( crc << 1 ) ;
}
}
if ( crc != checksum) return 1 ;
else return 0 ;
}
uint8_t SHT2x_ReadReg_Data ( uint8_t read_address, uint8_t reg)
{
uint8_t error = 0 ;
uint8_t checksum;
uint8_t data[ ] = { 0 } ;
SoftIIC_Start ( ) ;
SoftIIC_Send_Byte ( read_address & ~ 0x01 ) ;
SoftIIC_Wait_Ack ( ) ;
SoftIIC_Send_Byte ( reg) ;
SoftIIC_Wait_Ack ( ) ;
SoftIIC_Start ( ) ;
SoftIIC_Send_Byte ( read_address) ;
SoftIIC_Wait_Ack ( ) ;
data[ 0 ] = SoftIIC_Read_Byte ( 1 ) ;
printf ( "SHT2x_ReadReg_Data data:%X\r\n" , data[ 0 ] ) ;
checksum = SoftIIC_Read_Byte ( 0 ) ;
printf ( "SHT2x_ReadReg_Data checksum:%X\r\n" , checksum) ;
error |= SHT2x_CheckCRC ( data, 1 , checksum) ;
printf ( "SHT2x_ReadReg_Data error:%X\r\n" , error) ;
SoftIIC_Stop ( ) ;
return data[ 0 ] ;
}
void SHT2x_WriteReg_Data ( uint8_t write_address, uint8_t reg, uint8_t data)
{
SoftIIC_Start ( ) ;
SoftIIC_Send_Byte ( write_address) ;
SoftIIC_Wait_Ack ( ) ;
SoftIIC_Send_Byte ( reg) ;
SoftIIC_Wait_Ack ( ) ;
SoftIIC_Send_Byte ( data) ;
SoftIIC_Wait_Ack ( ) ;
SoftIIC_Stop ( ) ;
}
uint8_t SHT2x_Read_UserReg_Data ( uint8_t read_address)
{
uint8_t data;
data = SHT2x_ReadReg_Data ( read_address, SHT2x_Read_User_Reg) ;
printf ( "SHT2x_UserReg:%X\r\n" , data) ;
return data;
}
void SHT2x_Write_UserReg_Data ( uint8_t write_address, uint8_t data)
{
SHT2x_WriteReg_Data ( write_address, SHT2x_Write_User_Reg, data) ;
}
void SHT2x_SoftReset ( uint8_t write_address)
{
SoftIIC_Start ( ) ;
SoftIIC_Send_Byte ( write_address) ;
SoftIIC_Wait_Ack ( ) ;
SoftIIC_Send_Byte ( SHT2x_Soft_Reset) ;
SoftIIC_Wait_Ack ( ) ;
SoftIIC_Stop ( ) ;
}
uint16_t SHT2x_Measure_HW ( uint8_t read_address, uint8_t reg)
{
uint8_t data8[ 2 ] ;
uint8_t checksum;
uint16_t data16;
SoftIIC_Start ( ) ;
SoftIIC_Send_Byte ( read_address & ~ 0x01 ) ;
SoftIIC_Wait_Ack ( ) ;
SoftIIC_Send_Byte ( reg) ;
SoftIIC_Wait_Ack ( ) ;
SoftIIC_Start ( ) ;
SoftIIC_Send_Byte ( read_address) ;
SoftIIC_Wait_Ack ( ) ;
delay_ms ( 85 ) ;
data8[ 0 ] = SoftIIC_Read_Byte ( 1 ) ;
data8[ 1 ] = SoftIIC_Read_Byte ( 1 ) ;
checksum = SoftIIC_Read_Byte ( 0 ) ;
SoftIIC_Stop ( ) ;
if ( SHT2x_CheckCRC ( data8, 2 , checksum) != 0 )
{
printf ( "SHT2x_Measure_HW error:1\r\n" ) ;
return 1 ;
}
data16 = ( data8[ 0 ] << 8 ) | data8[ 1 ] ;
printf ( "SHT2x_Measure_HW data:%X\r\n" , data16) ;
return data16;
}
uint16_t SHT2x_Measure_POLL ( uint8_t read_address, uint8_t reg)
{
uint8_t i;
uint8_t data8[ 2 ] ;
uint8_t checksum;
uint16_t data16;
SoftIIC_Start ( ) ;
SoftIIC_Send_Byte ( read_address & ~ 0x01 ) ;
SoftIIC_Wait_Ack ( ) ;
SoftIIC_Send_Byte ( reg) ;
SoftIIC_Wait_Ack ( ) ;
delay_ms ( 1 ) ;
SoftIIC_Stop ( ) ;
do
{
delay_ms ( 10 ) ;
SoftIIC_Start ( ) ;
SoftIIC_Send_Byte ( read_address) ;
if ( i++ >= 20 ) break ;
} while ( SoftIIC_Wait_Ack ( ) == 1 ) ;
data8[ 0 ] = SoftIIC_Read_Byte ( 1 ) ;
data8[ 1 ] = SoftIIC_Read_Byte ( 1 ) ;
checksum = SoftIIC_Read_Byte ( 0 ) ;
SoftIIC_Stop ( ) ;
if ( SHT2x_CheckCRC ( data8, 2 , checksum) != 0 )
{
printf ( "SHT2x_Measure_POLL error:1\r\n" ) ;
return 1 ;
}
data16 = ( data8[ 0 ] << 8 ) | data8[ 1 ] ;
printf ( "SHT2x_Measure_POLL data:%X\r\n" , data16) ;
return data16;
}
uint16_t SHT2x_Measure_Temp_HW ( void )
{
uint16_t temp_hw;
temp_hw = SHT2x_Measure_HW ( SHT20 _Address_Read, SHT2x_Trig_T_Measurement_HM) ;
return temp_hw;
}
uint16_t SHT2x_Measure_Humidity_HW ( void )
{
uint16_t humidity_hw;
humidity_hw = SHT2x_Measure_HW ( SHT20 _Address_Read, SHT2x_Trig_RH_Measurement_HM) ;
return humidity_hw;
}
uint16_t SHT2x_Measure_Temp_POLL ( void )
{
uint16_t temp_poll;
temp_poll = SHT2x_Measure_POLL ( SHT20 _Address_Read, SHT2x_Trig_T_Measurement_POLL) ;
return temp_poll;
}
uint16_t SHT2x_Measure_Humidity_POLL ( void )
{
uint16_t humidity_poll;
humidity_poll = SHT2x_Measure_POLL ( SHT20 _Address_Read, SHT2x_Trig_RH_Measurement_POLL) ;
return humidity_poll;
}
float SHT2x_Calclates_Temperature ( uint16_t temp)
{
double temperature;
temp &= ~ 0x0003 ;
temperature = - 46.85f + 175.72f * ( double ) temp / 65536.0f ;
printf ( "temperature:%.2f\r\n" , temperature) ;
return temperature;
}
float SHT2x_Calclates_Humidity ( uint16_t humi)
{
float humidity;
humi &= ~ 0x0003 ;
humidity = - 6.0f + 125.0f * ( float ) humi / 65536.0f ;
printf ( "humidity:%.2f\r\n" , ( double ) humidity) ;
return humidity;
}
4、main.c
# include "./SYSTEM/sys/sys.h"
# include "./SYSTEM/delay/delay.h"
# include "./SYSTEM/usart/usart.h"
# include "./BSP/SHT2x/sht2x.h"
int main ( void )
{
HAL_Init ( ) ;
sys_stm32 _clock_init ( 336 , 8 , 2 , 7 ) ;
delay_init ( 168 ) ;
usart_init ( 115200 ) ;
SHT2x_Init_SoftIIC ( ) ;
while ( 1 )
{
uint8_t Initial_UserReg_Data;
Initial_UserReg_Data = SHT2x_Read_UserReg_Data ( SHT20 _Address_Read) ;
SHT2x_Write_UserReg_Data ( SHT20 _Address_Write, ( Initial_UserReg_Data & ~ SHT2x_RES_MASK) | SHT2x_RES_8_12BIT) ;
SHT2x_Read_UserReg_Data ( SHT20 _Address_Read) ;
SHT2x_Calclates_Temperature ( SHT2x_Measure_Temp_HW ( ) ) ;
SHT2x_Calclates_Humidity ( SHT2x_Measure_Humidity_HW ( ) ) ;
SHT2x_Calclates_Temperature ( SHT2x_Measure_Temp_POLL ( ) ) ;
SHT2x_Calclates_Humidity ( SHT2x_Measure_Humidity_POLL ( ) ) ;
delay_ms ( 5000 ) ;
}
}
四、功能展示
1、串口显示
SHT20 默认测量分辨率为 14bit(温度)/12bit(湿度)。
2、CRC 校验