打印
[STM32U5]

STM32U585AI探索套件压力传感器LPS22HH驱动与海拔换算

[复制链接]
19578|24
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Litthins|  楼主 | 2021-10-18 11:44 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 Litthins 于 2021-10-18 11:44 编辑
#技术资源#

本来打算写套件板载的HTS221温湿度传感器,发现这个论坛已经有人写过了。
今天分享的是压力传感器LPS22HH的数据读取与海拔换算。板上编号U26,才采用I2C2与STM32U5通信。具体位置见下图。
简单介绍下LPS22HH,传感器采用HLGA-10L封装,整体尺寸在2.0x2.0x0.73mm,是结构非常紧凑,适合空间受限应用环境的高性能MEMS压力传感器。作为气压传感器,量程和精度是我们普遍关心的指标。LPS22HH量程在260至1260hPa,精度在0.5hPa并且内建温度补偿。器件本身支持SPI、I2C、I3C总线,工作电压1.7至3.6V。
当然也有一些突出特性,比如传感器内集成FIFO,支持突发连续数据读取,该模式对需要低功耗和间歇获取数据的应用场合更友好。该传感器支持工作环境温度范围-40至+85摄氏度,考虑部分较恶劣的工作条件,也可作为备选器件考虑。
由于板上采用I2C总线与传感器通讯,接下来的驱动编写也使用I2C的通信方式。
LPS22HH的读地址为0xBB,定义为LPS22HH_RD;写地址为0xBA;定义为LPS22HH_WR。与HTS221温湿度传感器一样,LPS22HH也有一个名为REG_WHO_AM_I的寄存器地址0x0F;读取该地址,将得到0xB3的返回值;该值用于系统验证设备身份,与I2C总线的响应机制结合,可作为双重验证机制。验证结果通过枚举LPS22HHState表示,使代码便于理解。操作LPS22HH,除需要读取存放压力与温度参数的5个寄存器,还需要至少配置两个控制寄存器,分别是IF_CTRLCTRL_REG1。其中,IF_CTRL用于控制总线内部上下拉方式,I3C和I2C支持模式。CTRL_REG1用于控制内部滤波器、转换模式(可选连续转换或程控)、SPI支持模式。对于连续转换,有1Hz至200Hz转换速率可选,见数据手册截图。
压力数据由三个寄存器储存,分别为PRESSURE_OUT_XLPRESSURE_OUT_LPRESSURE_OUT_H;温度数据由两个寄存器储存,分别为TEMP_OUT_LTEMP_OUT_H。相关寄存器定义如下:
#include <inttypes.h>

typedef enum
{
  LPS22HH_PASSED = 0U,
  LPS22HH_FAILED
} LPS22HHState;

#define LPS22HH_RD 0xBB
#define LPS22HH_WR 0xBA

#define IF_CTRL 0x0E
#define CTRL_REG1 0x10
#define REG_WHO_AM_I 0x0F

#define PRESSURE_OUT_XL 0x28
#define PRESSURE_OUT_L 0x29
#define PRESSURE_OUT_H 0x2A

#define TEMP_OUT_L 0x2B
#define TEMP_OUT_H 0x2C

void LPS22HH_Init(void);
float LPS22HH_GET_Pressure(void);
float LPS22HH_GET_Temperature(void);
LPS22HHState LPS22HH_Identity_Verification(void);
传感器初始化代码中,给IF_CTRL赋值0x00,即采用I2C模式,不使用内部上下拉;给CTRL_REG1赋值0x20,即转换频率10Hz,不使用滤波器且连续转换:
void LPS22HH_Init(void)
{
        uint8_t cfg1[2] = {IF_CTRL, 0x00};
        HAL_I2C_Mem_Write(&hi2c2, LPS22HH_WR, cfg1[0], I2C_MEMADD_SIZE_8BIT, cfg1 + 1, 1, 0xFF);
        uint8_t cfg2[2] = {CTRL_REG1, 0x20};
        HAL_I2C_Mem_Write(&hi2c2, LPS22HH_WR, cfg2[0], I2C_MEMADD_SIZE_8BIT, cfg2 + 1, 1, 0xFF);
}
身份验证代码如下所示:
LPS22HHState LPS22HH_Identity_Verification(void)
{
        uint8_t reg_value = 0;
        HAL_I2C_Mem_Read(&hi2c2, LPS22HH_RD, REG_WHO_AM_I, I2C_MEMADD_SIZE_8BIT, reg_value, 1, 0xFFFF);
        if (reg_value == 0xB3)
                return LPS22HH_PASSED;
        else
                return LPS22HH_FAILED;
}
读取压力时,先通过I2C总线获取PRESSURE_OUT_XLPRESSURE_OUT_LPRESSURE_OUT_H三个寄存器的值,位移后组合为24位2进制补码形式。组合方式见下图。
该数据/4096即可换算得到单位为hPa的压力值,代码中将之转换为kPa。
float LPS22HH_GET_Pressure(void)
{
        float pressure = 0;
        int32_t pressure_s32 = 0;
        uint8_t pressure_xl, pressure_l, pressure_h = 0;
        HAL_I2C_Mem_Read(&hi2c2, LPS22HH_RD, PRESSURE_OUT_XL, I2C_MEMADD_SIZE_8BIT, &pressure_xl, 1, 0xFFFF);
        HAL_I2C_Mem_Read(&hi2c2, LPS22HH_RD, PRESSURE_OUT_L, I2C_MEMADD_SIZE_8BIT, &pressure_l, 1, 0xFFFF);
        HAL_I2C_Mem_Read(&hi2c2, LPS22HH_RD, PRESSURE_OUT_H, I2C_MEMADD_SIZE_8BIT, &pressure_h, 1, 0xFFFF);
        pressure_s32 = (pressure_h << 16) | (pressure_l << 8) | pressure_xl;
        pressure = (float)pressure_s32 / 4096 / 10;
        return pressure;
}
读取温度时,通过TEMP_OUT_LTEMP_OUT_H组合16位温度数据,组合方式见下图:
对组合后的数据/100,即可换算得到当前温度数据;温度传感器误差范围±1.5摄氏度,转换时对其进行了补偿,代码如下:
float LPS22HH_GET_Temperature(void)
{
        float temperature = 0;
        int16_t temperature_s16 = 0;
        uint8_t temperature_l, temperature_h = 0;
        HAL_I2C_Mem_Read(&hi2c2, LPS22HH_RD, TEMP_OUT_L, I2C_MEMADD_SIZE_8BIT, &temperature_l, 1, 0xFFFF);
        HAL_I2C_Mem_Read(&hi2c2, LPS22HH_RD, TEMP_OUT_H, I2C_MEMADD_SIZE_8BIT, &temperature_h, 1, 0xFFFF);
        temperature_s16 = (temperature_h << 8) | temperature_l;
        temperature = (float)temperature_s16 / 100 - 1.5;
        return temperature;
}
最后给出简单的气压-海拔换算公式,其中,压力单位为kPa:
printf("----Altitude-----: %fm\r\n",44330*(1- pow(pressure/102.3,0.19))/1000);
上个图展示下效果,本人在海边,海拔大约1~2米,与换算结果较为一致:






使用特权

评论回复
沙发
chenqianqian| | 2021-10-18 20:23 | 只看该作者
ST的开发版就是给力啊

使用特权

评论回复
评论
Litthins 2021-10-19 18:25 回复TA
功能比Nucleo丰富多了 
板凳
asmine| | 2021-10-19 10:11 | 只看该作者
这个小传感器不错啊~

使用特权

评论回复
评论
Litthins 2021-10-19 18:26 回复TA
确实,结构非常紧凑,体积感觉接近极限了 
地板
Sunriver_Yao| | 2021-10-22 15:27 | 只看该作者
只能测绝对气压,不能测相对气压。可惜了!

使用特权

评论回复
5
海滨消消| | 2021-10-22 15:48 | 只看该作者
海拔换算

使用特权

评论回复
6
Litthins|  楼主 | 2021-10-22 15:50 | 只看该作者
Sunriver_Yao 发表于 2021-10-22 15:27
只能测绝对气压,不能测相对气压。可惜了!

测相对气压的还没见到过

使用特权

评论回复
7
tpgf| | 2021-10-26 09:48 | 只看该作者
传感器能拉压两用吗

使用特权

评论回复
评论
Litthins 2021-11-6 19:09 回复TA
应该只是压力传感器 
8
asmine| | 2021-10-26 15:57 | 只看该作者
Sunriver_Yao 发表于 2021-10-22 15:27
只能测绝对气压,不能测相对气压。可惜了!

差压的,霍尼或者all senser吧

使用特权

评论回复
9
qintian0303| | 2021-10-27 09:05 | 只看该作者
国产也有很多这种传感器还是挺不错的

使用特权

评论回复
10
qintian0303| | 2021-10-27 09:05 | 只看该作者
Litthins 发表于 2021-10-22 15:50
测相对气压的还没见到过

差压传感器还是很多的,相对来说比较贵

使用特权

评论回复
11
trucyw| | 2021-10-28 18:09 | 只看该作者
ST确实出了好多传感器

使用特权

评论回复
12
koala889| | 2021-11-4 15:49 | 只看该作者
这个传感器好小啊

使用特权

评论回复
评论
Litthins 2021-11-6 19:10 回复TA
浓缩的都是精华 
13
coshi| | 2021-11-5 15:30 | 只看该作者
是一种什么连接方式呢

使用特权

评论回复
14
yanzhengxin1| | 2021-11-5 15:32 | 只看该作者
挺详细呀,iic控制,气压计的焊接好处理

使用特权

评论回复
15
gwsan| | 2021-11-5 15:33 | 只看该作者
非常小巧的传感器

使用特权

评论回复
16
drer| | 2021-11-5 15:34 | 只看该作者
有什么入手途径吗

使用特权

评论回复
17
aoyi| | 2021-11-5 15:48 | 只看该作者
在官网可以买到吗

使用特权

评论回复
18
zljiu| | 2021-11-5 15:50 | 只看该作者
换算有相关的算法是吗

使用特权

评论回复
评论
Litthins 2021-11-6 19:10 回复TA
只有近似的,专业算法要自己捣鼓 
19
yljon| | 2021-11-12 14:59 | 只看该作者
感觉好高级

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

10

主题

74

帖子

8

粉丝