MM32F3277 I2C 访问 LPS22HH 气压传感器

Foreword

这周选错传感器了,把 LPS22HB 选成 LPS22HH 了,文档白写了😫

就来更个 CSDN 吧,不然亏大了。

LPS22HB 和 LPS22HH 的异同

先讲讲他们的异同点吧

相同点

  • 地址是一样的(所以我看着 HH 的文档跑通了 HB 的传感器……)
  • 基础配置以及数据寄存器地址一样(FIFO 以及 Interrupt 功能位不一致)
  • 读取的数据都是气压和温度,位数一样
  • 气压测量范围一样
  • 都支持 SPI 和 I2C 通讯
  • 都支持 FIFO 和 Interrupt
  • 都支持设置参考气压值

不同点

  • WHO_AM_I 不一样,差了一位(发现 WHO_AM_I 对不上的时候我竟然觉得是文档写错了😑)
  • LPS22HH 支持 I3C 通讯
  • LPS22HH 支持更高的采样频率
  • LPS22HH 内部 FIFO 更大,FIFO 模式有区别
  • LPS22HH 有专门的 FIFO 数据读取寄存器

LPS22HH 压力传感器

主控芯片:MM32F3277

传感器:LPS22HH 压力传感器

通讯方式:I2C

开发环境:IAR 7.80.4

ST LPS22HH 压力传感器资料

Features

  • Embedded temperature compensation
  • 24-bit pressure data output
  • SPI, I2C or MIPI I3C interfaces
  • Embedded FIFO
  • Interrupt functions: Data-Ready, FIFO flags, pressure thresholds

Applications

  • Altimeters and barometers for portable devices
  • GPS applications
  • Weather station equipment
  • Sport watches
  • e-cigarettes
  • Drones
  • Gas metering

Pin

  1. VDD_IO: Power Supply

  2. SCL / SPC: SCL for I2C and I3C serial clock; SPC for SPI serial port clock

  3. RES: Connected to GND

  4. SDA / SDI / SDI or SDO: SDA for I2C and I3C serial data; SDI for 4-wire SPI serial data input; SDI or SDO for 3-wire SPI serial data input or output

  5. SA0 / SDO: SA0 for I2C and I3C LSB address; SDO for 4-wire SPI serial data output

  6. CS: interface selection 0 for SPI; 1 for I2C / I3C

  7. INT_DRDY: Interrupt or Data-Ready; Floating(Internal pull-down) for I2C and I3C; VDD_IO for I3C only

  8. GND

  9. GND

  10. VDD

lps22hh

在 MB-018 中,LPS22HH 连接 I2C,CS 接 VDD,SA0 接地 LSB = 0,INT_DRDY floating,I3C_DISABLE 置 1

LPS22HH Address

SA0 管脚决定了地址 LSB 位的高低,这样主控就可以连两个 LPS22HH 传感器,从地址不会冲突

// LPS22HB Address
#define SLAVE_ADDRESS_SA0               0x00
#define SLAVE_ADDRESS                   (0x5C | SLAVE_ADDRESS_SA0)              // 0x5C
#define SLAVE_ADDRESS_WRITE             SLAVE_ADDRESS << 1                      // 0xB8
#define SLAVE_ADDRESS_READ              (SLAVE_ADDRESS << 1) | 0x01             // 0xB9

I2C 对 LPS22HH 进行读写

I2C 读写方式及原理可见「Rose Island」MM32F3277 I2C 访问 HTS221 温湿度传感器

Master write data to Slave

Steps

  1. Master 发送 START 信号(SCL hold high, SDA high to low)

  2. Master 发送 Slave 的 7 位地址 + 写信号

  3. Slave 进行地址匹配,匹配成功回应 SAK

  4. Master 发送 SubAddress,即 Slave 内部寄存器地址

    通过CTRL_REG2 中的 IF_ADD_INC 位决定 SubAddr 地址是否自增,即是否可以连续操作多个寄存器,该位默认为高

    #define LPS22HH_CTRL_REG1               0x10
    LPS22HH_Reg_Write(I2Cx, LPS22HH_CTRL_REG1, buffer, 1)
    
  5. Slave 应答 SubAddr

  6. Master 发送 DATA,Slave 应答 SAK

  7. Master 发送完后,产生 STOP 信号(SCL hold high, SDA low to high)

i2cwrite

Master read data from Slave

Steps

  1. Master 发送 START 信号(SCL hold high, SDA high to low)
  2. Master 发送 Slave 的 7 位地址 + 写信号
  3. Slave 进行地址匹配,匹配成功回应 SAK
  4. Master 发送 SubAddress,即 Slave 内部寄存器地址,操作同上
  5. Slave 应答 SubAddr
  6. Master 发送 RESTART 信号,重新发送 Slave 的 7 位地址 + 读信号,Slave 回应 SAK
  7. Slave 发送 Data,Master 应答 MAK
  8. Master 接收最后一个数据后,不应答 NMAK,产生 STOP 信号(SCL hold high, SDA lowto high)

i2cread

Calculation Function

  • Pressure Calculation

    从以下三个寄存器中读取压力数据:PRESS_OUT_H / PRESS_OUT_L / PRESS_OUT_XL;

    如果用了传感器内部 FIFO,则读 FIFO_DATA_OUT_PRESS_H / FIFO_DATA_OUT_PRESS_L / FIFO_DATA_OUT_PRESS_XL
    P r e s s u r e ( h P a ) = ( P R E S S _ O U T _ H < < 16 )    &    ( P R E S S _ O U T _ L < < 8 )    &    ( P R E S S _ O U T _ X L ) 4096 Pressure(hPa) = \frac{(PRESS\_OUT\_H << 16)\ \ \&\ \ (PRESS\_OUT\_L << 8)\ \ \&\ \ (PRESS\_OUT\_XL)}{4096} Pressure(hPa)=4096(PRESS_OUT_H<<16)  &  (PRESS_OUT_L<<8)  &  (PRESS_OUT_XL)

  • Temperature Calculation

    从以下两个寄存器中读取压力数据:TEMP_OUT_H / TEMP_OUT_L;

    如果用了传感器内部 FIFO,则读 FIFO_DATA_OUT_TEMP_H / FIFO_DATA_OUT_TEMP_L
    T e m p e r a t u r e ( d e g C ) = ( T E M P _ O U T _ H < < 8 )    &    ( T E M P _ O U T _ L ) 100 Temperature(degC)=\frac{(TEMP\_OUT\_H << 8)\ \ \&\ \ (TEMP\_OUT\_L)}{100} Temperature(degC)=100(TEMP_OUT_H<<8)  &  (TEMP_OUT_L)

Embedded FIFO

128 个 40 位数据 FIFO 用于存储压力和温度值,在主控需要读取时唤醒传感器,从 FIFO 取出数据。启用 FIFO 后依旧可以从标准寄存器中读取数据。

6 种模式:

  • Bypass mode

    FIFO 未启用。如果需要切换 FIFO mode,需要先设置为 Bypass mode,再设置新的 FIFO mode。

  • FIFO mode

    启用 FIFO,数据会存入 FIFO 直到 FIFO 满。FIFO 默认深度是 128,用户可以通过配置 FIFO_WTM[6:0] 设定 FIFO 深度。

    FIFO 满后,需要切换回 Bypass mode 再重启 FIFO mode。

  • Continuous (Dynamic-Stream) mode

    启用 FIFO,环形队列。新的数据样本会放入 FIFO 触发读取。这种方式用于当数据读取周期不能满足 1/ODR 的时候。

    同时也可以使用 INT_F_WTM 中断,当 FIFO 满的时候,下一个数据触发读取 FIFO,FIFO 清空重新装数据。

  • Bypass to FIFO mode

    使用该模式需要启用中断。根据中断状态 INT_SOURCE 中的 IA 决定 mode,IA = 0 时为 Bypass mode,IA = 1 时为 FIFO mode。

  • Bypass to Continuous (Dynamic-Stream) mode

    使用该模式需要启用中断。根据中断状态 INT_SOURCE 中的 IA 决定 mode,IA = 0 时为 Bypass mode,IA = 1 时为 Continuous (Dynamic-Stream) mode。

  • Continuous (Dynamic-Stream) to FIFO mode

    使用该模式需要启用中断。根据中断状态 INT_SOURCE 中的 IA 决定 mode,IA = 0 时为 Continuous (Dynamic-Stream) mode,IA = 1 时为 FIFO mode。

Register Map

  • INTERRUPT_CFG

    Reg Address is 0x0B, R/W and default is 0x00

    1. PHE: 当气压比设定的标准线高时产生中断,标准线由用户定义,存储在 THS_P 寄存器中

    2. PLE: 当气压比设定的标准线低时产生中断,标准线由用户定义,存储在 THS_P 寄存器中

    3. LIR: 是否锁存中断请求至 INT_SOURCE 寄存器

    4. DIFF_EN: 中断使能

    5. RESET_AZ: Reset AUTOZERO function

    6. AUTOZERO: Enable AUTOZERO function

      AUTOZERO 置 1 后,读取的数据会作为参考值存入 REF_P 寄存器,之后该位自动清 0,如果要取消该参考值,需要对 RESET_AZ 位置 1

      P_DIFF_IN = measured pressure - REF_P (该值用于产生中断)

      PRESS_OUT = measured pressure - REF_P

      如果使用了 AUTOZEROPHE 比较的是 P_DIFF_IN 和 THS_P

    7. RESET_ARP: Reset AUTOREFP function

    8. AUTOREFP: Enable AUTOREFP function

      AUTOREFP 置 1 后,读取的数据会作为参考值存入 REF_P 寄存器,之后该位自动清 0,如果要取消该参考值,需要对 RESET_ARP 位置 1

      AUTOZERO 不同的是,PRESS_OUT 输出的是测量值,而不是与参考值的差值

      P_DIFF_IN = measured pressure - REF_P (该值用于产生中断)

      PRESS_OUT = measured pressure

  • **THS_P_L / THS_P_H **

    Reg Address is 0x0C and 0x0D, R/W and default is 0x00

    该 15 位的值用于和测量出的压力数据进行比较,产生中断。

    若要产生中断,需要将 INTERRUPT_CFGDIFF_EN / PHE / PLE 位使能

    THS_P(15-bit unsigned) = Desired interrupt threshold(hPa) × 16

  • IF_CTRL

    Reg Address is 0x0E, R/W and default is 0x00

    1. I2C_DISABLE: Set 0 to enable I2C; Set 1 to disable I2C
    2. I3C_DISABLE: Set 0 to enable I3C; Set 1 to disable I3C
    3. PD_DIS_INT1: 置 0 时 INT1 管脚下拉;置 1 时 INT1 管脚不下拉
    4. SDO_PU_EN: 置 0 时 SDO 管脚不上拉;置 1 时 SDO 管脚上拉
    5. SDA_PU_EN: 置 0 时 SDA 管脚不上拉;置 1 时 SDA 管脚上拉
    6. INT_EN_I3C: 置 0 时 INT1 管脚不使能 I3C;置 0 时 INT1 管脚使能 I3C
  • WHO_AM_I

    Reg Address is 0x0F, read only and default is 0xB3

    // LPS22HH Device ID
    #define DEVICE_ID_WHO_AM_I              0xB3
    
  • CTRL_REG1

    Reg Address is 0x10, R/W and default is 0x00

    1. SIM: 置 0 为 4 线 SPI;置 1 为 3 线 SPI
    2. BDU: 置 0 为连续更新 MSB 和 LSB 的数据;置 1 为只有当 MSB 和 LSB 都被读取了之后再更新数据,建议置 1
    3. LPFP_CFG: 如果低通滤波器未使能,bandwith = ODR / 2;如果低通滤波器使能且该位为 0,bandwith = ODR / 9;如果低通滤波器使能且该位为 1,bandwith = ODR / 20
    4. EN_LPFP: 是否使能低通滤波器
    5. ODR: 0x00 为 one-shot 模式,设备为 Power-down mode,配合 CFGR_REG2 中的 ONE_SHOT 位触发一次读取;其他情况下设备为 Continuous mode,根据频率连续读取数据
  • CTRL_REG2

    Reg Address is 0x11, R/W and default is 0x00

    1. ONE_SHOT: 触发 One_Shot,CFGR_REG1 中的 ODR 位需要是 0x00,硬件清零
    2. LOW_NOISE_EN: 置 0 为 low-current 模式;置 1 为 low-noise 模式,此时 ODR < 100Hz
    3. SWRESET: 置 1 为软件重启,硬件清零
    4. IF_ADD_INC: I2C / SPI 模式下操作寄存器时,地址自增
    5. PP_OD: interrupt 管脚配置,置 0 为推挽输出;置 1 为开漏输出
    6. INT_H_L: 置 0 为 interrupt 高有效;置 1 为低有效
    7. BOOT: 置 1 为 reboot,硬件清零
  • CTRL_REG3

    Reg Address is 0x12, R/W and default is 0x00

    1. INT_S: INT_DRDY 管脚输出,00 为 Data Signal,01 为 Pressure high 中断,10 为 Pressure Low 中断,11 为 Pressure High or Low 中断
    2. DRDY: INT_DRDY 管脚输出 Data ready signal
    3. INT_F_OVR: INT_DRDY 管脚输出 FIFO overrun status
    4. INT_F_WTM: INT_DRDY 管脚输出 FIFO threshold status
    5. INT_F_FULL: INT_DRDY 管脚输出 FIFO full flag

reg3

  • FIFO_CTRL

    Reg Address is 0x13, R/W and default is 0x00

    1. F_MODE / TRIG_MODES

      TRIG_MODESF_MODEMODE
      X00Bypass mode
      001FIFO mode
      01XContinuous (Dynamic-Stream) mode
      101Bypass to FIFO mode
      110Bypass to Continuous (Dynamic-Stream) mode
      111Continuous (Dynamic-Stream) to FIFO mode
    2. STOP_ON_WTM: 如果设置了 FIFO_WTMWTM 位,FIFO 中的数量到达 watermark level 的时候,FIFO 为满

  • FIFO_WTM

    Reg Address is 0x14, R/W and default is 0x00

    WTM 为 FIFO watermark level

  • REF_P_L / REF_P_H

    Reg Address is 0x15 / 0x16, read only and default is 0x00

    INTERRUPT_CFGAUTOZEROAUTOREFP 使能时,需要用到参考气压值

  • RPDS_L / RPDS_H

    Reg Address is 0x18 / 0x19, read only and default is 0x00

    用于焊接后的压力偏移量校准

  • INT_SOURCE

    Reg Address is 0x24, read only and default is 0x00

    1. PH: high differential pressure event
    2. PL: low differential pressure event
    3. IA: one or more interrupt event generated
    4. BOOT_ON: boot phase running
  • FIFO_STATUS1

    Reg Address is 0x25, read only and default is 0x00

    FSS: 0x00 为 FIFO 空;0x80 为 FIFO满

  • FIFO_STATUS2

    Reg Address is 0x26, read only and default is 0x00

    1. FIFO_FULL_IA: FIFO 满但未溢出
    2. FIFO_OVR_IA: FIFO 满且溢出
    3. FIFO_WTM_IA: FIFO 大于等于 watermark level
  • STATUS

    Reg Address is 0x27, read only and default is 0x00

    跟着 ODR 频率更新

    1. P_DA: 有新的压力数据了
    2. T_DA: 有新的温度数据了
    3. P_OR: 压力数据溢出,旧的数据被替换
    4. T_OR: 温度数据溢出,旧的数据被替换
  • PRESS_OUT_XL / PRESS_OUT_L / PRESS_OUT_H

    Reg Address is 0x28 / 0x29 / 0x2A , read only and default is 0x00

    输出的是与 RPDS 的差值

  • TEMP_OUT_L / TEMP_OUT_H

    Reg Address is 0x2B / 0x2C , read only and default is 0x00

  • FIFO_DATA_OUT_PRESS_XL / FIFO_DATA_OUT_PRESS_L / FIFO_DATA_OUT_PRESS_H

    Reg Address is 0x78 / 0x79 / 0x7A , read only and default is 0x00

  • FIFO_DATA_OUT_TEMP_L / FIFO_DATA_OUT_TEMP_H

    Reg Address is 0x7B / 0x7C , read only and default is 0x00

Code

实现 LPS22HH 数据读取

  • lps22hh.h

    
    #ifndef __LPS22HH_H_
    #define __LPS22HH_H_
    
    
    typedef enum {
        LPS22HH_OK       = (uint8_t)0,
        LPS22HH_ERROR    = !LPS22HH_OK
    } LPS22HH_Error_Typedef;
    
    typedef enum {
        LPS22HH_DISABLE  = (uint8_t)0,
        LPS22HH_ENABLE   = !LPS22HH_DISABLE
    } LPS22HH_State_Typedef;
    
    
    /// @defgroup HPS22HH Interrupts Definition
    /// @{
    #define LPS22HH_IT_PHE                  0x01
    #define LPS22HH_IT_PLE                  0x02
    /// @}
    
    
    /// @defgroup HPS22HH Interrupt Mode Definition
    /// @{
    #define LPS22HH_IT_MODE_RESETAZ         0x10
    #define LPS22HH_IT_MODE_AUTOZERO        0x20
    #define LPS22HH_IT_MODE_RESETARP        0x40
    #define LPS22HH_IT_MODE_AUTOREFP        0x80
    /// @}
    
    
    /// @defgroup LPS22HH Statusflags definition
    /// @{
    #define LPS22HH_ITS_PH_FLAG             0x01
    #define LPS22HH_ITS_PL_FLAG             0x02
    #define LPS22HH_ITS_IA_FLAG             0x04
    /// @}
    
    
    /// @defgroup LPS22HH Output data rate
    /// @{
    #define LPS22HH_OUTPUT_DATA_ONESHOT     0x00
    #define LPS22HH_OUTPUT_DATA_RATE_1      0x01
    #define LPS22HH_OUTPUT_DATA_RATE_10     0x02
    #define LPS22HH_OUTPUT_DATA_RATE_25     0x03
    #define LPS22HH_OUTPUT_DATA_RATE_50     0x04
    #define LPS22HH_OUTPUT_DATA_RATE_75     0x05
    #define LPS22HH_OUTPUT_DATA_RATE_100    0x06
    #define LPS22HH_OUTPUT_DATA_RATE_200    0x07
    /// @}
    
    
    /// @defgroup LPS22HH FIFO mode
    /// @{
    #define LPS22HH_FIFO_MODE_BYPASS               0x00
    #define LPS22HH_FIFO_MODE_FIFO                 0x01
    #define LPS22HH_FIFO_MODE_CONTINUOUS           0x02
    #define LPS22HH_FIFO_MODE_BYPASS_2_FIFO        0x05
    #define LPS22HH_FIFO_MODE_BYPASS_2_CONTINUOUS  0x06
    #define LPS22HH_FIFO_MODE_CONTINUOUS_2_FIFO    0x07
    /// @}
    
    
    #ifdef _LPS22HH_C_
    
    // LPS22HH register subAddr
    #define LPS22HH_INTERRUPT_CFG           0x0B                                    // Interrupt register
    #define LPS22HH_THS_P_L                 0x0C                                    // Pressure threshold registers
    #define LPS22HH_THS_P_H                 0x0D                                    // Pressure threshold registers
    #define LPS22HH_IF_CTRL                 0x0E                                    // Interface control register
    #define LPS22HH_WHO_AM_I                0x0F                                    // Who am I
    #define LPS22HH_CTRL_REG1               0x10                                    // Control registers
    #define LPS22HH_CTRL_REG2               0x11                                    // Control registers
    #define LPS22HH_CTRL_REG3               0x12                                    // Control registers
    #define LPS22HH_FIFO_CTRL               0x13                                    // FIFO configuration register
    #define LPS22HH_FIFO_WTM                0x14                                    // FIFO watermark level
    #define LPS22HH_REF_P_L                 0x15                                    // Reference pressure registers
    #define LPS22HH_REF_P_H                 0x16                                    // Reference pressure registers
    #define LPS22HH_RPDS_L                  0x18                                    // Pressure offset registers
    #define LPS22HH_RPDS_H                  0x19                                    // Pressure offset registers
    #define LPS22HH_INT_SOURCE              0x24                                    // Interrupt register
    #define LPS22HH_FIFO_STATUS1            0x25                                    // FIFO status registers
    #define LPS22HH_FIFO_STATUS2            0x26                                    // FIFO status registers
    #define LPS22HH_STATUS                  0x27                                    // Status register
    #define LPS22HH_PRESS_OUT_XL            0x28                                    // Pressure output registers
    #define LPS22HH_PRESS_OUT_L             0x29                                    // Pressure output registers
    #define LPS22HH_PRESS_OUT_H             0x2A                                    // Pressure output registers
    #define LPS22HH_TEMP_OUT_L              0x2B                                    // Temperature output registers
    #define LPS22HH_TEMP_OUT_H              0x2C                                    // Temperature output registers
    #define LPS22HH_FIFO_DATA_OUT_PRESS_XL  0x78                                    // FIFO pressure output registers
    #define LPS22HH_FIFO_DATA_OUT_PRESS_L   0x79                                    // FIFO pressure output registers
    #define LPS22HH_FIFO_DATA_OUT_PRESS_H   0x7A                                    // FIFO pressure output registers
    #define LPS22HH_FIFO_DATA_OUT_TEMP_L    0x7B                                    // FIFO temperature output registers
    #define LPS22HH_FIFO_DATA_OUT_TEMP_H    0x7C                                    // FIFO temperature output registers
    
    // LPS22HH Address
    #define SLAVE_ADDRESS_SA0               0x00
    #define SLAVE_ADDRESS                   (0x5C | SLAVE_ADDRESS_SA0)              // 0x5C
    #define SLAVE_ADDRESS_WRITE             SLAVE_ADDRESS << 1                      // 0xB8
    #define SLAVE_ADDRESS_READ              (SLAVE_ADDRESS << 1) | 0x01             // 0xB9
    
    // LPS22HH Device ID
    #define DEVICE_ID_WHO_AM_I              0xB3
    
    // LPS22HH_INTERRUPT_CFG
    #define LPS22HH_ITC_PHE_POS             (0)
    #define LPS22HH_ITC_PHE                 (0x01 << LPS22HH_ITC_PHE_POS)
    #define LPS22HH_ITC_PLE_POS             (1)
    #define LPS22HH_ITC_PLE                 (0x01 << LPS22HH_ITC_PLE_POS)
    #define LPS22HH_ITC_LIR_POS             (2)
    #define LPS22HH_ITC_LIR                 (0x01 << LPS22HH_ITC_LIR_POS)
    #define LPS22HH_ITC_DIFF_EN_POS         (3)
    #define LPS22HH_ITC_DIFF_EN             (0x01 << LPS22HH_ITC_DIFF_EN_POS)
    #define LPS22HH_ITC_RESET_AZ_POS        (4)
    #define LPS22HH_ITC_RESET_AZ            (0x01 << LPS22HH_ITC_RESET_AZ_POS)
    #define LPS22HH_ITC_AUTOZERO_POS        (5)
    #define LPS22HH_ITC_AUTOZERO            (0x01 << LPS22HH_ITC_AUTOZERO_POS)
    #define LPS22HH_ITC_RESET_ARP_POS       (6)
    #define LPS22HH_ITC_RESET_ARP           (0x01 << LPS22HH_ITC_RESET_ARP_POS)
    #define LPS22HH_ITC_AUTOREFP_POS        (7)
    #define LPS22HH_ITC_AUTOREFP            (0x01 << LPS22HH_ITC_AUTOREFP_POS)
    
    // LPS22HH_IF_CTRL
    #define LPS22HH_IFC_I2C_DIS_POS         (0)
    #define LPS22HH_IFC_I2C_DIS             (0x01 << LPS22HH_IFC_I2C_DIS_POS)
    #define LPS22HH_IFC_I3C_DIS_POS         (1)
    #define LPS22HH_IFC_I3C_DIS             (0x01 << LPS22HH_IFC_I3C_DIS_POS)
    #define LPS22HH_IFC_PD_DIS_INT_POS      (2)
    #define LPS22HH_IFC_PD_DIS_INT          (0x01 << LPS22HH_IFC_PD_DIS_INT_POS)
    #define LPS22HH_IFC_SDO_PU_EN_POS       (3)
    #define LPS22HH_IFC_SDO_PU_EN           (0x01 << LPS22HH_IFC_SDO_PU_EN_POS)
    #define LPS22HH_IFC_SDA_PU_EN_POS       (4)
    #define LPS22HH_IFC_SDA_PU_EN           (0x01 << LPS22HH_IFC_SDA_PU_EN_POS)
    #define LPS22HH_IFC_INT_EN_I3C_POS      (7)
    #define LPS22HH_IFC_INT_EN_I3C          (0x01 << LPS22HH_IFC_INT_EN_I3C_POS)
    
    // LPS22HH_CTRL_REG1
    #define LPS22HH_CR1_SIM_POS             (0)
    #define LPS22HH_CR1_SIM                 (0x01U << LPS22HH_CR1_SIM_POS)
    #define LPS22HH_CR1_BDU_POS             (1)
    #define LPS22HH_CR1_BDU                 (0x01U << LPS22HH_CR1_BDU_POS)
    #define LPS22HH_CR1_LPFP_CFG_POS        (2)
    #define LPS22HH_CR1_LPFP_CFG            (0x01U << LPS22HH_CR1_LPFP_CFG_POS)
    #define LPS22HH_CR1_EN_LPFP_POS         (3)
    #define LPS22HH_CR1_EN_LPFP             (0x01U << LPS22HH_CR1_EN_LPFP_POS)
    #define LPS22HH_CR1_ODR_POS             (4)
    #define LPS22HH_CR1_ODR_ONE_SHOT        (0x00U << LPS22HH_CR1_ODR_POS)
    #define LPS22HH_CR1_ODR_1               (0x01U << LPS22HH_CR1_ODR_POS)
    #define LPS22HH_CR1_ODR_10              (0x02U << LPS22HH_CR1_ODR_POS)
    #define LPS22HH_CR1_ODR_25              (0x03U << LPS22HH_CR1_ODR_POS)
    #define LPS22HH_CR1_ODR_50              (0x04U << LPS22HH_CR1_ODR_POS)
    #define LPS22HH_CR1_ODR_75              (0x05U << LPS22HH_CR1_ODR_POS)
    #define LPS22HH_CR1_ODR_100             (0x06U << LPS22HH_CR1_ODR_POS)
    #define LPS22HH_CR1_ODR_200             (0x07U << LPS22HH_CR1_ODR_POS)
    
    // LPS22HH_CTRL_REG2
    #define LPS22HH_CR2_ONE_SHOT_POS        (0)
    #define LPS22HH_CR2_ONE_SHOT            (0x01U << LPS22HH_CR2_ONE_SHOT_POS)
    #define LPS22HH_CR2_LOW_NOISE_EN_POS    (1)
    #define LPS22HH_CR2_LOW_NOISE_EN        (0x01U << LPS22HH_CR2_LOW_NOISE_EN_POS)
    #define LPS22HH_CR2_SWRESET_POS         (2)
    #define LPS22HH_CR2_SWRESET             (0x01U << LPS22HH_CR2_SWRESET_POS)
    #define LPS22HH_CR2_IF_ADD_INC_POS      (4)
    #define LPS22HH_CR2_IF_ADD_INC          (0x01U << LPS22HH_CR2_IF_ADD_INC_POS)
    #define LPS22HH_CR2_PP_OD_POS           (5)
    #define LPS22HH_CR2_PP_OD               (0x01U << LPS22HH_CR2_PP_OD_POS)
    #define LPS22HH_CR2_INT_H_L_POS         (6)
    #define LPS22HH_CR2_INT_H_L             (0x01U << LPS22HH_CR2_INT_H_L_POS)
    #define LPS22HH_CR2_BOOT_POS            (7)
    #define LPS22HH_CR2_BOOT                (0x01U << LPS22HH_CR2_BOOT_POS)
    
    // LPS22HH_CTRL_REG3
    #define LPS22HH_CR3_INT_S_POS           (0)
    #define LPS22HH_CR3_INT_S_DATA_SIG      (0x00U << LPS22HH_CR3_INT_S_POS)
    #define LPS22HH_CR3_INT_S_PH            (0x01U << LPS22HH_CR3_INT_S_POS)
    #define LPS22HH_CR3_INT_S_PL            (0x02U << LPS22HH_CR3_INT_S_POS)
    #define LPS22HH_CR3_INT_S_PHL           (0x03U << LPS22HH_CR3_INT_S_POS)
    #define LPS22HH_CR3_DRDY_POS            (2)
    #define LPS22HH_CR3_DRDY                (0x00U << LPS22HH_CR3_DRDY_POS)
    #define LPS22HH_CR3_INT_F_OVR_POS       (3)
    #define LPS22HH_CR3_INT_F_OVR           (0x01U << LPS22HH_CR3_INT_F_OVR_POS)
    #define LPS22HH_CR3_INT_F_WTM_POS       (4)
    #define LPS22HH_CR3_INT_F_WTM           (0x01U << LPS22HH_CR3_INT_F_WTM_POS)
    #define LPS22HH_CR3_INT_F_FULL_POS      (5)
    #define LPS22HH_CR3_INT_F_FULL          (0x01U << LPS22HH_CR3_INT_F_FULL_POS)
    
    // LPS22HH_FIFO_CTRL
    #define LPS22HH_FC_MODE_POS             (0)
    #define LPS22HH_FC_BYPASS               (0x00U << LPS22HH_FC_MODE_POS)
    #define LPS22HH_FC_FIFO                 (0x01U << LPS22HH_FC_MODE_POS)
    #define LPS22HH_FC_CONTINUOUS           (0x02U << LPS22HH_FC_MODE_POS)
    #define LPS22HH_FC_BYPASS_2_FIFO        (0x05U << LPS22HH_FC_MODE_POS)
    #define LPS22HH_FC_BYPASS_2_CONTINUOUS  (0x06U << LPS22HH_FC_MODE_POS)
    #define LPS22HH_FC_CONTINUOUS_2_FIFO    (0x07U << LPS22HH_FC_MODE_POS)
    #define LPS22HH_FC_STOP_ON_WTM_POS      (3)
    #define LPS22HH_FC_STOP_ON_WTM          (0x01 << LPS22HH_FC_STOP_ON_WTM_POS)
    
    // LPS22HH_INT_SOURCE
    #define LPS22HH_ITS_PH_POS              (0)
    #define LPS22HH_ITS_PH                  (0x01 << LPS22HH_ITS_PH_POS)
    #define LPS22HH_ITS_PL_POS              (1)
    #define LPS22HH_ITS_PL                  (0x01 << LPS22HH_ITS_PL_POS)
    #define LPS22HH_ITS_IA_POS              (2)
    #define LPS22HH_ITS_IA                  (0x01 << LPS22HH_ITS_IA_POS)
    
    // LPS22HH_FIFO_STATUS2
    #define LPS22HH_FSTA_FULL_IA_POS        (0)
    #define LPS22HH_FSTA_FULL_IA            (0x01 << LPS22HH_FSTA_FULL_IA_POS)
    #define LPS22HH_FSTA_OVR_IA_POS         (1)
    #define LPS22HH_FSTA_OVR_IA             (0x01 << LPS22HH_FSTA_OVR_IA_POS)
    #define LPS22HH_FSTA_WTM_IA_POS         (2)
    #define LPS22HH_FSTA_WTM_IA             (0x01 << LPS22HH_FSTA_WTM_IA_POS)
    
    // LPS22HH_STATUS
    #define LPS22HH_STATUS_P_DA_POS         (0)
    #define LPS22HH_STATUS_P_DA             (1 << LPS22HH_STATUS_P_DA_POS)
    #define LPS22HH_STATUS_T_DA_POS         (1)
    #define LPS22HH_STATUS_T_DA             (1 << LPS22HH_STATUS_T_DA_POS)
    #define LPS22HH_STATUS_P_OR_POS         (4)
    #define LPS22HH_STATUS_P_OR             (1 << LPS22HH_STATUS_P_OR_POS)
    #define LPS22HH_STATUS_T_OR_POS         (5)
    #define LPS22HH_STATUS_T_OR             (1 << LPS22HH_STATUS_T_OR_POS)
    
    #endif
    LPS22HH_Error_Typedef LPS22HH_Reg_Write(I2C_TypeDef *I2Cx, u8 regAddr, u8* ptr, u16 cnt);
    LPS22HH_Error_Typedef LPS22HH_Reg_Read(I2C_TypeDef *I2Cx, u8 regAddr, u8* ptr, u16 cnt);
    u8 LPS22HH_WHO_AM_I_Get(I2C_TypeDef *I2Cx);
    LPS22HH_Error_Typedef LPS22HH_Software_Reset(I2C_TypeDef *I2Cx);
    LPS22HH_Error_Typedef LPS22HH_Init(I2C_TypeDef *I2Cx, bool oneshot, u8 frequency);
    LPS22HH_Error_Typedef LPS22HH_DeInit(I2C_TypeDef *I2Cx);
    LPS22HH_Error_Typedef LPS22HH_PRESS_OUT_Get(I2C_TypeDef *I2Cx, int32_t *P_OUT);
    LPS22HH_Error_Typedef LPS22HH_TEMP_OUT_Get(I2C_TypeDef *I2Cx, int16_t *T_OUT);
    LPS22HH_Error_Typedef LPS22HH_Pressure_Calculation(I2C_TypeDef *I2Cx, int32_t *value);
    LPS22HH_Error_Typedef LPS22HH_Temperature_Calculation(I2C_TypeDef *I2Cx, int16_t *value);
    LPS22HH_Error_Typedef LPS22HH_Calculation(I2C_TypeDef *I2Cx, int32_t *p_value, int16_t *t_value, bool oneshot);
    void LPS22HH_Altitude_Calculation(int32_t *p_value);
    
    #endif
    
    
    
  • lps22hh.c

    
    LPS22HH_Error_Typedef LPS22HH_Reg_Write(I2C_TypeDef *I2Cx, u8 regAddr, u8* ptr, u16 cnt)
    {
        Sensor_Write(I2Cx, SLAVE_ADDRESS_WRITE, regAddr, ptr, cnt);
    
        return LPS22HH_OK;
    }
    
    
    LPS22HH_Error_Typedef LPS22HH_Reg_Read(I2C_TypeDef *I2Cx, u8 regAddr, u8* ptr, u16 cnt)
    {
        Sensor_Read(I2Cx, SLAVE_ADDRESS_READ, regAddr, ptr, cnt);
    
        return LPS22HH_OK;
    }
    
    
    u8 LPS22HH_WHO_AM_I_Get(I2C_TypeDef *I2Cx)
    {
        u8 device_id;
    	if(LPS22HH_Reg_Read(I2Cx, LPS22HH_WHO_AM_I, &device_id, 1))
        	return LPS22HH_ERROR;
    	return device_id;
    }
    
    
    LPS22HH_Error_Typedef LPS22HH_Software_Reset(I2C_TypeDef *I2Cx)
    {
    	u8 swreset = 0x04;
    	if(LPS22HH_Reg_Read(I2Cx, LPS22HH_CTRL_REG2, &swreset, 1))
        	return LPS22HH_ERROR;
    	return LPS22HH_OK;
    }
    
    //
    LPS22HH_Error_Typedef LPS22HH_Init(I2C_TypeDef *I2Cx, bool oneshot, u8 frequency)
    {
    	u8 buffer[3] = {0, 0, 0};
    
    	if(LPS22HH_WHO_AM_I_Get(I2Cx) == DEVICE_ID_WHO_AM_I){
        	buffer[0] = LPS22HH_IFC_I3C_DIS;                                        // Disable I3C in IF_CTRL
        	if(LPS22HH_Reg_Write(I2Cx, LPS22HH_IF_CTRL, buffer, 1))
            	return LPS22HH_ERROR;
    
        	if(oneshot){
            	buffer[0] = LPS22HH_CR1_BDU | LPS22HH_CR1_ODR_ONE_SHOT;             // Set BDU and ODR in CTRL_REG1
        	}else{
            	buffer[0] = LPS22HH_CR1_BDU | (frequency << LPS22HH_CR1_ODR_POS);   // Set BDU and ODR in CTRL_REG1
        	}
        	buffer[1] = LPS22HH_CR2_IF_ADD_INC;                                     // Set ONESHOT and AUTOINC in CTRL_REG1
        	buffer[2] = 0x00;                                                       // Clear CTRL_REG3
        	if(LPS22HH_Reg_Write(I2Cx, LPS22HH_CTRL_REG1, buffer, 3))
            	return LPS22HH_ERROR;
    
        	return LPS22HH_OK;
    	}else{
        	return LPS22HH_ERROR;
    	}
    }
    
    //
    LPS22HH_Error_Typedef LPS22HH_DeInit(I2C_TypeDef *I2Cx)
    {
    	u8 buffer[4] = {0, 0, 0, 0};
    
    	if(LPS22HH_Reg_Write(I2Cx, LPS22HH_CTRL_REG1, buffer, 3))
        	return LPS22HH_ERROR;
    
    	return LPS22HH_OK;
    }
    
    //
    LPS22HH_Error_Typedef LPS22HH_PRESS_OUT_Get(I2C_TypeDef *I2Cx, int32_t *P_OUT)
    {
    	uint8_t buffer[3] = {0, 0, 0};
    	// read from standard registers
    	if(LPS22HH_Reg_Read(I2Cx, LPS22HH_PRESS_OUT_XL, buffer, 3))
           	 return LPS22HH_ERROR;
    
    	*P_OUT = (buffer[2] << 16) | (buffer[1] << 8) | buffer[0];
    	return LPS22HH_OK;
    }
    
    //
    LPS22HH_Error_Typedef LPS22HH_TEMP_OUT_Get(I2C_TypeDef *I2Cx, int16_t *T_OUT)
    {
    	uint8_t buffer[2] = {0, 0};
    	// read from normal registers
       	 if(LPS22HH_Reg_Read(I2Cx, LPS22HH_TEMP_OUT_L, buffer, 2))
        	return LPS22HH_ERROR;
    
    	*T_OUT = (buffer[1] << 8) | buffer[0];
    	return LPS22HH_OK;
    }
    
    //
    LPS22HH_Error_Typedef LPS22HH_Pressure_Calculation(I2C_TypeDef *I2Cx, int32_t *value)
    {
    	int32_t P_OUT = 0x00;
    	if(LPS22HH_PRESS_OUT_Get(I2Cx, &P_OUT))
        	return LPS22HH_ERROR;
    
    	*value = (P_OUT * 10) / 4096;
    	printf("Get Pressure value : %d.%d hPa \n", *value / 10, abs(*value % 10));
    	return LPS22HH_OK;
    }
    
    //
    LPS22HH_Error_Typedef LPS22HH_Temperature_Calculation(I2C_TypeDef *I2Cx, int16_t *value)
    {
    	int16_t T_OUT = 0x00;
    	if(LPS22HH_TEMP_OUT_Get(I2Cx, &T_OUT))
        	return LPS22HH_ERROR;
    
    	*value = T_OUT / 10;
    	printf("Get Temperature value : %d.%d C \n", *value / 10, abs(*value % 10));
    	return LPS22HH_OK;
    }
    
    //
    LPS22HH_Error_Typedef LPS22HH_Calculation(I2C_TypeDef *I2Cx, int32_t *p_value, int16_t *t_value, bool oneshot)
    {
    	if(oneshot){
        	uint8_t tmp = 0x00;
        	if(LPS22HB_Reg_Read(I2Cx, LPS22HB_CTRL_REG2, &tmp, 1))
            	return LPS22HB_ERROR;
        	tmp |= LPS22HB_CR2_ONE_SHOT;
        	if(LPS22HB_Reg_Write(I2Cx, LPS22HB_CTRL_REG2, &tmp, 1))
            	return LPS22HB_ERROR;
    	}
    
    	u8 buffer = 0x00;
    	if(LPS22HH_Reg_Read(I2Cx, LPS22HH_STATUS, &buffer, 1))
        	return LPS22HH_ERROR;
    	if(buffer && LPS22HH_STATUS_P_DA != 0){
        	LPS22HH_Pressure_Calculation(I2Cx, p_value, fifo);
        	LPS22HH_Altitude_Calculation(p_value);
    	}
    	if(buffer && LPS22HH_STATUS_T_DA != 0){
        	LPS22HH_Temperature_Calculation(I2Cx, t_value, fifo);
    	}
    	return LPS22HH_OK;
    }
    
    //
    void LPS22HH_Altitude_Calculation(int32_t *p_value)
    {
    	float altitude = 44300 * (1 - pow(*p_value / 10132.5, 0.19));
    	printf("Get Altitude value : %.1f M \n", altitude);
    }
    

也可参考 ST 的 LPS22HH 使用代码STM32DUINO/LPS22HH

The End

看到一句话,感觉很棒:

社会太卷怎么办

读书,读书破万卷

P.S. 最近疫情严重,开始琢磨在家重蔬菜,生菜水培就是长得有点儿慢
lettuce

  • 11
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值