陀螺仪LSM6DSV16X与AI集成.7--检测自由落体
- 概述
- 视频教学
- 样品申请
- 源码下载
- 主要内容
- 生成STM32CUBEMX
- 串口配置
- IIC配置
- CS和SA0设置
- 串口重定向
- 参考程序
- 初始换管脚
- 获取ID
- 复位操作
- BDU设置
- 设置量程
- 设置FIFO水印
- 设置速率
- 使用流模式
- 设置FIFO时间戳批处理速率
- 使能时间戳
- FIFO状态寄存器
- 演示
概述
LSM6DSV16X是一款高性能、低功耗的6轴IMU传感器,集成了3轴加速度计和3轴陀螺仪。本文将详细介绍如何配置和读取LSM6DSV16X传感器的FIFO数据,包括初始化、配置以及数据处理的完整流程, 以实现数据的批量处理和传输,减少系统功耗,提高应用的响应速度和数据处理效率。
最近在弄ST和瑞萨RA的课程,需要样片的可以加群申请:615061293 。
视频教学
https://www.bilibili.com/video/BV12s421T73k/
陀螺仪LSM6DSV16X与AI集成(7)----FIFO数据读取与配置
样品申请
https://www.wjx.top/vm/OhcKxJk.aspx#
源码下载
https://download.csdn.net/download/qq_24312945/89471311
主要内容
- 初始化LSM6DSV16X传感器并检查其设备ID
- 恢复传感器默认配置并设置必要的参数
- 配置FIFO模式和水印阈值
- 设置加速度计和陀螺仪的数据速率
- 连续读取FIFO中的传感器数据并解析输出
LSM6DSV16X传感器包含一个FIFO缓冲区,能够存储不同类型的数据,以节省系统功耗。主处理器不需要连续轮询传感器数据,而是可以在需要时唤醒并从FIFO中读取重要数据 。
FIFO缓冲区可以存储以下类型的数据:
● 陀螺仪数据
● 加速度计数据
● 外部传感器数据(最多4个)
● 计步器数据
● 时间戳
● 温度
● 机器学习核心(MLC)特征和过滤数据
● 低功耗传感器融合算法输出数据(如四元数、陀螺仪偏差、重力向量等)
生成STM32CUBEMX
用STM32CUBEMX生成例程,这里使用MCU为STM32H503CB。
配置时钟树,配置时钟为250M。
串口配置
查看原理图,PB6和PB7设置为开发板的串口。
配置串口。
IIC配置
配置IIC速度为1M。
CS和SA0设置
串口重定向
打开魔术棒,勾选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/lsm6dsv16x-pid/tree/main
初始换管脚
由于需要向LSM6DSV16X_I2C_ADD_L写入以及为IIC模式。
所以使能CS为高电平,配置为IIC模式。
配置SA0为高电平。
printf("HELLO!\n");
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(SA0_GPIO_Port, SA0_Pin, GPIO_PIN_RESET);
HAL_Delay(100);
lsm6dsv16x_fifo_status_t fifo_status;
stmdev_ctx_t dev_ctx;
lsm6dsv16x_reset_t rst;
/* 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;
/* Init test platform */
// platform_init(dev_ctx.handle);
/* Wait sensor boot time */
platform_delay(BOOT_TIME);
获取ID
可以向WHO_AM_I (0Fh)获取固定值,判断是否为0x70。
lsm6dsv16x_device_id_get为获取函数。
对应的获取ID驱动程序,如下所示。
/* Check device ID */
lsm6dsv16x_device_id_get(&dev_ctx, &whoamI);
printf("LSM6DSV16X_ID=0x%x,whoamI=0x%x",LSM6DSV16X_ID,whoamI);
if (whoamI != LSM6DSV16X_ID)
while (1);
复位操作
可以向CTRL3 (12h)的SW_RESET寄存器写入1进行复位。
lsm6dsv16x_reset_set为重置函数。
对应的驱动程序,如下所示。
/* Restore default configuration */
lsm6dsv16x_reset_set(&dev_ctx, LSM6DSV16X_RESTORE_CTRL_REGS);
do {
lsm6dsv16x_reset_get(&dev_ctx, &rst);
} while (rst != LSM6DSV16X_READY);
BDU设置
在很多传感器中,数据通常被存储在输出寄存器中,这些寄存器分为两部分:MSB和LSB。这两部分共同表示一个完整的数据值。例如,在一个加速度计中,MSB和LSB可能共同表示一个加速度的测量值。
连续更新模式(BDU = ‘0’):在默认模式下,输出寄存器的值会持续不断地被更新。这意味着在你读取MSB和LSB的时候,寄存器中的数据可能会因为新的测量数据而更新。这可能导致一个问题:当你读取MSB时,如果寄存器更新了,接下来读取的LSB可能就是新的测量值的一部分,而不是与MSB相对应的值。这样,你得到的就是一个“拼凑”的数据,它可能无法准确代表任何实际的测量时刻。
块数据更新(BDU)模式(BDU = ‘1’):当激活BDU功能时,输出寄存器中的内容不会在读取MSB和LSB之间更新。这就意味着一旦开始读取数据(无论是先读MSB还是LSB),寄存器中的那一组数据就被“锁定”,直到两部分都被读取完毕。这样可以确保你读取的MSB和LSB是同一测量时刻的数据,避免了读取到代表不同采样时刻的数据。
简而言之,BDU位的作用是确保在读取数据时,输出寄存器的内容保持稳定,从而避免读取到拼凑或错误的数据。这对于需要高精度和稳定性的应用尤为重要。
可以向CTRL3 (12h)的BDU寄存器写入1进行开启。
对应的驱动程序,如下所示。
/* Enable Block Data Update */
lsm6dsv16x_block_data_update_set(&dev_ctx, PROPERTY_ENABLE);
设置量程
速率可以通过CTRL1 (10h)设置加速度速率和CTRL2 (11h)进行设置角速度速率。
设置加速度量程可以通过CTRL8 (17h)进行设置。
设置角速度量程可以通过CTRL6 (15h)进行设置。
设置加速度和角速度的量程和速率可以使用如下函数。
/* Set full scale */
lsm6dsv16x_xl_full_scale_set(&dev_ctx, LSM6DSV16X_2g);
lsm6dsv16x_gy_full_scale_set(&dev_ctx, LSM6DSV16X_2000dps);
设置FIFO水印
FIFO控制寄存器1 (FIFO_CTRL1):这个寄存器用于设置FIFO的水印阈值。
● WTM_[7:0]:FIFO水印阈值。当FIFO中写入的字节数大于或等于这个阈值时,水印标志位会被置高。
具体描述如下:
● 1 LSb = TAG (1 Byte) + 1 sensor (6 Bytes) written in FIFO:
○ 每个LSb表示一个TAG(1字节)和一个传感器的数据(6字节)被写入FIFO。
○ 因此,每个水印阈值单位对应的大小是7字节(1字节的TAG加上6字节的传感器数据)。
下面代码设置了FIFO的水印阈值。当FIFO中存储的数据达到该阈值时,传感器会产生一个中断信号,以通知主处理器读取数据。水印值是未读传感器数据TAG和6个字节的数据样本总数。
lsm6dsv16x_fifo_watermark_set(&dev_ctx, FIFO_WATERMARK);
在配置LSM6DSV16X传感器的FIFO功能时,每个传感器数据样本的大小为6字节。这是因为加速度计和陀螺仪的每个数据样本都包含三个轴向的数据,每个轴向的数据用2字节表示。具体来说:
● 加速度计数据:包含X、Y、Z三个轴向的数据,每个轴向的数据大小为2字节。因此,加速度计的一个完整数据样本大小为3轴 * 2字节 = 6字节。
● 陀螺仪数据:同样包含X、Y、Z三个轴向的数据,每个轴向的数据大小也是2字节。因此,陀螺仪的一个完整数据样本大小也是3轴 * 2字节 = 6字节。
#define FIFO_WATERMARK 64的定义是为了在FIFO中存储64个样本后触发中断。因为每个样本大小为7字节(1字节的TAG和6字节的传感器数据),所以当FIFO中存储的数据达到448字节(64 * 7字节)时,会触发中断通知主处理器读取数据。
这可以通过以下公式计算:
水印阈值字节数=64×(1字节的TAG+6字节的传感器数据)=448字节
这个设置可以确保在适当的时间间隔内读取数据,既避免了频繁中断带来的开销,又不会因为FIFO溢出而丢失数据。
设置速率
LSM6DSV16X传感器的FIFO控制寄存器3(FIFO_CTRL3)的内容,该寄存器用于选择陀螺仪和加速度计数据写入FIFO的批处理数据速率(BDR,Batch Data Rate)。以下是详细描述:
FIFO_CTRL3寄存器(地址09h),该寄存器包含两个主要字段:
● BDR_GY_[3:0]:选择陀螺仪数据的批处理速率。
● BDR_XL_[3:0]:选择加速度计数据的批处理速率。
将加速度计的数据速率(Output Data Rate, ODR)设置为60Hz。这意味着加速度计的数据将以每秒60次的频率批量写入FIFO。
将陀螺仪的数据速率设置为15Hz。这意味着陀螺仪的数据将以每秒15次的频率批量写入FIFO。
/* Set FIFO batch XL/Gyro ODR to 12.5Hz */
lsm6dsv16x_fifo_xl_batch_set(&dev_ctx, LSM6DSV16X_XL_BATCHED_AT_60Hz);
lsm6dsv16x_fifo_gy_batch_set(&dev_ctx, LSM6DSV16X_GY_BATCHED_AT_15Hz);
使用流模式
FIFO控制寄存器4(FIFO_CTRL4)用于选择FIFO模式,并提供以下选项:
FIFO_MODE_[2:0] 字段用于选择FIFO模式,详细描述如下:
000: 旁路模式(FIFO禁用,默认)
001: FIFO模式(当FIFO满时停止收集数据)
010: 连续模式直到水印标志被设置为满模式(FIFO水印标志设置为满模式之前,连续模式)
011: 连续模式直到解除触发,之后为FIFO模式
100: 旁路到连续模式(旁路模式直到解除触发,之后为连续模式)
101: 保留
110: 连续模式(如果FIFO满了,新样本将覆盖旧的样本)
111: 旁路到FIFO模式(旁路模式直到解除触发,之后为FIFO模式)
使用流模式有以下优点:
持续数据采集:适用于需要连续监控的场景,如运动跟踪和实时监控应用。
数据最新性:始终获取到最新的数据,避免数据滞后。
无需等待FIFO清空:当FIFO填满时,新数据自动覆盖旧数据,无需手动清空FIFO。
/* Set FIFO mode to Stream mode (aka Continuous Mode) */
lsm6dsv16x_fifo_mode_set(&dev_ctx, LSM6DSV16X_STREAM_MODE);
设置FIFO时间戳批处理速率
LSM6DSV16X传感器的时间戳批处理速率、温度数据批处理速率、增强的EIS陀螺仪输出批处理,以及FIFO的工作模式。这些配置确保传感器数据能够以适当的速率和模式进行批处理和存储,以满足不同的应用需求。
/* Set Output Data Rate */
lsm6dsv16x_xl_data_rate_set(&dev_ctx, LSM6DSV16X_ODR_AT_60Hz);
lsm6dsv16x_gy_data_rate_set(&dev_ctx, LSM6DSV16X_ODR_AT_15Hz);
lsm6dsv16x_fifo_timestamp_batch_set(&dev_ctx, LSM6DSV16X_TMSTMP_DEC_8);
使能时间戳
FUNCTIONS_ENABLE寄存器(地址50h) 的TIMESTAMP_EN可以使能时间戳计数器。计数器的值可以从TIMESTAMP0(40h),TIMESTAMP1(41h),TIMESTAMP2(42h)和TIMESTAMP3(43h)寄存器读取。
lsm6dsv16x_timestamp_set(&dev_ctx, PROPERTY_ENABLE);
FIFO状态寄存器
LSM6DSV16X传感器的FIFO状态寄存器FIFO_STATUS2 (1Ch)的FIFO_WTM_IA可以判断FIFO水印状态。
0:FIFO填充量低于水印。
1:FIFO填充量等于或大于水印。
DIFF_FIFO包括DIFF_FIFO_[7:0]和DIFF_FIFO_8,总共9位,用于精确表示未读数据样本的数量。
FIFO_DATA_OUT_TAG寄存器(地址78h)用于标识存储在FIFO中的传感器数据类型。以下是详细解释:
字段:
TAG_SENSOR_[4:0]:用于标识存储在FIFO中的传感器数据类型。
TAG_CNT_[1:0]:用于标识传感器时间槽的2位计数器。
LSM6DSV16X传感器的FIFO数据输出寄存器用于读取FIFO中的X轴、Y轴和Z轴数据。以下是详细解释:
FIFO_DATA_OUT_X_L (79h) 和 FIFO_DATA_OUT_X_H (7Ah) 寄存器
功能:读取FIFO中X轴的数据。
寄存器描述:
FIFO_DATA_OUT_X_L (低字节):包含X轴数据的低8位。
FIFO_DATA_OUT_X_H (高字节):包含X轴数据的高8位。
组合读取16位X轴数据:D[15:0]。
FIFO_DATA_OUT_Y_L (7Bh) 和 FIFO_DATA_OUT_Y_H (7Ch) 寄存器
功能:读取FIFO中Y轴的数据。
寄存器描述:
FIFO_DATA_OUT_Y_L (低字节):包含Y轴数据的低8位。
FIFO_DATA_OUT_Y_H (高字节):包含Y轴数据的高8位。
组合读取16位Y轴数据:D[15:0]。
FIFO_DATA_OUT_Z_L (7Dh) 和 FIFO_DATA_OUT_Z_H (7Eh) 寄存器
功能:读取FIFO中Z轴的数据。
寄存器描述:
FIFO_DATA_OUT_Z_L (低字节):包含Z轴数据的低8位。
FIFO_DATA_OUT_Z_H (高字节):包含Z轴数据的高8位。
组合读取16位Z轴数据:D[15:0]。
其中时间戳速度单位为21.75us。
演示
实际测试如下所示,数据为64个数据。
加速度速率为60Hz,角速度速率为15Hz,所以数据输出基本上为4个ACC数据一个GYR数据。
时间戳速率60Hz/8为7.5Hz(133.33ms),大概8个ACC数据之后出现一个时间戳数据。
下图中的2个时间戳数据为81998618和81992474,81998618-81992474=6144*21.75us=133.632ms