上周尝试了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:
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);
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;
}
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压力传感器上面可以增大压力
传感器的位置:
增大的压力数据:
|