姑苏企业建设网站公司,1688网站的特点,优化排名,自建网站多少钱陀螺仪LSM6DSV16X与AI集成.1--轮询获取陀螺仪数据 概述视频教学样品申请通信模式管脚定义IIC通信模式速率生成STM32CUBEMX串口配置IIC配置CS和SA0设置串口重定向参考程序初始换管脚获取ID复位操作BDU设置设置量程和速率配置过滤链轮询读取数据主程序演示 概述
本文将介绍如何使… 陀螺仪LSM6DSV16X与AI集成.1--轮询获取陀螺仪数据 概述视频教学样品申请通信模式管脚定义IIC通信模式速率生成STM32CUBEMX串口配置IIC配置CS和SA0设置串口重定向参考程序初始换管脚获取ID复位操作BDU设置设置量程和速率配置过滤链轮询读取数据主程序演示 概述
本文将介绍如何使用 LSM6DSV16X 传感器来读取数据。主要步骤包括初始化传感器接口、验证设备ID、配置传感器的数据输出率和滤波器以及通过轮询方式持续读取加速度、角速率和温度数据。读取到的数据会被转换为适当的单位并通过串行通信输出。这个代码是一个很好的起点用于了解如何操作 LSM6DSV16X 传感器并获取其数据。
最近在弄ST和瑞萨RA的课程需要样片的可以加群申请615061293 。 视频教学
样品申请
https://www.wjx.top/vm/OhcKxJk.aspx#
通信模式
对于LSM6DSV16X可以使用SPI或者IIC进行通讯。 最小系统图如下所示。
在CS管脚为1的时候为IIC模式
本文使用的板子原理图如下所示。
管脚定义 IIC通信模式
在使用IIC通讯模式的时候SA0是用来控制IIC的地址位的。 对于IIC的地址可以通过SDO/SA0引脚修改。SDO/SA0引脚可以用来修改设备地址的最低有效位。如果SDO/SA0引脚连接到电源电压LSb最低有效位为’1’地址1101011b否则如果SDO/SA0引脚连接到地线LSb的值为’0’地址1101010b。 IIC接口如下所示。 主要使用的管脚为CS、SCL、SDA、SA0。
速率
该模块支持的速度为普通模式(100k)和快速模式(400k)。
生成STM32CUBEMX
用STM32CUBEMX生成例程这里使用MCU为STM32WB55RG。 配置时钟树配置时钟为32M。 串口配置
查看原理图PB6和PB7设置为开发板的串口。 配置串口。 IIC配置 配置IIC为快速模式速度为400k。
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(123123123);lsm6dsv16x_reset_t rst;stmdev_ctx_t dev_ctx;/* Initialize mems driver interface */dev_ctx.write_reg platform_write;dev_ctx.read_reg platform_read;dev_ctx.handle SENSOR_BUS;HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);HAL_GPIO_WritePin(SA0_GPIO_Port, SA0_Pin, GPIO_PIN_RESET);获取ID
可以向WHO_AM_I (0Fh)获取固定值判断是否为0x70。 lsm6dsv16x_device_id_get为获取函数。 对应的获取ID驱动程序,如下所示。 /* Wait sensor boot time */platform_delay(BOOT_TIME);/* Check device ID */lsm6dsv16x_device_id_get(dev_ctx, whoamI);printf(LSM6DSV16X_ID0x%x,whoamI0x%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 Output Data Rate.* Selected data rate have to be equal or greater with respect* with MLC data rate.*/lsm6dsv16x_xl_data_rate_set(dev_ctx, LSM6DSV16X_ODR_AT_7Hz5);lsm6dsv16x_gy_data_rate_set(dev_ctx, LSM6DSV16X_ODR_AT_15Hz);/* Set full scale */lsm6dsv16x_xl_full_scale_set(dev_ctx, LSM6DSV16X_2g);lsm6dsv16x_gy_full_scale_set(dev_ctx, LSM6DSV16X_2000dps);配置过滤链 /* Configure filtering chain */filt_settling_mask.drdy PROPERTY_ENABLE;filt_settling_mask.irq_xl PROPERTY_ENABLE;filt_settling_mask.irq_g PROPERTY_ENABLE;lsm6dsv16x_filt_settling_mask_set(dev_ctx, filt_settling_mask);lsm6dsv16x_filt_gy_lp1_set(dev_ctx, PROPERTY_ENABLE);lsm6dsv16x_filt_gy_lp1_bandwidth_set(dev_ctx, LSM6DSV16X_GY_ULTRA_LIGHT);lsm6dsv16x_filt_xl_lp2_set(dev_ctx, PROPERTY_ENABLE);lsm6dsv16x_filt_xl_lp2_bandwidth_set(dev_ctx, LSM6DSV16X_XL_STRONG);轮询读取数据
进入一个无限循环不断检查是否有新的数据加速度、角速率、温度可用。 对于每种类型的数据加速度、角速率、温度如果有新数据就读取原始数据转换为对应的单位毫克、毫度每秒、摄氏度并通过串行输出打印。
对于数据是否准备好可以访问STATUS_REG (1Eh)进行判断。 /* Read output only if new xl value is available */lsm6dsv16x_flag_data_ready_get(dev_ctx, drdy);对于加速度数据可以通过28-2D进行获取。 加速度数据首先以原始格式通常是整数读取然后需要转换为更有意义的单位如毫重力mg。这里的转换函数 lsm6dsv16x_from_fs2_to_mg() 根据加速度计的量程这里假设为±2g将原始数据转换为毫重力单位。 acceleration_mg[0] lsm6dsv16x_from_fs2_to_mg(data_raw_acceleration[0]); 等三行代码分别转换 X、Y、Z 轴的加速度数据。 ● LSM6DSV16X 加速度计通常会有一个固定的位分辨率比如 16 位即输出值是一个 16 位的整数。这意味着加速度计可以输出的不同值的总数是 2^1665536。这些值均匀地分布在 -2g 到 2g 的范围内。 ● 因此这个范围4g 或者 4000 mg被分成了 65536 个步长。 ● 每个步长的大小是 4000 mg/65536≈0.061 mg/LSB 所以函数中的乘法 ((float_t)lsb) * 0.061f 是将原始的整数值转换为以毫重力mg为单位的加速度值。这个转换对于将加速度计的原始读数转换为实际的物理测量值是必需的。 if (drdy.drdy_xl) {/* Read acceleration field data */memset(data_raw_acceleration, 0x00, 3 * sizeof(int16_t));lsm6dsv16x_acceleration_raw_get(dev_ctx, data_raw_acceleration);acceleration_mg[0] lsm6dsv16x_from_fs2_to_mg(data_raw_acceleration[0]);acceleration_mg[1] lsm6dsv16x_from_fs2_to_mg(data_raw_acceleration[1]);acceleration_mg[2] lsm6dsv16x_from_fs2_to_mg(data_raw_acceleration[2]);printf(Acceleration [mg]:%4.2f\t%4.2f\t%4.2f\r\n,acceleration_mg[0], acceleration_mg[1], acceleration_mg[2]);} 对于角速度数据可以通过22-2D进行获取。 在 LSM6DSV16X 传感器中函数 lsm6dsv16x_from_fs2000_to_mdps(int16_t lsb) 用于将原始的传感器数据以最小可分辨位Least Significant Bit简称 LSB为单位转换为以毫度每秒mdps为单位的角速度值。这里的 70.0f 是一个转换因子用于从原始数据单位转换到实际的物理单位。 具体来说这个转换因子是基于传感器的灵敏度或比例因子。对于 LSM6DSV16X 传感器当设置为 ±2000 dps (度每秒) 的满量程时每个 LSB 代表的角速度值为 70 mdps。 /* Read output only if new xl value is available */if (drdy.drdy_gy) {/* Read angular rate field data */memset(data_raw_angular_rate, 0x00, 3 * sizeof(int16_t));lsm6dsv16x_angular_rate_raw_get(dev_ctx, data_raw_angular_rate);angular_rate_mdps[0] lsm6dsv16x_from_fs2000_to_mdps(data_raw_angular_rate[0]);angular_rate_mdps[1] lsm6dsv16x_from_fs2000_to_mdps(data_raw_angular_rate[1]);angular_rate_mdps[2] lsm6dsv16x_from_fs2000_to_mdps(data_raw_angular_rate[2]);printf(Angular rate [mdps]:%4.2f\t%4.2f\t%4.2f\r\n,angular_rate_mdps[0], angular_rate_mdps[1], angular_rate_mdps[2]);}对于温度数据可以通过20-21进行获取。 if (drdy.drdy_temp) {/* Read temperature data */memset(data_raw_temperature, 0x00, sizeof(int16_t));lsm6dsv16x_temperature_raw_get(dev_ctx, data_raw_temperature);temperature_degC lsm6dsv16x_from_lsb_to_celsius(data_raw_temperature);printf(Temperature [degC]:%6.2f\r\n, temperature_degC);}主程序 /* Infinite loop *//* USER CODE BEGIN WHILE */while (1){lsm6dsv16x_data_ready_t drdy;/* Read output only if new xl value is available */lsm6dsv16x_flag_data_ready_get(dev_ctx, drdy);if (drdy.drdy_xl) {/* Read acceleration field data */memset(data_raw_acceleration, 0x00, 3 * sizeof(int16_t));lsm6dsv16x_acceleration_raw_get(dev_ctx, data_raw_acceleration);acceleration_mg[0] lsm6dsv16x_from_fs2_to_mg(data_raw_acceleration[0]);acceleration_mg[1] lsm6dsv16x_from_fs2_to_mg(data_raw_acceleration[1]);acceleration_mg[2] lsm6dsv16x_from_fs2_to_mg(data_raw_acceleration[2]);printf(Acceleration [mg]:%4.2f\t%4.2f\t%4.2f\r\n,acceleration_mg[0], acceleration_mg[1], acceleration_mg[2]);} /* Read output only if new xl value is available */if (drdy.drdy_gy) {/* Read angular rate field data */memset(data_raw_angular_rate, 0x00, 3 * sizeof(int16_t));lsm6dsv16x_angular_rate_raw_get(dev_ctx, data_raw_angular_rate);angular_rate_mdps[0] lsm6dsv16x_from_fs2000_to_mdps(data_raw_angular_rate[0]);angular_rate_mdps[1] lsm6dsv16x_from_fs2000_to_mdps(data_raw_angular_rate[1]);angular_rate_mdps[2] lsm6dsv16x_from_fs2000_to_mdps(data_raw_angular_rate[2]);printf(Angular rate [mdps]:%4.2f\t%4.2f\t%4.2f\r\n,angular_rate_mdps[0], angular_rate_mdps[1], angular_rate_mdps[2]);}if (drdy.drdy_temp) {/* Read temperature data */memset(data_raw_temperature, 0x00, sizeof(int16_t));lsm6dsv16x_temperature_raw_get(dev_ctx, data_raw_temperature);temperature_degC lsm6dsv16x_from_lsb_to_celsius(data_raw_temperature);printf(Temperature [degC]:%6.2f\r\n, temperature_degC);} HAL_Delay(100);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */演示