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
-
VDD_IO: Power Supply -
SCL / SPC: SCL for I2C and I3C serial clock; SPC for SPI serial port clock -
RES: Connected to GND -
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 -
SA0 / SDO: SA0 for I2C and I3C LSB address; SDO for 4-wire SPI serial data output -
CS: interface selection 0 for SPI; 1 for I2C / I3C -
INT_DRDY: Interrupt or Data-Ready; Floating(Internal pull-down) for I2C and I3C; VDD_IO for I3C only -
GND -
GND -
VDD
在 MB-018 中,LPS22HH 连接 I2C,CS 接 VDD,SA0 接地 LSB = 0,INT_DRDY floating,I3C_DISABLE 置 1
LPS22HH Address
SA0 管脚决定了地址 LSB 位的高低,这样主控就可以连两个 LPS22HH 传感器,从地址不会冲突
#define SLAVE_ADDRESS_SA0 0x00
#define SLAVE_ADDRESS (0x5C | SLAVE_ADDRESS_SA0)
#define SLAVE_ADDRESS_WRITE SLAVE_ADDRESS << 1
#define SLAVE_ADDRESS_READ (SLAVE_ADDRESS << 1) | 0x01
I2C 对 LPS22HH 进行读写
I2C 读写方式及原理可见「Rose Island」MM32F3277 I2C 访问 HTS221 温湿度传感器
Master write data to Slave
Steps:
-
Master 发送 START 信号(SCL hold high, SDA high to low) -
Master 发送 Slave 的 7 位地址 + 写信号 -
Slave 进行地址匹配,匹配成功回应 SAK -
Master 发送 SubAddress,即 Slave 内部寄存器地址 通过CTRL_REG2 中的 IF_ADD_INC 位决定 SubAddr 地址是否自增,即是否可以连续操作多个寄存器,该位默认为高 #define LPS22HH_CTRL_REG1 0x10
LPS22HH_Reg_Write(I2Cx, LPS22HH_CTRL_REG1, buffer, 1)
-
Slave 应答 SubAddr -
Master 发送 DATA,Slave 应答 SAK -
Master 发送完后,产生 STOP 信号(SCL hold high, SDA low to high)
Master read data from Slave
Steps:
- Master 发送 START 信号(SCL hold high, SDA high to low)
- Master 发送 Slave 的 7 位地址 + 写信号
- Slave 进行地址匹配,匹配成功回应 SAK
- Master 发送 SubAddress,即 Slave 内部寄存器地址,操作同上
- Slave 应答 SubAddr
- Master 发送 RESTART 信号,重新发送 Slave 的 7 位地址 + 读信号,Slave 回应 SAK
- Slave 发送 Data,Master 应答 MAK
- Master 接收最后一个数据后,不应答 NMAK,产生 STOP 信号(SCL hold high, SDA lowto high)
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
-
PHE : 当气压比设定的标准线高时产生中断,标准线由用户定义,存储在 THS_P 寄存器中 -
PLE : 当气压比设定的标准线低时产生中断,标准线由用户定义,存储在 THS_P 寄存器中 -
LIR : 是否锁存中断请求至 INT_SOURCE 寄存器 -
DIFF_EN : 中断使能 -
RESET_AZ : Reset AUTOZERO function -
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
如果使用了 AUTOZERO ,PHE 比较的是 P_DIFF_IN 和 THS_P -
RESET_ARP : Reset AUTOREFP function -
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_CFG 中 DIFF_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
I2C_DISABLE : Set 0 to enable I2C; Set 1 to disable I2CI3C_DISABLE : Set 0 to enable I3C; Set 1 to disable I3CPD_DIS_INT1 : 置 0 时 INT1 管脚下拉;置 1 时 INT1 管脚不下拉SDO_PU_EN : 置 0 时 SDO 管脚不上拉;置 1 时 SDO 管脚上拉SDA_PU_EN : 置 0 时 SDA 管脚不上拉;置 1 时 SDA 管脚上拉INT_EN_I3C : 置 0 时 INT1 管脚不使能 I3C;置 0 时 INT1 管脚使能 I3C -
WHO_AM_I Reg Address is 0x0F, read only and default is 0xB3
#define DEVICE_ID_WHO_AM_I 0xB3
-
CTRL_REG1 Reg Address is 0x10, R/W and default is 0x00
SIM : 置 0 为 4 线 SPI;置 1 为 3 线 SPIBDU : 置 0 为连续更新 MSB 和 LSB 的数据;置 1 为只有当 MSB 和 LSB 都被读取了之后再更新数据,建议置 1LPFP_CFG : 如果低通滤波器未使能,bandwith = ODR / 2;如果低通滤波器使能且该位为 0,bandwith = ODR / 9;如果低通滤波器使能且该位为 1,bandwith = ODR / 20EN_LPFP : 是否使能低通滤波器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
ONE_SHOT : 触发 One_Shot,CFGR_REG1 中的 ODR 位需要是 0x00,硬件清零LOW_NOISE_EN : 置 0 为 low-current 模式;置 1 为 low-noise 模式,此时 ODR < 100HzSWRESET : 置 1 为软件重启,硬件清零IF_ADD_INC : I2C / SPI 模式下操作寄存器时,地址自增PP_OD : interrupt 管脚配置,置 0 为推挽输出;置 1 为开漏输出INT_H_L : 置 0 为 interrupt 高有效;置 1 为低有效BOOT : 置 1 为 reboot,硬件清零 -
CTRL_REG3 Reg Address is 0x12, R/W and default is 0x00
INT_S : INT_DRDY 管脚输出,00 为 Data Signal,01 为 Pressure high 中断,10 为 Pressure Low 中断,11 为 Pressure High or Low 中断DRDY : INT_DRDY 管脚输出 Data ready signalINT_F_OVR : INT_DRDY 管脚输出 FIFO overrun statusINT_F_WTM : INT_DRDY 管脚输出 FIFO threshold statusINT_F_FULL : INT_DRDY 管脚输出 FIFO full flag
-
FIFO_CTRL Reg Address is 0x13, R/W and default is 0x00
-
F_MODE / TRIG_MODES
TRIG_MODES | F_MODE | MODE |
---|
X | 00 | Bypass mode | 0 | 01 | FIFO mode | 0 | 1X | Continuous (Dynamic-Stream) mode | 1 | 01 | Bypass to FIFO mode | 1 | 10 | Bypass to Continuous (Dynamic-Stream) mode | 1 | 11 | Continuous (Dynamic-Stream) to FIFO mode |
-
STOP_ON_WTM : 如果设置了 FIFO_WTM 的 WTM 位,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_CFG 中 AUTOZERO 和 AUTOREFP 使能时,需要用到参考气压值 -
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
PH : high differential pressure eventPL : low differential pressure eventIA : one or more interrupt event generatedBOOT_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
FIFO_FULL_IA : FIFO 满但未溢出FIFO_OVR_IA : FIFO 满且溢出FIFO_WTM_IA : FIFO 大于等于 watermark level -
STATUS Reg Address is 0x27, read only and default is 0x00 跟着 ODR 频率更新
P_DA : 有新的压力数据了T_DA : 有新的温度数据了P_OR : 压力数据溢出,旧的数据被替换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;
#define LPS22HH_IT_PHE 0x01
#define LPS22HH_IT_PLE 0x02
#define LPS22HH_IT_MODE_RESETAZ 0x10
#define LPS22HH_IT_MODE_AUTOZERO 0x20
#define LPS22HH_IT_MODE_RESETARP 0x40
#define LPS22HH_IT_MODE_AUTOREFP 0x80
#define LPS22HH_ITS_PH_FLAG 0x01
#define LPS22HH_ITS_PL_FLAG 0x02
#define LPS22HH_ITS_IA_FLAG 0x04
#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
#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_
#define LPS22HH_INTERRUPT_CFG 0x0B
#define LPS22HH_THS_P_L 0x0C
#define LPS22HH_THS_P_H 0x0D
#define LPS22HH_IF_CTRL 0x0E
#define LPS22HH_WHO_AM_I 0x0F
#define LPS22HH_CTRL_REG1 0x10
#define LPS22HH_CTRL_REG2 0x11
#define LPS22HH_CTRL_REG3 0x12
#define LPS22HH_FIFO_CTRL 0x13
#define LPS22HH_FIFO_WTM 0x14
#define LPS22HH_REF_P_L 0x15
#define LPS22HH_REF_P_H 0x16
#define LPS22HH_RPDS_L 0x18
#define LPS22HH_RPDS_H 0x19
#define LPS22HH_INT_SOURCE 0x24
#define LPS22HH_FIFO_STATUS1 0x25
#define LPS22HH_FIFO_STATUS2 0x26
#define LPS22HH_STATUS 0x27
#define LPS22HH_PRESS_OUT_XL 0x28
#define LPS22HH_PRESS_OUT_L 0x29
#define LPS22HH_PRESS_OUT_H 0x2A
#define LPS22HH_TEMP_OUT_L 0x2B
#define LPS22HH_TEMP_OUT_H 0x2C
#define LPS22HH_FIFO_DATA_OUT_PRESS_XL 0x78
#define LPS22HH_FIFO_DATA_OUT_PRESS_L 0x79
#define LPS22HH_FIFO_DATA_OUT_PRESS_H 0x7A
#define LPS22HH_FIFO_DATA_OUT_TEMP_L 0x7B
#define LPS22HH_FIFO_DATA_OUT_TEMP_H 0x7C
#define SLAVE_ADDRESS_SA0 0x00
#define SLAVE_ADDRESS (0x5C | SLAVE_ADDRESS_SA0)
#define SLAVE_ADDRESS_WRITE SLAVE_ADDRESS << 1
#define SLAVE_ADDRESS_READ (SLAVE_ADDRESS << 1) | 0x01
#define DEVICE_ID_WHO_AM_I 0xB3
#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)
#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)
#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)
#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)
#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)
#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)
#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)
#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)
#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;
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;
}else{
buffer[0] = LPS22HH_CR1_BDU | (frequency << LPS22HH_CR1_ODR_POS);
}
buffer[1] = LPS22HH_CR2_IF_ADD_INC;
buffer[2] = 0x00;
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};
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};
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. 最近疫情严重,开始琢磨在家重蔬菜,生菜水培就是长得有点儿慢
|