当前位置: 首页 > wzjs >正文

网站备案 做网站时就需要吗官方正版清理优化工具

网站备案 做网站时就需要吗,官方正版清理优化工具,郑州影楼网站建设,泉州seo网站建设费用STM32H5开发陀螺仪LSM6DSV16X.3--SFLP获取四元数 概述视频教学样品申请源码下载硬件准备参考程序SFLP生成STM32CUBEMX串口配置IIC配置CS和SA0设置ICASHE修改堆栈串口重定向参考程序初始换管脚获取ID复位操作BDU设置设置量程初始化SFLP步骤FIFO 阈值配置 FIFO 模式设置FIFO模式为…

STM32H5开发陀螺仪LSM6DSV16X.3--SFLP获取四元数

  • 概述
  • 视频教学
  • 样品申请
  • 源码下载
  • 硬件准备
  • 参考程序
  • SFLP
  • 生成STM32CUBEMX
  • 串口配置
  • IIC配置
  • CS和SA0设置
  • ICASHE
  • 修改堆栈
  • 串口重定向
  • 参考程序
  • 初始换管脚
  • 获取ID
  • 复位操作
  • BDU设置
  • 设置量程
  • 初始化SFLP步骤
  • FIFO 阈值
  • 配置 FIFO 模式
  • 设置FIFO模式为Stream(连续)模式
  • 设置 加速度计 ODR
  • 设置 陀螺仪 ODR
  • 设定 SFLP 输出速率
  • 启用 SFLP 四元数输出
  • 设置陀螺仪偏置(Gyro Bias)值
  • 读取四元数数据
  • 演示

概述

在现代的运动跟踪和姿态检测应用中,低功耗、高精度的传感器数据融合处理变得越来越重要。LSM6DSV16X传感器集成了SFLP(Sensor Fusion Low Power)算法模块,可以在低功耗模式下实现六轴传感器数据的高效融合。SFLP模块通过处理加速度计和陀螺仪的数据,生成一个表示设备姿态的四元数,这为游戏、增强现实(AR)、虚拟现实(VR)等应用中的精准运动追踪提供了技术支持。在本文中,我们将深入探讨如何利用SFLP模块获取四元数数据,并分析其在实际应用中的优势和实现方法。

最近在弄ST和瑞萨RA的课程,需要样片的可以加群申请:615061293 。

在这里插入图片描述

视频教学

https://www.bilibili.com/video/BV1a854zmELy

STM32H5开发陀螺仪LSM6DSV16X(3)----SFLP获取四元数

样品申请

https://www.wjx.top/vm/OhcKxJk.aspx#

源码下载

硬件准备

首先需要准备一个开发板,这里我准备的是自己绘制的开发板,需要的可以进行申请。
主控为STM32H503CB,陀螺仪为LSM6DSV16X,磁力计为LIS2MDL。

在这里插入图片描述

参考程序

https://github.com/CoreMaker-lab/STM32H503_LSM6DSV16X_LIS2MDL

https://gitee.com/CoreMaker/STM32H503_LSM6DSV16X_LIS2MDL

SFLP

LSM6DSV16X 特性涉及到的是一种低功耗的传感器融合算法(Sensor Fusion Low Power, SFLP).
低功耗传感器融合(SFLP)算法:
该算法旨在以节能的方式结合加速度计和陀螺仪的数据。传感器融合算法通过结合不同传感器的优势,提供更准确、可靠的数据。
6轴游戏旋转向量:
SFLP算法能够生成游戏旋转向量。这种向量是一种表示设备在空间中方向的数据,特别适用于游戏和增强现实应用,这些应用中理解设备的方向和运动非常关键。
四元数表示法:
旋转向量以四元数的形式表示。四元数是一种编码3D旋转的方法,它避免了欧拉角等其他表示法的一些限制(如万向节锁)。一个四元数有四个分量(X, Y, Z 和 W),其中 X, Y, Z 代表向量部分,W 代表标量部分。
FIFO存储:
四元数的 X, Y, Z 分量存储在 LSM6DSV16X 的 FIFO(先进先出)缓冲区中。FIFO 缓冲区是一种数据存储方式,允许临时存储传感器数据。这对于有效管理数据流非常有用,特别是在数据处理可能不如数据收集那么快的系统中。

在这里插入图片描述

图片包含了关于 LSM6DSV16X 传感器的低功耗传感器融合(Sensor Fusion Low Power, SFLP)功能的说明。这里是对图片内容的解释:
SFLP 功能:

  1. SFLP 单元用于生成基于加速度计和陀螺仪数据处理的以下数据:
  2. 游戏旋转向量:以四元数形式表示设备的姿态。
  3. 重力向量:提供一个三维向量,表示重力方向。
  4. 陀螺仪偏差:提供一个三维向量,表示陀螺仪的偏差。
    激活与重置:
  5. 通过在 EMB_FUNC_EN_A(04h)嵌入式功能寄存器中设置 SFLP_GAME_EN 位为 1 来激活 SFLP 单元。
  6. 通过在 EMB_FUNC_INIT_A(66h)嵌入式功能寄存器中设置 SFLP_GAME_INIT 位为 1 来重置 SFLP 单元。
    性能参数表:
    表格展示了 SFLP 功能在不同情况下的性能,包括静态精度、低动态精度和高动态精度,以及校准时间和方向稳定时间。这些参数反映了传感器在不同运动状态下的精确度和响应速度。

在这里插入图片描述

生成STM32CUBEMX

用STM32CUBEMX生成例程,这里使用MCU为STM32H503CB。
配置时钟树,配置时钟为250M。

在这里插入图片描述

串口配置

查看原理图,PA9和PA10设置为开发板的串口。

在这里插入图片描述
配置串口,速率为2000000。

在这里插入图片描述

IIC配置

在这里插入图片描述
在这里插入图片描述
配置IIC为快速模式,速度为400k。

在这里插入图片描述

CS和SA0设置

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

ICASHE

在这里插入图片描述

修改堆栈

在这里插入图片描述

串口重定向

打开魔术棒,勾选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

初始换管脚

由于需要向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_4g);lsm6dsv16x_gy_full_scale_set(&dev_ctx, LSM6DSV16X_2000dps);

初始化SFLP步骤

启用 LSM6DSV16X 传感器中的旋转向量低功耗传感器融合(Rotation Vector SFLP)功能的步骤。旋转向量是一个四元数,它提供了一个精确的设备姿态估计。这通常用于游戏控制、增强现实和虚拟现实等应用。下面是函数各部分的作用:

  1. 函数定义:LSM6DSV16XSensor_Enable_Rotation_Vector 旨在启用旋转向量功能,并返回操作的结果。如果成功,返回 0;如果出现错误,则返回错误代码。
  2. 设置满量程:函数首先设置加速度计和陀螺仪的满量程,这是传感器能够测量的最大范围。这里分别设置为 4g 和 2000 度每秒(dps)。
  3. 获取 FIFO SFLP 设置:然后,它读取当前的 FIFO SFLP(传感器融合低功耗)配置。
  4. 启用旋转向量 SFLP 特性:通过将 fifo_sflp.game_rotation 设为 1 来启用游戏旋转向量功能。
  5. 设置 FIFO 模式:将 FIFO 设置为流模式(也称为连续模式),在此模式下,数据持续地流入 FIFO,如果 FIFO 满了,新数据会覆盖旧数据。
  6. 设置数据输出率:为加速度计和陀螺仪以及 SFLP 设置数据输出率(ODR),在这里都设置为每秒 120 次采样(120Hz)。
  7. 启用 SFLP 低功耗模式:最后,启用 SFLP 游戏旋转向量特性,确保以低功耗模式运行。

FIFO 阈值

设置 FIFO 的“水位阈值”,即 当 FIFO 中存储的数据量 ≥ 该阈值时,传感器会触发 Watermark 中断(如果配置了中断)。
表示当 FIFO 中累积了FIFO_WATERMARK(32)时,就会满足“水位条件”。
LSM6DSV16X 的 FIFO_CTRL1(0x07)寄存器,是设置 FIFO 水位阈值(watermark threshold) 的关键寄存器。

在这里插入图片描述

1 LSB 表示 1个样本,每个样本由:
● 1 byte TAG(标识是哪类数据,如 GYRO/ACC)
● 6 byte 数据(例如三轴陀螺仪 X/Y/Z,每轴2字节)
设置了 FIFO 的“容量警戒线”为 32 个样本,等于 224 字节,一旦数据满到这个程度,FIFO_WTM_IA 标志就会被置位,从而引发中断或被 MCU 轮询识别到,随后就可以读取 FIFO 里的数据了。

  /** Set FIFO watermark (number of unread sensor data TAG + 6 bytes* stored in FIFO) to FIFO_WATERMARK samples*/lsm6dsv16x_fifo_watermark_set(&dev_ctx, FIFO_WATERMARK);

配置 FIFO 模式

设置 SFLP 模块中要写入 FIFO 的三类输出:
在这里插入图片描述
那么 FIFO 中的每个 SFLP 样本,可能是:
● 四元数:QX, QY, QZ, QW
● 重力向量:3 轴重力向量
● 陀螺仪偏置:3 轴陀螺仪偏置

在这里插入图片描述

  /* Set FIFO batch of sflp data */fifo_sflp.game_rotation = 1;fifo_sflp.gravity = 1;fifo_sflp.gbias = 1;lsm6dsv16x_fifo_sflp_batch_set(&dev_ctx, fifo_sflp);

设置FIFO模式为Stream(连续)模式

Stream Mode 是最常用于实时流数据采集的方式 —— 即使 FIFO 满了,也继续采集,不丢失最新数据(会覆盖旧数据)。

在这里插入图片描述

  /* Set FIFO mode to Stream mode (aka Continuous Mode) */lsm6dsv16x_fifo_mode_set(&dev_ctx, LSM6DSV16X_STREAM_MODE);

设置 加速度计 ODR

设置 加速度计 ODR(输出数据率)为 30Hz。

在这里插入图片描述

  /* Set Output Data Rate */lsm6dsv16x_xl_data_rate_set(&dev_ctx, LSM6DSV16X_ODR_AT_30Hz);

设置 陀螺仪 ODR

设置 陀螺仪 ODR 为 30Hz。

在这里插入图片描述

  lsm6dsv16x_gy_data_rate_set(&dev_ctx, LSM6DSV16X_ODR_AT_30Hz);

设定 SFLP 输出速率

设定 SFLP 模块自身的输出速率,控制四元数/重力/陀螺仪偏置等数据输出频率。

在这里插入图片描述

lsm6dsv16x_sflp_data_rate_set(&dev_ctx, LSM6DSV16X_SFLP_30Hz);

启用 SFLP 四元数输出

启用 SFLP 的四元数输出。

在这里插入图片描述

  lsm6dsv16x_sflp_game_rotation_set(&dev_ctx, PROPERTY_ENABLE);

设置陀螺仪偏置(Gyro Bias)值

初始化时设置陀螺仪偏置(Gyro Bias)值,目的是为了提升姿态融合(四元数)算法的准确性,特别适用于你使用的 SFLP(Sensor Fusion Low Power)模块。

  /** here application may initialize offset with latest values* calculated from previous run and saved to non volatile memory.*/gbias.gbias_x = 0.0f;gbias.gbias_y = 0.0f;gbias.gbias_z = 0.0f;lsm6dsv16x_sflp_game_gbias_set(&dev_ctx, &gbias);

读取四元数数据

FIFO_STATUS1(1Bh)和 FIFO_STATUS2(1Ch)寄存器中的 DIFF_FIFO [8:0] 字段包含在 FIFO 中收集的字(1 字节标签 + 6 字节数据)的数量。

在这里插入图片描述
在这里插入图片描述

    /* Read watermark flag */status=lsm6dsv16x_fifo_status_get(&dev_ctx, &fifo_status);

之后需要通过FIFO_DATA_OUT_TAG (78h)判断是什么数据准备好,当为SFLP game rotation vector(0X13)时候,为四元数准备完毕。

在这里插入图片描述

之后读取FIFO_DATA_OUT_X_L (79h)到FIFO_DATA_OUT_Z_H (7Eh)共6个字节数据,进行四元数读取。

在这里插入图片描述

  /* Infinite loop *//* USER CODE BEGIN WHILE */while (1){uint16_t num = 0;/* Read watermark flag */lsm6dsv16x_fifo_status_get(&dev_ctx, &fifo_status);if (fifo_status.fifo_th == 1) {num = fifo_status.fifo_level;printf( "-- FIFO num %d \r\n", num);while (num--) {lsm6dsv16x_fifo_out_raw_t f_data;uint8_t *axis;float_t quat[4];float_t gravity_mg[3];float_t gbias_mdps[3];/* Read FIFO sensor value */lsm6dsv16x_fifo_out_raw_get(&dev_ctx, &f_data);switch (f_data.tag) {case LSM6DSV16X_SFLP_GYROSCOPE_BIAS_TAG:axis = &f_data.data[0];gbias_mdps[0] = lsm6dsv16x_from_fs125_to_mdps(axis[0] | (axis[1] << 8));gbias_mdps[1] = lsm6dsv16x_from_fs125_to_mdps(axis[2] | (axis[3] << 8));gbias_mdps[2] = lsm6dsv16x_from_fs125_to_mdps(axis[4] | (axis[5] << 8));printf("GBIAS [mdps]:%4.2f\t%4.2f\t%4.2f\r\n",(double_t)gbias_mdps[0], (double_t)gbias_mdps[1], (double_t)gbias_mdps[2]);break;case LSM6DSV16X_SFLP_GRAVITY_VECTOR_TAG:axis = &f_data.data[0];gravity_mg[0] = lsm6dsv16x_from_sflp_to_mg(axis[0] | (axis[1] << 8));gravity_mg[1] = lsm6dsv16x_from_sflp_to_mg(axis[2] | (axis[3] << 8));gravity_mg[2] = lsm6dsv16x_from_sflp_to_mg(axis[4] | (axis[5] << 8));printf("Gravity [mg]:%4.2f\t%4.2f\t%4.2f\r\n",(double_t)gravity_mg[0], (double_t)gravity_mg[1], (double_t)gravity_mg[2]);break;case LSM6DSV16X_SFLP_GAME_ROTATION_VECTOR_TAG:sflp2q(quat, (uint16_t *)&f_data.data[0]);printf("[%02x %02x %02x %02x %02x %02x] Game Rotation \tX: %2.3f\tY: %2.3f\tZ: %2.3f\tW: %2.3f\r\n",f_data.data[0], f_data.data[1],f_data.data[2],f_data.data[3],f_data.data[4],f_data.data[5],(double_t)quat[0], (double_t)quat[1], (double_t)quat[2], (double_t)quat[3]);break;default:break;}}printf("------ \r\n\r\n");}		/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */

最后转换为姿态角。

  /* USER CODE BEGIN WHILE */while (1){uint16_t num = 0;/* Read watermark flag */lsm6dsv16x_fifo_status_get(&dev_ctx, &fifo_status);if (fifo_status.fifo_th == 1) {num = fifo_status.fifo_level;sprintf((char *)tx_buffer, "-- FIFO num %d \r\n", num);while (num--) {lsm6dsv16x_fifo_out_raw_t f_data;int16_t *axis;float quat[4];float gravity_mg[3];float gbias_mdps[3];/* Read FIFO sensor value */lsm6dsv16x_fifo_out_raw_get(&dev_ctx, &f_data);switch (f_data.tag) {
//        case LSM6DSV16X_SFLP_GYROSCOPE_BIAS_TAG:
//          axis = (int16_t *)&f_data.data[0];
//          gbias_mdps[0] = lsm6dsv16x_from_fs125_to_mdps(axis[0]);
//          gbias_mdps[1] = lsm6dsv16x_from_fs125_to_mdps(axis[1]);
//          gbias_mdps[2] = lsm6dsv16x_from_fs125_to_mdps(axis[2]);
//          printf("GBIAS [mdps]:%4.2f\t%4.2f\t%4.2f\r\n",
//                         (double_t)gbias_mdps[0], (double_t)gbias_mdps[1], (double_t)gbias_mdps[2]);//          break;
//        case LSM6DSV16X_SFLP_GRAVITY_VECTOR_TAG:
//          axis = (int16_t *)&f_data.data[0];
//          gravity_mg[0] = lsm6dsv16x_from_sflp_to_mg(axis[0]);
//          gravity_mg[1] = lsm6dsv16x_from_sflp_to_mg(axis[1]);
//          gravity_mg[2] = lsm6dsv16x_from_sflp_to_mg(axis[2]);
//          printf("Gravity [mg]:%4.2f\t%4.2f\t%4.2f\r\n",
//                         (double_t)gravity_mg[0], (double_t)gravity_mg[1], (double_t)gravity_mg[2]);//          break;case LSM6DSV16X_SFLP_GAME_ROTATION_VECTOR_TAG:sflp2q(quat, (uint16_t *)&f_data.data[0]);
//          printf("Game Rotation \tX: %2.3f\tY: %2.3f\tZ: %2.3f\tW: %2.3f\r\n",
//                  (double_t)quat[0], (double_t)quat[1], (double_t)quat[2], (double_t)quat[3]);float sx=quat[1];  float sy=quat[2];  float sz=quat[0];  float sw=quat[3];if (sw< 0.0f) {sx*=-1.0f;sy*=-1.0f;sz*=-1.0f;sw*=-1.0f;}float sqx = sx * sx;float sqy = sy * sy;float sqz = sz * sz;float euler[3];euler[0] = -atan2f(2.0f* (sy*sw+sx*sz), 1.0f-2.0f*(sqy+sqx));euler[1] = -atan2f(2.0f * (sx*sy+sz*sw),1.0f-2.0f*(sqx+sqz));euler[2] = -asinf(2.0f* (sx*sw-sy*sz));if (euler[0] <0.0f)euler[0] +=2.0f*3.1415926;for(uint8_t i=0; i<3; i++){euler[i] = 57.29578 * (euler[i]);}printf("euler[0]=%f,euler[1]=%f,euler[2]=%f\n",euler[0],euler[1],euler[2]);break;default:break;}}}		/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */

演示

在这里插入图片描述

http://www.dtcms.com/wzjs/343304.html

相关文章:

  • 网站建设明细推广app的单子都在哪里接的
  • 微信网站开发平台今日新闻内容
  • 莆田专业网站建设公司一级消防工程师考试
  • 网页制作工具程seo关键词排名优化怎么收费
  • 国外网站开发现状网上推广平台
  • 微信小程序官网平台入口官网登录产品seo怎么优化
  • 网站建设如何做百度关键词搜索引擎
  • 怎样做国外电子商务网站seo收费标准多少
  • 苏州知名高端网站建设企业长沙网站优化体验
  • 分包合同建设局网站下载2023全民核酸又开始了
  • 深圳坂田网站建设如何写好一篇软文
  • 网站建设服务规划与措施网站权重查询接口
  • 做化妆品网站百度开户返点
  • 湛江 网站建设推广宣传方式有哪些
  • 可以做行程的网站2021小学生新闻摘抄
  • 石家庄网站建设模板服务黑帽seo是什么
  • 昆明网络建站公司seo前线
  • 仙桃网站建设线上推广策略
  • 网站推荐你懂我的意思吧知乎在百度怎么发广告做宣传
  • 什么网站做美式软装设计域名注册要多少钱
  • 网站 js 广告代码大全百度词条官网入口
  • 网站开发jsp需要什么jar包seo系统是什么意思
  • 做公司网站用什么系统百度网站排名规则
  • 做的的网站怎样上传购物网站大全
  • 盘石做的网站免费入驻的卖货平台有哪些
  • 网站如何选择服务器长春百度seo排名
  • wordpress多语言插件:qtranslateseo综合查询 站长工具
  • 镇江百度网站seo百科
  • google网站优化工具湖北seo服务
  • 做网站老板嫌弃太丑谁的锅seo怎么去优化