GXHT30温湿度芯片STM32、C51驱动,可PIN TO PIN软硬件兼容SHT30/SHT31
GXHT3x系列温湿度芯片,是新型高精度单芯片集成温湿度传感IC是“在硅基CMOS晶圆上集成高灵敏度MEMS湿敏元件,把温度补偿和标定数据都集成在一个电路里”,实现湿敏电容结构和信号处理电路的单芯片集成,减少并降低了传感器的体积和成本,同时降低信号传输带来的干扰,提高产品精度、可靠性、一致性。
·
GXHT30温湿度芯片STM32、C51驱动,可PIN TO PIN软硬件兼容SHT30/SHT31
一、资源说明
二、基本参数
三、参考驱动
四、注意事项


一、资源说明
GXHT3x系列温湿度芯片,是新型高精度单芯片集成温湿度传感IC是“在硅基CMOS晶圆上集成高灵敏度MEMS湿敏元件,把温度补偿和标定数据都集成在一个电路里”,实现湿敏电容结构和信号处理电路的单芯片集成,减少并降低了传感器的体积和成本,同时降低信号传输带来的干扰,提高产品精度、可靠性、一致性。
GXHT30x系列温湿度芯片,包含IIC通信协议芯片GXHT30、GXHT31;单总线通信协议GXHT3W。两款芯片均有防尘透气膜、可喷三防漆膜版本可选。
二、基本参数
| 产品型号 | GXHT30 |
| 通信方式 | IIC-bus |
| 分辨率 | 16bit ADC |
| 封装大小 | 2.5mm × 2.5mm x 0.9mm (DFN-8) |
| 工作电压 | 2.5~5.5V |
| 工作范围 | -45~130℃ |
| 温度精度(典型) | ±0.3°C (-40°C ~ 90°C) |
| 湿度精度(典型) | ±3% (10% ~ 90%) |
| IIC地址 | 0x44、0x45可选 |
| 平均功耗 | 2uA(@3.3V) |
| 空闲状态 | 0.2uA(@3.3V) |
| 抗静电能力 | 8KV(HBM),850V(CDM) |
三、参考驱动
通信时序


驱动实例
1、STM32F103 + GXHT30/GXHT31温湿度芯片驱动实例
STM32 GXHT30.h文件
#ifndef _GXHT30_H
#define _GXHT30_H
#include "stm32f10x.h"
#include "string.h"
#include "stdio.h"
extern float GXHT30_temp;
//如果移植程序时只要改一下三个地方就行了
#define GXHT30_SCL GPIO_Pin_5 //SCL-PA5
#define GXHT30_SDA GPIO_Pin_6 //SDA-PA6
#define GPIO_GXHT30 GPIOA
#define GXHT30_SCL_H GPIO_SetBits(GPIO_GXHT30,GXHT30_SCL)
#define GXHT30_SCL_L GPIO_ResetBits(GPIO_GXHT30,GXHT30_SCL)
#define GXHT30_SDA_H GPIO_SetBits(GPIO_GXHT30,GXHT30_SDA)
#define GXHT30_SDA_L GPIO_ResetBits(GPIO_GXHT30,GXHT30_SDA)
/* 声明全局函数 */
void GXHT30_INIT(void);
void GXHT30_SDA_OUT(void);
void GXHT30_SDA_IN(void);
void GXHT30_SDA_in(void);
void GXHT30_StarT(void);
void GXHT30_StoP(void);
void GXHT30_Ack(void);
void GXHT30_NAck(void);
u8 GXHT30_Wait_Ack(void);
void GXHT30_Send_Byte(u8 txd);
u8 GXHT30_Read_Byte(u8 ack);
void GXHT30_read_result(u8 addr);
void al_get_gxth30_temp(void);
#endif
STM32 GXHT30.c文件
#include "GXHT30.h"
#include "delay.h"
#define write 0
#define read 1
//定义全局变量
float GXHT30_temp,GXHT30_humi,GXHT30_Temperature,GXHT30_Humidity;
/*
* @name CRC_8
* @brief CRC-8校验
* @param Crc_ptr -> 校验数据首地址
L EN -> 校验数据长度
* @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 : GXHT30_INIT
* Description : 初始化GPIO.
****************************************************************************/
void GXHT30_INIT()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStructure.GPIO_Pin=GXHT30_SDA;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;
GPIO_Init(GPIOA,&GPIO_InitStructure);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStructure.GPIO_Pin=GXHT30_SCL;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GXHT30_SCL_H;
GXHT30_SDA_H;
}
/*******************************************************************************
* 函 数 名 : GXHT30_SDA_OUT
* 函数功能 : SDA输出配置
*******************************************************************************/
void GXHT30_SDA_OUT()
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=GXHT30_SDA;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;
GPIO_Init(GPIOA,&GPIO_InitStructure);
}
/*******************************************************************************
* 函 数 名 : GXHT30_SDA_IN
* 函数功能 : SDA输入配置
*******************************************************************************/
void GXHT30_SDA_IN(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=GXHT30_SDA;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_OD;
GPIO_Init(GPIOA,&GPIO_InitStructure);
}
void GXHT30_SDA_in(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=GXHT30_SDA;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
GPIO_Init(GPIOA,&GPIO_InitStructure);
}
/*******************************************************************************
* 函 数 名 : GXHT30_StarT
* 函数功能 : IIC起始信号
*******************************************************************************/
void GXHT30_StarT(void)
{
GXHT30_SDA_OUT();
GXHT30_SDA_H;
GXHT30_SCL_H;
delay_us(5);
GXHT30_SDA_L;
delay_us(6);
GXHT30_SCL_L;
}
/*******************************************************************************
* 函 数 名 : GXHT30_StoP
* 函数功能 : 产生停止信号
*******************************************************************************/
void GXHT30_StoP(void)
{
GXHT30_SDA_OUT();
GXHT30_SCL_L;
GXHT30_SDA_L;
GXHT30_SCL_H;
delay_us(6);
GXHT30_SDA_H;
delay_us(6);
}
/*******************************************************************************
* 函 数 名 : GXHT30_Ack
* 函数功能 : 主机产生应答信号ACK
*******************************************************************************/
void GXHT30_Ack(void)
{
GXHT30_SCL_L;
GXHT30_SDA_OUT();
GXHT30_SDA_L;
delay_us(2);
GXHT30_SCL_H;
delay_us(5);
GXHT30_SCL_L;
}
/*******************************************************************************
* 函 数 名 : GXHT30_NAck
* 函数功能 : 主机不产生应答信号NACK
*******************************************************************************/
void GXHT30_NAck(void)
{
GXHT30_SCL_L;
GXHT30_SDA_OUT();
GXHT30_SDA_H;
delay_us(2);
GXHT30_SCL_H;
delay_us(5);
GXHT30_SCL_L;
}
/*******************************************************************************
* 函 数 名 : GXHT30_Wait_Ack
* 函数功能 : 等待从机应答信号
返回值: 1 接收应答失败
0 接收应答成功
*******************************************************************************/
u8 GXHT30_Wait_Ack(void)
{
u8 tempTime=0;
GXHT30_SDA_IN();
GXHT30_SDA_H;
delay_us(1);
GXHT30_SCL_H;
delay_us(1);
while(GPIO_ReadInputDataBit(GPIO_GXHT30,GXHT30_SDA))
{
tempTime++;
delay_us(1);
if(tempTime>250)
{
GXHT30_StoP();
return 1;
}
}
GXHT30_SCL_L;
delay_us(1);
return 0;
}
/*******************************************************************************
* 函 数 名 : GXHT30_Send_Byte
* 函数功能 : 主机发送一个字节
*******************************************************************************/
void GXHT30_Send_Byte(u8 txd)
{
u8 i=0;
GXHT30_SDA_OUT();
GXHT30_SCL_L; //拉低时钟开始数据传输
for(i=0;i<8;i++)
{
if((txd&0x80)>0) //0x80 1000 0000
GXHT30_SDA_H;
else
GXHT30_SDA_L;
txd<<=1;
delay_us(1);
GXHT30_SCL_H;
delay_us(2);
GXHT30_SCL_L;
delay_us(2);
}
}
/*******************************************************************************
* 函 数 名 : GXHT30_Read_Byte
* 函数功能 : 主机读取一个字节
*******************************************************************************/
u8 GXHT30_Read_Byte(u8 ack)
{
u8 i=0,receive=0;
GXHT30_SDA_in();
for(i=0;i<8;i++)
{
GXHT30_SCL_L;
delay_us(2);
GXHT30_SCL_H;
while(!GPIO_ReadInputDataBit(GPIO_GXHT30,GXHT30_SCL));
receive<<=1;
if(GPIO_ReadInputDataBit(GPIO_GXHT30,GXHT30_SDA))
receive++;
delay_us(1);
}
if(ack==0)
GXHT30_NAck();
else
GXHT30_Ack();
return receive;
}
/*******************************************************************************
* 函 数 名 : GXHT30_read_result
* 函数功能 : 读数据 addr->0x44 0x45
*******************************************************************************/
void GXHT30_read_result(u8 addr)
{
u16 tem,hum;
unsigned char buff[6];
float Temperature=0;
float Humidity=0;
GXHT30_StarT();
GXHT30_Send_Byte(addr<<1 | write);//写7位GXHT30设备地址加0作为写取位,1为读取位
GXHT30_Wait_Ack();
GXHT30_Send_Byte(0x2C);
GXHT30_Wait_Ack();
GXHT30_Send_Byte(0x10);
GXHT30_Wait_Ack();
GXHT30_StoP();
delay_ms(15); //数据转换
GXHT30_StarT();
GXHT30_Send_Byte(addr<<1 | read);//写7位GXHT30设备地址加0作为写取位,1为读取位
if(GXHT30_Wait_Ack()==0)
{
GXHT30_SDA_in();
buff[0]=GXHT30_Read_Byte(1);
buff[1]=GXHT30_Read_Byte(1);
buff[2]=GXHT30_Read_Byte(1);
buff[3]=GXHT30_Read_Byte(1);
buff[4]=GXHT30_Read_Byte(1);
buff[5]=GXHT30_Read_Byte(0);
GXHT30_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 = (100.0*(float)hum/65535.0);// RH = hum*100 / (2^16-1)
}
else
{
GXHT30_temp = 0;
GXHT30_humi = 0;
}
}
if((Temperature>=-20)&&(Temperature<=125)&&(Humidity>=0)&&(Humidity<=100))//过滤错误数据
{
GXHT30_temp = Temperature;
GXHT30_humi = Humidity;
}
tem = 0;
hum = 0;
}
/*******************************************************************************
* 函 数 名 : al_float_buffer_sort
* 函数功能 : 多次读数值排序取中间值平均
*******************************************************************************/
void al_float_buffer_sort(float *buf, uint8_t length)
{
uint8_t i, j;
float tmp;
for (i = 0; i < length; i++)
{
for (j = i + 1; j < length; j++)
{
if (buf[j] < buf[i])
{
tmp = buf[j];
buf[j] = buf[i];
buf[i] = tmp;
}
}
}
}
void al_get_gxth30_temp(void)
{
float buff_temp[20],buff_humi[20];
for(u8 i = 0;i < 10;i++)
{
GXHT30_read_result(0x44);
buff_temp[i] = GXHT30_temp;
buff_humi[i] = GXHT30_humi;
}
al_float_buffer_sort(buff_temp,10);
al_float_buffer_sort(buff_humi,10);
GXHT30_Temperature = (buff_temp[4] + buff_temp[5]) / 2;
GXHT30_Humidity = (buff_humi[4] + buff_humi[5]) / 2;
printf("温度:%0.2f, 湿度:%0.2f",GXHT30_Temperature,GXHT30_Humidity);
}
2、C51 + GXHT30/GXHT31温湿度芯片驱动实例
C51 GXHT30.h文件
#ifndef _gxht30_H_
#define _gxht30_H_
#include "main.h"
sbit SCL = P3^2; //I2C时钟线
sbit SDA = P3^3; //I2C数据线
#define ACK 0
#define NACK 1
extern float Temp,Humi;
// Error codes
typedef enum{
NO_ERROR = 0x00, // no error
ACK_ERROR = 0x01, // no acknowledgment error
CHECKSUM_ERROR = 0x02, // checksum mismatch error
TIMEOUT_ERROR = 0x04, // timeout error
PARM_ERROR = 0x80, // parameter out of range error
}etError;
extern etError error;
// Sensor Commands
typedef enum
{
CMD_MEAS_CLOCKSTR_H = 0x2C06, // meas. clock stretching, high rep.
CMD_MEAS_CLOCKSTR_M = 0x2C0D, // meas. clock stretching, medium rep.
CMD_MEAS_CLOCKSTR_L = 0x2C10, // meas. clock stretching, low rep.
CMD_MEAS_POLLING_H = 0x2400, // meas. no clock stretching, high rep.
CMD_MEAS_POLLING_M = 0x240B, // meas. no clock stretching, medium rep.
CMD_MEAS_POLLING_L = 0x2416, // meas. no clock stretching, low rep.
}etCommands;
#define gxht30ADDR 0x44 //gxht30的I2C地址 0s44/0x45
#define gxht30WriteHeader gxht30ADDR << 1
#define gxht30ReadHeader gxht30WriteHeader | 1
extern void sys_iic_init(void);
extern etError gxht30_XHGetTempAndHumi(float *temp,
float *humi);
extern void al_get_gxthc3_tempandhumi(void);
#endif
C51 GXHT30.c文件
#include "gxht30.h"
#include <intrins.h>
#include <stdio.h>
include "delay.h"
#include "io.h"
etError error;
//定义全局温湿度变量
float gxht30_temp_val,gxht30_humi_val;
void sys_iic_init(void)
{
P3CR = 0x0C; //PxCR=0是输入,=1是输出
P3PCR = 0x0C;
SCL = 1; //I2C时钟线
SDA = 1; //I2C数据线
}
#define POLYNOMIAL 0x31 // P(x) = x^8 + x^5 + x^4 + 1 = 00110001
//CRC校验函数
unsigned char gxht30_CalcCrc(unsigned char *crcdata, unsigned char nbrOfBytes)
{
unsigned char Bit; // bit mask
unsigned char crc = 0xFF; // calculated checksum
unsigned char byteCtr; // byte counter
// calculates 8-Bit checksum with given polynomial
for(byteCtr = 0; byteCtr < nbrOfBytes; byteCtr++)
{
crc ^= (crcdata[byteCtr]);
for(Bit = 8; Bit > 0; --Bit)
{
if(crc & 0x80) crc = (crc << 1) ^ POLYNOMIAL;
else crc = (crc << 1);
}
}
return crc;
}
///*******延时函数、可自行适当调整*************/
void delay_5us(void)
{
uint8_t i;
for(i=0;i<3;i++);
}
///*******I2C总线启动函数*************/
void I2C_Start(void)
{
SDA = 1;
delay_5us();
SCL = 1;
delay_5us();
SDA = 0;
delay_5us();
SCL = 0;
delay_5us();
}
///*******I2C总线停止函数*************/
void I2C_Stop(void)
{
SDA = 0;
SCL = 0;
delay_5us();
SCL = 1;
delay_5us();
SDA = 1;
delay_5us();
}
///*================================================================
//【名 称】unsigned char I2CWRByte(unsigned char WRByte)
//【功 能】I2C写一个字节数据,返回ACK或者NACK
//【备 注】从高到低,依次发送
//================================================================*/
etError I2CWRByte(unsigned char WRByte)
{
unsigned char i;
P3CR = 0xFF; //设置SDA输出
SCL = 0;
for(i=0;i<8;i++)
{
if(WRByte&0x80)
{
SDA = 1;
}
else
{
SDA = 0;
}
delay_5us();
SCL=1; //输出SDA稳定后,拉高SCL给出上升沿,从机检测到后进行数据采样
delay_5us();
SCL=0;
delay_5us();
WRByte <<= 1;
}
SDA = 1;
SCL = 1;
delay_5us();
if(SDA==1) //SDA为高,收到NACK
{
SCL=0;
delay_5us();
return NO_ERROR;
}
else //SDA为低,收到ACK
{
SCL=0;
delay_5us();
return ACK_ERROR;
}
}
///*================================================================
//【名 称】unsigned char I2CRDByte(unsigned char AckValue)
//【功 能】I2C读一个字节数据,入口参数用于控制应答状态,ACK或者NACK
//【备 注】从高到低,依次接收
//================================================================*/
unsigned char I2CRDByte(unsigned char AckValue)
{
unsigned char i,RDByte=0;
P3CR = 0xF7; //设置SCL输入
SCL = 0;
SDA = 1; //释放总线
for (i=0;i<8;i++)
{
RDByte <<= 1; //移位
SCL = 1; //给出上升沿
delay_5us(); //延时等待信号稳定
if(SDA==1) //采样获取数据
{
RDByte |= 0x01;
}
else
{
RDByte &= 0xfe;
}
SCL = 0; //下降沿,从机给出下一位值
delay_5us();
}
P3CR = 0xFF;
SDA = AckValue; //应答状态
delay_5us();
SCL = 1;
delay_5us();
SCL = 0;
SDA = 1;
delay_5us();
return RDByte;
}
etError gxht30_WriteCommand(etCommands cmd)
{
etError error; // error code
// write the upper 8 bits of the command to the sensor
error = I2CWRByte(cmd >> 8);
// write the lower 8 bits of the command to the sensor
error |= I2CWRByte(cmd & 0xFF);
return error;
}
///*================================================================
//【名 称】gxht30_XHGetTempAndHumi(float *temp,
float *humi)
//【功 能】读数据
//【备 注】读6位数据,最后一位发送NACK,停止IIC通信
//================================================================*/
etError gxht30_XHGetTempAndHumi(float *temp,
float *humi)
{
float rawValueTemp,rawValueHumi; // temperature raw value from sensor
unsigned char i;
unsigned char buff[6];
I2C_Start();
error = I2CWRByte(gxht30WriteHeader);
// if no error ...
if(error == NO_ERROR)
{
error = gxht30_WriteCommand(CMD_MEAS_CLOCKSTR_H);
I2C_Stop();
}
delay_ms(15); //数据转换,该延时是必须的
if(error == NO_ERROR)
{
I2C_Start();
error = I2CWRByte(gxht30ReadHeader);
}
// if no error, read temperature and humidity raw values
if(error == NO_ERROR)
{
for(i=0;i<5;i++)
{
buff[i] = I2CRDByte(ACK);
}
buff[i] = I2CRDByte(NACK);
I2C_Stop();
if(buff[2]!=gxht30_CalcCrc(buff,2)) error = CHECKSUM_ERROR;
if(buff[5]!=gxht30_CalcCrc(&buff[3],2)) error = CHECKSUM_ERROR;
}
// if no error, calculate temperature in and humidity in %RH
if(error == NO_ERROR)
{
rawValueTemp =(buff[0] * 256) + buff[1];
rawValueHumi =(buff[3] * 256) + buff[4];
*temp =175.0 * rawValueTemp / 65535 - 45.0;
*humi =100 * rawValueHumi / 65535;
}
rawValueTemp = 0;
rawValueHumi = 0;
return error;
}
/*******************************************************************************
* 函 数 名 : al_float_buffer_sort
* 函数功能 : 多次读数值排序取中间值平均
*******************************************************************************/
void al_float_buffer_sort(float *buf, uint8_t length)
{
uint8_t i, j;
float tmp;
for (i = 0; i < length; i++)
{
for (j = i + 1; j < length; j++)
{
if (buf[j] < buf[i])
{
tmp = buf[j];
buf[j] = buf[i];
buf[i] = tmp;
}
}
}
}
void al_get_gxth30_tempandhumi(void)
{
float buff_temp[4],buff_humi[4];
uint8_t i;
for(i = 0;i < 4;i++)
{
gxht30_XHGetTempAndHumi(&gxht30_temp_val,&gxht30_humi_val);
buff_temp[i] = gxht30_temp_val;
buff_humi[i] = gxht30_humi_val;
}
al_float_buffer_sort(buff_temp,4);
al_float_buffer_sort(buff_humi,4);
gxht30_temp_val = (buff_temp[1] + buff_temp[2]) / 2;
gxht30_humi_val = (buff_humi[2] + buff_humi[2]) / 2;
}
四、注意事项
1、IIC总线SCL、SDA必须加1~10K上拉电阻,一般建议选4.7K或者10K;
2、主机发送完数据转换命令,必须加一定的延时(参考规格书),确保芯片完成数据转换,再读数据;
3、主机读6个字节数据,最好加上CRC校验,确保数据没问题,最后一个字节发送NACK,终止IIC通信。
友情提示:欢迎各位小伙伴交流应用GXHT30温湿度芯片
TEL:13128272535
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)