温湿度传感器GXHT40-兼容替代SHT40,附参考C驱动
一、资源说明
二、基本参数
三、参考驱动
四、注意事项
一、资源说明
GXHT40温湿度芯片,是新型高精度单芯片集成温湿度传感IC是“在硅基CMOS晶圆上集成高灵敏度MEMS湿敏元件,把温度补偿和标定数据都集成在一个电路里”,实现湿敏电容结构和信号处理电路的单芯片集成,减少并降低了传感器的体积和成本,同时降低信号传输带来的干扰,提高产品精度、可靠性、一致性。
GXHT40是一款极低功耗的温湿度传感器,平均功耗仅0.5uA(每秒转换一次@3.3V),工作电压1.6 ~ 5.5V,温度测量范围为-40°C ~ 125°C,湿度测量范围为 0 ~ 100%RH,可支持二次过标准回流焊接,限制最高温度为260℃,焊接完成无需水合处理,常温下12小时自然恢复。
二、基本参数
GXHT40关键电器参数如下:
三、参考驱动
1、GXHT40芯片引脚定义图
2、GXHTC3芯片硬件参考电路图
GXHTC3使用标准IIC通信协议,支持400KHZ通信速率,SCL、SDA通信引脚开漏输出,需要加1-10K可选上拉电阻,VDD和GND之间需要加100nF的去耦电容,该电容离传感器越近越好。
3、芯片IIC器件地址
GXHT40芯片有两个IIC器件通信地址可选,0x44/0x45。
4、温湿度测量和数据读取
每一次测量仅需发生一次测量命令,并且以 STRAT 信号开 始,终止于 STOP 信号。具体执行顺序如下:
1) 主机初始化IIC,对传感器进行软件复位,确保传感器准备就绪
2) 主机向传感器发送测量命令
2) 等待芯片完成数据转换
4.)读出6字节数据(温度数据2字节,温度数据校验1字节,湿度数据2字节,湿度数据校验1字节)
其中数据转换命令分为高、中、低重复率测量,重复率越高,说明芯片内部进行更多次的数据平均,重复性越高数据会越平稳,因此转换的时间会更长,对应功耗也会增加。客户可以根据自己需要灵活使用相应的数据测量命令。
这里需要注意的是,发送完测量命令需要等待芯片完成数据转换再读数据,主机可以通过定时器或者直接加delay_ms(x)延时进行等待,实际应用时可以多等待一会,确保数据已经完成转换。如果不想增加延时,发送完测量命令直接读地址来读取数据,这时数据没有转换完成传感器会给主机返回NACK信号,直到传感器转换完主机才会收到ACK信号,这个时候才能读取后面的6字节数据。
5、典型测量时序图
6、传感器加热器功能
传感器集成了一个加热器,它通过设置不同的命令实现开关。加热器功能主要用于以下几种常见的场景如:(1)除去传感器表面的溅射或者结露的水滴。虽然结露的水滴对于传感器来说不会导致传感器损坏,但是如 果液态的水滴一直存在于传感器的表面,会影响传感器对环境湿度的响应。(2)长期高湿环境,通过周期性的加热能够保证传感器的长期可靠性。
注意:打开加热器期间,可以正常读温湿度数据。但在开启加热器期间,传感器的性能指标不再适用!!!
7、驱动实例
STM32F103 + GXHT40温湿度芯片驱动实例
GXHT40.h文件
#include "GXHT4x.h"
#include "delay.h"
#define write 0
#define read 1
/*
* @name CRC_8
* @brief CRC-8校验
* @param Crc_ptr -> 校验数据首地址
LEN -> 校验数据长度
* @retval CRC_Value -> 校验值
*/
static uint8_t CRC_8(uint8_t *Crc_ptr,uint8_t LEN)
{
uint8_t CRC_Value = 0xFF;
uint8_t i = 0,j = 0;
for(i=0;i<LEN;i++)
{
CRC_Value ^= *(Crc_ptr+i);
for(j=0;j<8;j++)
{
if(CRC_Value & 0x80)
CRC_Value = (CRC_Value << 1) ^ 0x31;
else
CRC_Value = (CRC_Value << 1);
}
}
return CRC_Value;
}
/****************************************************************************
* Function Name : GXHT4X_GPIO_INIT
* Description : 初始化GPIO.
* Input : None
* Output : None
* Return : None
****************************************************************************/
void GXHT4X_GPIO_INIT(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStructure.GPIO_Pin=GXHT4X_SDA;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;
GPIO_Init(GPIO_GXHT4X,&GPIO_InitStructure);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStructure.GPIO_Pin=GXHT4X_SCL;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;
GPIO_Init(GPIO_GXHT4X,&GPIO_InitStructure);
GXHT4X_SCL_H;
GXHT4X_SDA_H;
delay_ms(100); //等待系统电源稳定
GXHT4XReset(GXHT4X_ADDRESS); //软件复位 确保芯片已就绪
}
/*******************************************************************************
* 函 数 名 : GXHT4X_SDA_OUT
* 函数功能 : SDA输出配置
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void GXHT4X_SDA_OUT(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=GXHT4X_SDA;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;
GPIO_Init(GPIO_GXHT4X,&GPIO_InitStructure);
}
/*******************************************************************************
* 函 数 名 : GXHT4X_SDA_IN
* 函数功能 : SDA输入配置
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void GXHT4X_SDA_IN(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=GXHT4X_SDA;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_OD;
GPIO_Init(GPIO_GXHT4X,&GPIO_InitStructure);
}
void GXHT4X_SDA_in(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=GXHT4X_SDA;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
GPIO_Init(GPIO_GXHT4X,&GPIO_InitStructure);
}
//产生起始信号
void GXHT4X_StarT(void)
{
GXHT4X_SDA_OUT();
GXHT4X_SDA_H;
GXHT4X_SCL_H;
delay_us(5);
GXHT4X_SDA_L;
delay_us(6);
GXHT4X_SCL_L;
}
//产生停止信号
void GXHT4X_StoP(void)
{
GXHT4X_SDA_OUT();
GXHT4X_SCL_L;
GXHT4X_SDA_L;
GXHT4X_SCL_H;
delay_us(6);
GXHT4X_SDA_H;
delay_us(6);
}
//主机产生应答信号ACK
void GXHT4X_Ack(void)
{
GXHT4X_SCL_L;
GXHT4X_SDA_OUT();
GXHT4X_SDA_L;
delay_us(2);
GXHT4X_SCL_H;
delay_us(5);
GXHT4X_SCL_L;
}
//主机不产生应答信号NACK
void GXHT4X_NAck(void)
{
GXHT4X_SCL_L;
GXHT4X_SDA_OUT();
GXHT4X_SDA_H;
delay_us(2);
GXHT4X_SCL_H;
delay_us(5);
GXHT4X_SCL_L;
}
//等待从机应答信号
//返回值:1 接收应答失败
// 0 接收应答成功
u8 GXHT4X_Wait_Ack(void)
{
u8 tempTime=0;
GXHT4X_SDA_IN();
GXHT4X_SDA_H;
delay_us(1);
GXHT4X_SCL_H;
delay_us(1);
while(GPIO_ReadInputDataBit(GPIO_GXHT4X,GXHT4X_SDA))
{
tempTime++;
delay_us(1);
if(tempTime>250)
{
GXHT4X_StoP();
return 1;
}
}
GXHT4X_SCL_L;
delay_us(1);
return 0;
}
//GXHT4X 发送一个字节
void GXHT4X_Send_Byte(u8 txd)
{
u8 i=0;
GXHT4X_SDA_OUT();
GXHT4X_SCL_L;//拉低时钟开始数据传输
for(i=0;i<8;i++)
{
if((txd&0x80)>0) //0x80 1000 0000
GXHT4X_SDA_H;
else
GXHT4X_SDA_L;
txd<<=1;
delay_us(1);
GXHT4X_SCL_H;
delay_us(2); //发送数据
GXHT4X_SCL_L;
delay_us(2);
}
}
//GXHT4X 读取一个字节
u8 GXHT4X_Read_Byte(u8 ack)
{
u8 i=0,receive=0;
GXHT4X_SDA_in();
for(i=0;i<8;i++)
{
GXHT4X_SCL_L;
delay_us(2);
GXHT4X_SCL_H;
while(!GPIO_ReadInputDataBit(GPIO_GXHT4X,GXHT4X_SCL));
receive<<=1;
if(GPIO_ReadInputDataBit(GPIO_GXHT4X,GXHT4X_SDA))
receive++;
delay_us(1);
}
if(ack==0)
GXHT4X_NAck();
else
GXHT4X_Ack();
return receive;
}
void GXHT4X_read_result(u8 GXHT4x_ADDRESS, float *GXHT4x_TEMP,float *GXHT4x_HUMI)
{
u16 tem,hum;
unsigned char buff[6];
float temperature,humidity;
GXHT4X_StarT();
GXHT4X_Send_Byte(GXHT4x_ADDRESS <<1 | write);//写7位GXHT4X设备地址加0作为写取位,1为读取位
GXHT4X_Wait_Ack();
GXHT4X_Send_Byte(GXHT4X_CMD_MEASURE_HPM);
GXHT4X_Wait_Ack();
GXHT4X_StoP();
delay_ms(10); //等待芯片完成数据转换
GXHT4X_StarT();
GXHT4X_Send_Byte(GXHT4x_ADDRESS <<1 | read);//写7位GXHT4X设备地址加0作为写取位,1为读取位
if(GXHT4X_Wait_Ack()==0)
{
GXHT4X_SDA_in();
buff[0]=GXHT4X_Read_Byte(1);
buff[1]=GXHT4X_Read_Byte(1);
buff[2]=GXHT4X_Read_Byte(1);
buff[3]=GXHT4X_Read_Byte(1);
buff[4]=GXHT4X_Read_Byte(1);
buff[5]=GXHT4X_Read_Byte(0);
GXHT4X_StoP();
if(CRC_8(buff, 2) == buff[2] && CRC_8(buff + 3, 2) == buff[5])
{
tem = ((buff[0]<<8) | buff[1]);//温度拼接
hum = ((buff[3]<<8) | buff[4]);//湿度拼接
temperature = 175.0 * (float)tem / 65535.0 - 45.0 ; // T = -45 + 175 * tem / (2^16-1)
humidity = 125.0 * (float)hum / 65535.0 - 6; // RH = -6 + 125 * hum / (2^16-1)
if(humidity >= 100)
humidity = 100;
if((temperature>=-45&&temperature<=125)&&(humidity>=0 && humidity<=100))//过滤错误数据
{
*GXHT4x_TEMP = temperature;
*GXHT4x_HUMI = humidity;
}
}
else
{
*GXHT4x_TEMP = 0;
*GXHT4x_HUMI = 0;
}
}
tem = 0;
hum = 0;
}
/****************************************************************************
* Function Name : GXHT4XReset
* Description : GXHT4X软复位
* Input : None
* Output : None
* Return : None
****************************************************************************/
void GXHT4XReset(u8 GXHT4x_ADDRESS)
{
GXHT4X_StarT();
GXHT4X_Send_Byte(GXHT4x_ADDRESS << 1 | write);
GXHT4X_Wait_Ack();
GXHT4X_Send_Byte(GXHT4X_CMD_RESET);
GXHT4X_Wait_Ack();
GXHT4X_StoP();
delay_ms(1);
}
GXHT40.C文件
#ifndef _GXHT4x_H
#define _GXHT4x_H
#include "stm32f10x.h"
/* sensor measurement commands*/
#define GXHT4X_CMD_MEASURE_HPM 0xFD
#define GXHT4X_CMD_MEASURE_LPM 0xE0
#define GXHT4X_CMD_READ_SERIAL 0x89
#define GXHT4X_CMD_RESET 0x94
#define GXHT4X_ADDRESS 0x44
//如果移植程序时只要改一下三个地方就行了
/* 定时使用的IO口 */
#define GXHT4X_SCL GPIO_Pin_6
#define GXHT4X_SDA GPIO_Pin_7
#define GPIO_GXHT4X GPIOA
#define GXHT4X_SCL_H GPIO_SetBits(GPIO_GXHT4X,GXHT4X_SCL)
#define GXHT4X_SCL_L GPIO_ResetBits(GPIO_GXHT4X,GXHT4X_SCL)
#define GXHT4X_SDA_H GPIO_SetBits(GPIO_GXHT4X,GXHT4X_SDA)
#define GXHT4X_SDA_L GPIO_ResetBits(GPIO_GXHT4X,GXHT4X_SDA)
extern void GXHT4X_GPIO_INIT(void);
extern void GXHT4XReset(u8 GXHT4x_ADDRESS);
extern void GXHT4X_read_result(u8 GXHT4x_ADDRESS, float *GXHT4x_TEMP,float *GXHT4x_HUMI);
#endif
四、注意事项
1、IIC总线SCL、SDA必须加上拉电阻,建议1~10K,一般选择4.7K或者10K即可;
2、主机发送完数据转换命令,必须加一定的延时(参考规格书),确保芯片完成数据转换,再读数据;
3、主机读6个字节数据,最好加上CRC校验,确保数据没问题,最后一个字节发送NACK,终止IIC通信。
友情提示:
有任何问题可随时沟通交流,Call:13128272535