3634 views|2 replies

282

Posts

2

Resources
The OP
 

GD32E231 analog IIC driver LPS22HH [Copy link]

 

Last week I tried the STTS7551 temperature sensor (portal: GD32E231 simulates IIC to drive STTS751 ), and then I started trying the LPS22HH sensor.

From the schematic diagram, they are all connected to the same IIC bus, which is IIC1. However, after using the same program to modify the address, they still cannot run, as shown below:

I used the same program as stts751, but it didn't work after I modified the address and register name . This problem bothered me for several days. Finally, I had no choice but to connect the corresponding pins of the sensor and the microcontroller together according to the following figure, and then I found that it could be read normally. I don't know what the reason is? Is there any expert who can answer this question?

The connection diagram is as follows. The wires are a bit messy, just connect them in order:

Although I can receive data normally at this time, there is another problem. I receive data every 1s, but the data is sometimes good and sometimes bad . For example, when reading ID: B3, sometimes I can read B3 normally, and sometimes I can't read it. There should be no problem with my IIC communication. The OLED that should be connected is displayed normally without any error. It was also normal when I used STTS7551 last time. I don't know what the reason is. I hope to get the answer from an expert . Thank you.


Total number of registers:

It needs to be set, refer to the register:

Control register IF_CTRL , this register sets the IIC operation, I set the value to 0x1A, that is, set the pull-up resistor and the I2C used

Register WHO_AM_I , this register is for identity identification, 0xB3

Control register CTRL_REG1 , this needs to be set, ODR[2:0] needs to be set, otherwise the data can only be obtained by triggering. Mine is 001, and the data is updated once every second.

Get the register of pressure data. The pressure data is 24-bit. Just get the value of the three-bit register and then calculate it. Get_Pressure_H_LPS22HH()<<16)|(Get_Pressure_L_LPS22HH()<<8)|(Get_Pressure_XL_LPS22HH()

The same is true for getting temperature data. The temperature data is 16 bits and needs to be divided by 100 to get the normal temperature value: (Get_Temp_H_LPS22HH()<<8)|(Get_Temp_L_LPS22HH())


Read and write 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;
}

Since the data read above is sometimes good and sometimes bad, I changed the code for reading and setting data at the end. It is no longer a simple read. I added a judgment. If the read data is incorrect, it will be read until 20 consecutive read errors occur before exiting, as follows:

Modified read and write operations:

//设置寄存器
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;
}

Register operations:

//读取我是谁
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;
}

Initialize 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");
	}

Serial port sends data and OLED displays:

//发送数据到串口
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();
}

Macro definition in .h file:

#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


Display effect:

Pressing your hand on the lps22HH pressure sensor can increase the pressure

Sensor location:

Increased pressure data:

This post is from MEMS sensors

Latest reply

When you put your hand on the sensor, it is not the pressure that causes the change, but the temperature change that affects the internal compensation.   Details Published on 2019-8-3 13:20
 
 

1w

Posts

25

Resources
2
 

When you put your hand on the sensor, it is not the pressure that causes the change, but the temperature change that affects the internal compensation.

This post is from MEMS sensors

Comments

Thank you for your correction  Details Published on 2019-8-3 15:51
 
 
 

282

Posts

2

Resources
3
 
dcexpert posted on 2019-8-3 13:20 When your hand is placed on the sensor, it is not the pressure that causes the change, but the temperature change that affects the internal compensation

Thank you for your correction

This post is from MEMS sensors
 
 
 

Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list