本文将介绍如何使用 LPS22DF 传感器来读取数据。LPS22DF是一款超紧凑型压阻绝对压力传感器,可用作数字输出气压计。LPS22DF相比前代产品具有更低的功耗和更小的压力噪声。
本章主要步骤包括初始化传感器接口、验证设备ID、配置传感器的数据输出率和滤波器,以及通过轮询方式持续读取气压数据和温度数据。读取到的数据会被转换为适当的单位并通过串行通信输出。
最近在弄ST的教程,需要样片的可以加群申请:615061293/925643491 。
首先需要准备一个开发板,这里我准备的是自己绘制的开发板,需要的可以进行申请。 主控为STM32U073CC,气压计为LPS22DF
[https://www.bilibili.com/video/BV1PbmEYXE2J/]
[https://www.wjx.top/vm/OhcKxJk.aspx#]
[https://download.csdn.net/download/qq_24312945/89972258]
LPS22DF是一款超紧凑型压阻绝对压力传感器,可用作数字输出气压计。LPS22DF相比前代产品具有更低的功耗和更小的压力噪声。
该器件包含传感元件和IC接口,该接口通过I²C、MIPI I3CSM或SPI接口实现传感元件与应用的通信,同时该器件也支持用于数据接口的广泛Vdd IO。检测绝对压力的传感元件由悬浮膜组成,采用ST开发的专门工艺进行制造。
LPS22DF采用全压塑孔LGA封装(HLGA)。可保证在-40 °C到+85 °C的温度范围都能工作。封装上有开孔,以便外部压力到达传感元件。
260-1260 hPa 的绝对压力范围,适用于多种气压应用。 最低电流消耗可达 1.7 μA,适合低功耗设备。 压力精度达 0.2 hPa,并具备 0.34 Pa 的低噪声和 0.45 Pa/°C 的温度补偿偏移。
对于LPS22DF,可以使用IIC进行通讯。
最小系统图如下所示。
本文使用的板子原理图如下所示。
该模块支持的I2C速度为快速模式1M。
用STM32CUBEMX生成例程,这里使用MCU为STM32H503CB。 配置时钟树,配置时钟为250M。
查看原理图,PA9和PA10设置为开发板的串口。
配置串口,速率为115200。
配置IIC为快速模式,速度为400k。
通过设置SA0管脚的高低电平可以改变模块的地址。
这里设置SA0管脚位输出管脚。
LPS22DF可以通过CS管脚进行IIC或者SPI通讯切换
若无法正常运行需要修改优化等级。
打开魔术棒,勾选MicroLIB
在main.c中,添加头文件,若不添加会出现 identifier "FILE" is undefined报错。
/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes */
函数声明和串口重定向:
/* USER CODE BEGIN PFP */
int fputc(int ch, FILE *f){
HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
/* USER CODE END PFP */
[https://github.com/STMicroelectronics/lps22df-pid/]
使能SA0为低电平,配置模块地址。
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(SA0_GPIO_Port, SA0_Pin, GPIO_PIN_RESET); //GPIO_PIN_RESET
printf("hello!n");
lps22df_pin_int_route_t int_route;
lps22df_all_sources_t all_sources;
lps22df_bus_mode_t bus_mode;
stmdev_ctx_t dev_ctx;
lps22df_id_t id;
lps22df_md_t md;
int ret;
/* Initialize mems driver interface */
dev_ctx.write_reg = platform_write;
dev_ctx.read_reg = platform_read;
dev_ctx.mdelay = platform_delay;
dev_ctx.handle = &SENSOR_BUS;
可以向WHO_AM_I (0Fh)获取固定值,判断是否为0xB4。
lps22df_id_get为获取函数。
对应的获取ID驱动程序,如下所示。
/* Check device ID */
lps22df_id_get(&dev_ctx, &id);
printf("LPS22DF_ID=0x%x,whoamI=0x%xn",LPS22DF_ID,id.whoami);
if (id.whoami != LPS22DF_ID)
while(1);
可以向CTRL_REG2 (11h)的BOOT位和SWRESET位写入1进行软件复位。
● BOOT: 重启存储在非易失性存储器中的寄存器内容。设置为 1 后立即执行,完成后自动清零。用于恢复工厂校准参数。
● SWRESET: 软件复位。设置为 1 会触发复位,复位完成后自动清零。
对应的驱动程序,如下所示。
/* Boot device */
ret = lps22df_init_set(&dev_ctx, LPS22DF_BOOT);
if (ret != 0)
while(1);
/* Reset device */
ret = lps22df_init_set(&dev_ctx, LPS22DF_RESET);
if (ret != 0)
while(1);
在很多传感器中,数据通常被存储在输出寄存器中,这些寄存器分为两部分:MSB和LSB。这两部分共同表示一个完整的数据值。例如,在一个加速度计中,MSB和LSB可能共同表示一个加速度的测量值。
连续更新模式(BDU = ‘0’):在默认模式下,输出寄存器的值会持续不断地被更新。这意味着在你读取MSB和LSB的时候,寄存器中的数据可能会因为新的测量数据而更新。这可能导致一个问题:当你读取MSB时,如果寄存器更新了,接下来读取的LSB可能就是新的测量值的一部分,而不是与MSB相对应的值。这样,你得到的就是一个“拼凑”的数据,它可能无法准确代表任何实际的测量时刻。
块数据更新(BDU)模式(BDU = ‘1’):当激活BDU功能时,输出寄存器中的内容不会在读取MSB和LSB之间更新。这就意味着一旦开始读取数据(无论是先读MSB还是LSB),寄存器中的那一组数据就被“锁定”,直到两部分都被读取完毕。这样可以确保你读取的MSB和LSB是同一测量时刻的数据,避免了读取到代表不同采样时刻的数据。
简而言之,BDU位的作用是确保在读取数据时,输出寄存器的内容保持稳定,从而避免读取到拼凑或错误的数据。这对于需要高精度和稳定性的应用尤为重要。
可以向CTRL_REG2 (11h)的BDU寄存器写入1进行开启。
对应的驱动程序,如下所示。
/* Set bdu and if_inc recommended for driver usage */
lps22df_init_set(&dev_ctx, LPS22DF_DRV_RDY);
设置速率和平均样本数可以通过CTRL_REG1 (10h)进行设置。
● ODR[3:0](输出数据速率选择):用于设置传感器的数据输出速率。默认值为 0000(关机/单次采样模式)。可以设置的频率包括 1 Hz、4 Hz、10 Hz、25 Hz、50 Hz、75 Hz、100 Hz 和 200 Hz。不同的输出速率适用于不同应用场景,频率越高数据更新越快,但功耗也相应增加。
● AVG[2:0](平均选择):用于选择压力和温度数据的平均样本数。默认值为 000(4 次平均)。可选项包括 4、8、16、32、64、128 和 512。较高的平均数可以提高测量精度,但会导致响应速度下降。
/* Select bus interface */
bus_mode.filter = LPS22DF_FILTER_AUTO;
bus_mode.interface = LPS22DF_SEL_BY_HW;
lps22df_bus_mode_set(&dev_ctx, &bus_mode);
/* Set Output Data Rate */
md.odr = LPS22DF_4Hz;
md.avg = LPS22DF_16_AVG;
md.lpf = LPS22DF_LPF_ODR_DIV_4;
lps22df_mode_set(&dev_ctx, &md);
/* Configure inerrupt pins */
lps22df_pin_int_route_get(&dev_ctx, &int_route);
int_route.drdy_pres = PROPERTY_DISABLE;
lps22df_pin_int_route_set(&dev_ctx, &int_route);
对于压强和温度数据是否准备好,可以查看STATUS (27h)的T_DA位和P_DA位,判断是否有新数据到达。
● T_DA(温度数据可用):表示新的温度数据是否生成。
● P_DA(压力数据可用):表示新的压力数据是否生成。
该寄存器在每个 ODR 周期都会更新,以反映最新的温度和压力数据状态。————————————————
原文链接:https://blog.csdn.net/qq_24312945/article/details/142976931
对于压强数据,主要在LPS22DF_PRESS_OUT_XL (28h)-LPS22DF_PRESS_OUT_H (2Ah)。
压强转换如下所示。
对于温度数据,主要在TEMP_OUT_L (2Bh)-TEMP_OUT_H (2Ch)。
对应代码如下。
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* Read output only if new values are available */
lps22df_all_sources_get(&dev_ctx, &all_sources);
if ( all_sources.drdy_pres | all_sources.drdy_temp ) {
lps22df_data_get(&dev_ctx, &data);
printf("pressure [hPa]:%6.2f temperature [degC]:%6.2frn",
data.pressure.hpa, data.heat.deg_c);
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
正常气压为50hPa到1050hPa之间。
审核编辑 黄宇
全部0条评论
快来发表一下你的评论吧 !