温湿度传感器GXHT40-兼容替代SHT40,附参考C驱动

 温湿度传感器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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值