社区导航

 

搜索
查看: 266|回复: 2

[环境传感器] GD32E231模拟IIC驱动HTS221

[复制链接]

76

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2019-8-3 16:08 | 显示全部楼层 |阅读模式

HTS221是温湿度传感器。依然使用IIC操作。

 

原理图,如下,IIC地址0xBE:

 

2.jpg

 


寄存器:

1.jpg

这个芯片操作寄存器还是比较简单的,但是最开始的时候需要对芯片将进行设置.

AV_CONF寄存器:这个可以根据自己的需求进行设置,我设置的是0x09:

5.jpg

CTRL1寄存器:设置电源启动。我设置的是0x81.

6.jpg

上述的两个寄存器比较重要,需要设置一下。

 

Humidity读取寄存器,16位数据

7.jpg

 

temperature读取寄存器,16位数据:

8.jpg

芯片的标志:0xB3。

4.jpg

后面还有温度,湿度的计算补偿寄存器等,这个对计算温湿度很重要:

3.jpg

我看了一下这个,没太明白,所以我只对输出的温湿度寄存器进行了读取,显示的是16进制的数据,没有进行温湿度转换,需要转换的话是需要最后面的这些寄存器一起使用的,操作起来还是比较复杂的,所以暂时没有进行计算,等以后有时间了在慢慢弄,下面是补偿说明。

 

9.jpg


 

代码:

初始化:

//初始化传感器LPS22HH
	if(0 == Set_Reg_HTS221(HTS221_ADDR_W_1, HTS221_AV_CONF, 0x09u))  //0x09
	{
		send_str((unsigned char *)"IF_CTRL set successful\r\n");
	}
	else
	{
		send_str((unsigned char *)"IF_CTRL set fail\r\n");
	}
	
	if(0 == Set_Reg_HTS221(HTS221_ADDR_W_1, HTS221_REG_CTRL_1, 0x81u))
	{
		send_str((unsigned char *)"CTRL_1 set successful\r\n");
	}
	else
	{
		send_str((unsigned char *)"CTRL_1 set fail\r\n");
	}

 

//HTS221写
static int IIC_WrDat_HTS221(uint8_t IIC_Add, uint8_t IIC_Reg, uint8_t IIC_Data)
{
	uint8_t ret_suc = 1;
	
	IIC_Start();
	IIC_Send_Byte(IIC_Add & 0xfe);
	ret_suc = IIC_Wait_Ack();
	if(ret_suc == 1)	{IIC_Stop();return -1;}
	
	IIC_Send_Byte(IIC_Reg);			//write data
	ret_suc = IIC_Wait_Ack();
	if(ret_suc == 1)	{IIC_Stop();return -1;}
	
	IIC_Send_Byte(IIC_Data);
	ret_suc = IIC_Wait_Ack();
	if(ret_suc == 1)	{IIC_Stop();return -1;}	
	
	IIC_Stop();
	
	return 0;
}


//HTS221读
static int IIC_Read_HTS221(uint8_t IIC_Add, uint8_t IIC_Reg)
{
	int ret;
	uint8_t ret_suc = 1;
	
	IIC_Start();
	IIC_Send_Byte(IIC_Add & 0xfe);
	ret_suc = IIC_Wait_Ack();
	if(ret_suc == 1)	{IIC_Stop();return -1;}
		
	IIC_Send_Byte(IIC_Reg);
	ret_suc = IIC_Wait_Ack();
	if(ret_suc == 1)	{IIC_Stop();return -1;}
		
	IIC_Start();
	IIC_Send_Byte(IIC_Add | 0x01);
	ret_suc = IIC_Wait_Ack();
	if(ret_suc == 1)	{IIC_Stop();return -1;}
	
    ret=IIC_Read_Byte(1);
	IIC_Stop();

	return ret;
}

//设置寄存器
int Set_Reg_HTS221(uint8_t add, uint8_t reg, uint8_t dat)
{
	int ret_succ = -1;
	uint8_t i = 20u;		//失败之后尝试的次数
	
	do{
		if(0 == IIC_WrDat_HTS221(add, reg, dat))
		{
			ret_succ = 0;		//设置成功
			break;
		}
		else
		{
			i--;				//获取失败,再次尝试
		}
	}while(i>0u);
	
	return ret_succ;
}

//读取寄存器
int Get_Reg_HTS221(uint8_t add, uint8_t reg)
{
	uint8_t i = 20u;
	int ret_get = -1;
	
	do{
		ret_get = IIC_Read_HTS221(add, reg);
		if(-1 != ret_get)
		{
			break;				//获取数据成功
		}
		else
		{
			i--;				//获取失败,再次尝试
		}
	}while(i>0u);
	
	return ret_get;
}

//读取我是谁
int Get_WHO_AM_I_HTS221(void)
{
	return Get_Reg_HTS221(HTS221_ADDR_W_1, HTS221_REG_WHO_AM_I);	
}


//获取状态寄存器
int Get_Status_HTS221(void)
{
	return Get_Reg_HTS221(HTS221_ADDR_W_1, HTS221_REG_STATUS);	
}

//获取压力值L
int Get_Humidity_L_HTS221(void)
{
	return Get_Reg_HTS221(HTS221_ADDR_W_1, HTS221_REG_HUMI_OUT_L);	
}

//获取压力值H
int Get_Humidity_H_HTS221(void)
{
	return Get_Reg_HTS221(HTS221_ADDR_W_1, HTS221_REG_HUMI_OUT_H);	
}

float Get_Humidity_HTS221(void)
{
	static float Last_return_p = 0.0f;
	int get_p;
	
	if((Get_Humidity_H_HTS221() != -1)
		&&(Get_Humidity_L_HTS221() != -1))
	{
		get_p = (Get_Humidity_H_HTS221()<<8)|(Get_Humidity_L_HTS221());
		//Last_return_p = ((float)get_p / 4096.0f);
		Last_return_p = get_p; 
	}
	else
	{
		
	}
	return Last_return_p;
}

//获取温度值H
int Get_Temp_L_HTS221(void)
{
	return Get_Reg_HTS221(HTS221_ADDR_W_1, HTS221_REG_TEMP_OUT_L);	
}

//获取温度值H
int Get_Temp_H_HTS221(void)
{
	return Get_Reg_HTS221(HTS221_ADDR_W_1, HTS221_REG_TEMP_OUT_H);	
}

float Get_Temp_HTS221(void)
{
	static float Last_return_t = 0.0f;
	int get_t;
	
	if((Get_Temp_H_HTS221() != -1)
		&&(Get_Temp_L_HTS221() != -1))
	{
		get_t = (Get_Temp_H_HTS221()<<8)|(Get_Temp_L_HTS221());
//		Last_return_t = ((float) get_t / 100.0f);
		Last_return_t = get_t;
	}
	else
	{
		
	}
	return Last_return_t;
}

//发送数据到串口
void Send_Uart_HTS221(void)
{	
	char str[35] = {0};
	
	send_str((uint8_t *)"<-----------START--------->\r\n");		
	sprintf(str,"Humidity:%X\r\n", (int)Get_Humidity_HTS221());
	send_str((uint8_t *)str);	

	sprintf(str,"Temp:%X\r\n", (int)Get_Temp_HTS221());
	send_str((uint8_t *)str);		
	
	sprintf(str,"Who_am_i:%X\r\n",Get_WHO_AM_I_HTS221());			
	send_str((uint8_t *)str);			
	send_str((uint8_t *)"<------------END---------->\r\n\n");			
}

//显示数据到OLED
void OLED_Display_HTS221(void)
{
	char str_dis1[20], str_dis2[20], str_dis3[20];
	
	OLED_Clear();
	sprintf(str_dis1,"Pressure:%.2f\r\n", Get_Humidity_HTS221());
	sprintf(str_dis2,"Temp:%.2f\r\n", Get_Temp_HTS221());
	sprintf(str_dis3,"Who_am_i:%X\r\n",Get_WHO_AM_I_HTS221());	
	OLED_ShowString(0,16,(uint8_t *)str_dis1,16,1);
	OLED_ShowString(0,32,(uint8_t *)str_dis2,16,1);
	OLED_ShowString(0,48,(uint8_t *)str_dis3,16,1);
	OLED_Refresh_Gram();
}

 

宏定义:

/*register address*/
#define HTS221_REG_WHO_AM_I		(0x0FU)

#define HTS221_AV_CONF			(0x10U)
#define HTS221_REG_CTRL_1		(0x20U)
#define HTS221_REG_CTRL_2		(0x21U)
#define HTS221_REG_CTRL_3		(0x22U)

#define HTS221_REG_STATUS		(0x27U)

#define HTS221_REG_HUMI_OUT_L	(0x28U)
#define HTS221_REG_HUMI_OUT_H	(0x29U)

#define HTS221_REG_TEMP_OUT_L 	(0x2AU)
#define HTS221_REG_TEMP_OUT_H	(0x2BU)

#define HTS221_REG_H0_rH_x2		(0x30U)
#define HTS221_REG_H1_rH_x2		(0x31U)

#define HTS221_REG_T0_degC_x8	(0x32U)
#define HTS221_REG_T1_degC_x8	(0x33U)
#define HTS221_REG_T1_T0 	 	(0x35U)

#define HTS221_REG_H0_T0_OUT1	(0x36U)
#define HTS221_REG_H0_T0_OUT2	(0x37U)

#define HTS221_REG_H1_T0_OUT1	(0x3AU)
#define HTS221_REG_H1_T0_OUT2	(0x3BU)

#define HTS221_REG_T0_OUT1		(0x3CU)
#define HTS221_REG_T0_OUT2		(0x3DU)

#define HTS221_REG_T1_OUT1		(0x3EU)
#define HTS221_REG_T1_OUT2		(0x3FU)


	
/*IIC slave address write and read*/
#define HTS221_ADDR_W_1			0xBEU
#define HTS221_ADDR_R_1			0xBFU


 

效果展示:

上面已经说了,我没有对采集的数据做计算,只展示了获取的寄存器的信息:

 

10.jpg

 

 

来源:EEWorld ST传感器与低功耗无线技术论坛板块,转载请附上链接


回复

使用道具 举报

8459

TA的帖子

14

TA的资源

版主

Rank: 6Rank: 6

测评达人

发表于 2019-8-3 17:47 | 显示全部楼层

传感器的T0/T1两组寄存器,给出了预先标定的数据。传感器测量出的数据,需要根据T0/T1进行线性插值,计算后才是实际的温度。

 

湿度也是同样的方式。

点评

多谢赐教,这个地方我还需要在研究研究,谢谢  详情 回复 发表于 2019-8-3 20:01


回复

使用道具 举报

76

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

 楼主| 发表于 2019-8-3 20:01 | 显示全部楼层
dcexpert 发表于 2019-8-3 17:47 传感器的T0/T1两组寄存器,给出了预先标定的数据。传感器测量出的数据,需要根据T0/T1进行线性插值,计算后 ...

多谢赐教,这个地方我还需要在研究研究,谢谢



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

关闭

站长推荐上一条 /3 下一条

  • 论坛活动 E手掌握

    扫码关注
    EEWORLD 官方微信

  • EE福利  唾手可得

    扫码关注
    EE福利 唾手可得

Archiver|手机版|小黑屋|电子工程世界 ( 京ICP证 060456 )

GMT+8, 2019-8-23 00:26 , Processed in 0.121805 second(s), 18 queries , Gzip On, MemCache On.

快速回复 返回顶部 返回列表