3650|2

282

帖子

2

TA的资源

一粒金砂(高级)

楼主
 

GD32E231模拟IIC驱动LPS22HH [复制链接]

 

上周尝试了STTS7551温度传感器(传送门:GD32E231模拟IIC驱动STTS751),之后就开始尝试LPS22HH传感器。

从原理图上面看都是连接在同样的IIC总线上的,都是IIC1,但是使用同样的程序修改了地址止之后始终都运行不了,如下图:

 

使用stts751一样的程序,修改了地址和寄存器名字之后就是用不了了,这个问题困扰了我好几天,最后实在没办法就按照下图的方式将传感器和单片机相应的引脚都连接在一起之后发现可以正常的读取了。我也不知道是什么原因?有没高手给解答一下?

 

连接图如下,线接的有点乱,按照顺序接好就行了:

 

这个时候虽然可以正常的接收到数据了,但是又有了一个问题,我是没1s钟接收一次数据,但是数据时好时坏,就比如读取ID:B3,有时候可以正常的读取B3,有时候就读取不出来,我的IIC通信应该是没有问题的呀,应该连接的OLED是正常的显示的,没有显示过错误,而且上次使用STTS7551的时候也是正常的,不知道原因出在哪里,期望得到高手的解答,谢谢

 


寄存器总数:

其中需要进行设置,参考寄存器:

控制寄存器IF_CTRL,这个寄存器设置IIC操作的,我设置的值是0x1A,也就是设置了上拉电阻和使用的I2C

寄存器WHO_AM_I,这个寄存器是身份识别的,为0xB3

 

控制寄存器CTRL_REG1,这个需要设置一下,需要将ODR[2:0]设置一下,不然的话只能用触发的方式获取数据,我这是的001,每一秒钟更新一次数据。

 

获取压力数据的寄存器,压力数据是24为的,直接获取三位寄存器的值在进行计算就行了,Get_Pressure_H_LPS22HH()<<16)|(Get_Pressure_L_LPS22HH()<<8)|(Get_Pressure_XL_LPS22HH()

 

获取温度数据也是一样的,温度数据是16位的,需要除以100,才是正常的温度值:(Get_Temp_H_LPS22HH()<<8)|(Get_Temp_L_LPS22HH())

 

 


读写IIC:

//LPS22HH写
static int IIC_WrDat_LPS22HH(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)	{return -1;}
	
	IIC_Send_Byte(IIC_Reg);			//write data
	ret_suc = IIC_Wait_Ack();
	if(ret_suc == 1)	{return -1;}
	
	IIC_Send_Byte(IIC_Data);
	ret_suc = IIC_Wait_Ack();
	if(ret_suc == 1)	{return -1;}	
	
	IIC_Stop();
	
	return 0;
}


//LPS22HH读
static int IIC_Read_LPS22HH(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)	{return -1;}
		
	IIC_Send_Byte(IIC_Reg);
	ret_suc = IIC_Wait_Ack();
	if(ret_suc == 1)	{return -1;}
		
	IIC_Start();
	IIC_Send_Byte(IIC_Add | 0x01);
	ret_suc = IIC_Wait_Ack();
	if(ret_suc == 1)	{return -1;}
	
    ret=IIC_Read_Byte(1);
	IIC_Stop();

	return ret;
}

 

 

介于上面读取的数据时好时坏,所以我对最后的读取数据和设置数据的代码改变了一下,不再是直接的简单的读取,增加了判断,如果读取的数据不正确的话,就在读取,知道连续20次读取出错之后才会退出,如下:

修改的读写操作:

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

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

 

寄存器的操作:

//读取我是谁
int Get_WHO_AM_I_LPS22HH(void)
{
	return Get_Reg_LPS22HH(LPS22HH_ADDR_W_1, LPS22HH_REG_WHO_AM_I);	
}


//获取状态寄存器
int Get_Status_LPS22HH(void)
{
	return Get_Reg_LPS22HH(LPS22HH_ADDR_W_1, LPS22HH_REG_STATUS);	
}

//获取压力值XL
int Get_Pressure_XL_LPS22HH(void)
{
	return Get_Reg_LPS22HH(LPS22HH_ADDR_W_1, LPS22HH_REG_PRE_OUT_XL);	
}

//获取压力值L
int Get_Pressure_L_LPS22HH(void)
{
	return Get_Reg_LPS22HH(LPS22HH_ADDR_W_1, LPS22HH_REG_PRE_OUT_L);	
}

//获取压力值H
int Get_Pressure_H_LPS22HH(void)
{
	return Get_Reg_LPS22HH(LPS22HH_ADDR_W_1, LPS22HH_REG_PRE_OUT_H);	
}

float Get_Pressure(void)
{
	static float Last_return_p = 0.0f;
	int get_p;
	
	if((Get_Pressure_H_LPS22HH() != -1)
		&&(Get_Pressure_L_LPS22HH() != -1)
		&&(Get_Pressure_XL_LPS22HH() != -1))
	{
		get_p = (Get_Pressure_H_LPS22HH()<<16)|(Get_Pressure_L_LPS22HH()<<8)|(Get_Pressure_XL_LPS22HH());
		Last_return_p = ((float)get_p / 4096.0f);
	}
	else
	{
		
	}
	return Last_return_p;
}

//获取温度值H
int Get_Temp_L_LPS22HH(void)
{
	return Get_Reg_LPS22HH(LPS22HH_ADDR_W_1, LPS22HH_REG_TEMP_OUT_L);	
}

//获取温度值H
int Get_Temp_H_LPS22HH(void)
{
	return Get_Reg_LPS22HH(LPS22HH_ADDR_W_1, LPS22HH_REG_TEMP_OUT_H);	
}

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

 

初始化LPS22HH:

//初始化传感器LPS22HH
	if(0 == Set_Reg_LPS22HH(LPS22HH_ADDR_W_1, LPS22HH_REG_IF_CTRL, 0x1A))
	{
		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_LPS22HH(LPS22HH_ADDR_W_1, LPS22HH_REG_CTRL_1, 0x18))
	{
		send_str((unsigned char *)"CTRL_1 set successful\r\n");
	}
	else
	{
		send_str((unsigned char *)"CTRL_1 set fail\r\n");
	}

 

 

串口发送数据和OLED显示:

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

	sprintf(str,"Temp:%f\r\n", Get_Temp());
	send_str((uint8_t *)str);		
	
	sprintf(str,"Who_am_i:%X\r\n",Get_WHO_AM_I_LPS22HH());			
	send_str((uint8_t *)str);			
	send_str((uint8_t *)"<------------END---------->\r\n\n");			
}

//显示数据到OLED
void OLED_Display_LPS22HH(void)
{
	char str_dis1[20], str_dis2[20], str_dis3[20];
	
	OLED_Clear();
	sprintf(str_dis1,"Pressure:%.2f\r\n", Get_Pressure());
	sprintf(str_dis2,"Temp:%.2f\r\n", Get_Temp());
	sprintf(str_dis3,"Who_am_i:%X\r\n",Get_WHO_AM_I_LPS22HH());	
	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();
}

 

.h文件中的宏定义:

 

#define LPS22HH_REG_INT_CFG  	(0x0BU)
#define LPS22HH_REG_THS_P_L  	(0x0CU)
#define LPS22HH_REG_THS_P_H		(0x0DU)
#define LPS22HH_REG_IF_CTRL		(0x0EU)

#define LPS22HH_REG_WHO_AM_I	(0x0FU)
#define LPS22HH_REG_CTRL_1		(0x10U)
#define LPS22HH_REG_CTRL_2		(0x11U)
#define LPS22HH_REG_CTRL_3		(0x12U)

#define LPS22HH_REG_REF_P_L		(0x15U)
#define LPS22HH_REG_REF_P_H		(0x16U)
#define LPS22HH_REG_RPDS_L		(0x18U)
#define LPS22HH_REG_RPDS_H 		(0x19U)
#define LPS22HH_REG_INT_SOURCE	(0x24U)

#define LPS22HH_REG_STATUS		(0x27U)
#define LPS22HH_REG_PRE_OUT_XL	(0x28U)
#define LPS22HH_REG_PRE_OUT_L	(0x29U)
#define LPS22HH_REG_PRE_OUT_H	(0x2AU)

#define LPS22HH_REG_TEMP_OUT_L 	(0x2BU)
#define LPS22HH_REG_TEMP_OUT_H	(0x2CU)

	
/*IIC slave address write and read*/
/*SD0 connect to power supply*/
#define LPS22HH_ADDR_W_1			0xBAU
#define LPS22HH_ADDR_R_1			0xBBU
/*SD0 connect to ground*/
#define LPS22HH_ADDR_W_0			0xB8U
#define LPS22HH_ADDR_R_0			0xB9U

 


显示效果:

 

用手按在lps22HH压力传感器上面可以增大压力

传感器的位置:

 

增大的压力数据:

 

 

 

 

最新回复

手放在传感器上 不是压力引起变化 而是温度变化会影响内部补偿   详情 回复 发表于 2019-8-3 13:20
点赞 关注(1)
 
 

回复
举报

1万

帖子

25

TA的资源

版主

沙发
 

手放在传感器上 不是压力引起变化 而是温度变化会影响内部补偿

点评

多谢指正  详情 回复 发表于 2019-8-3 15:51
 
 
 

回复

282

帖子

2

TA的资源

一粒金砂(高级)

板凳
 
dcexpert 发表于 2019-8-3 13:20 手放在传感器上 不是压力引起变化 而是温度变化会影响内部补偿

多谢指正

 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表