概述本文将介绍如何使用 lsm6dsv16x 传感器来读取数据。主要步骤包括初始化传感器接口、验证设备id、配置传感器的数据输出率和滤波器,以及通过轮询方式持续读取加速度、角速率和温度数据。读取到的数据会被转换为适当的单位并通过串行通信输出。这个代码是一个很好的起点,用于了解如何操作 lsm6dsv16x 传感器并获取其数据。
最近在弄st和瑞萨ra的课程,需要样片的可以加群申请:615061293 。
视频教学https://www.bilibili.com/video/bv1rc4y1y75j/
样品申请https://www.wjx.top/vm/ohckxjk.aspx#
源码下载https://download.csdn.net/download/qq_24312945/88594487
通信模式对于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_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 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^16=65536。这些值均匀地分布在 -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.2ft%4.2ft%4.2frn,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.2ft%4.2ft%4.2frn,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.2frn, 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.2ft%4.2ft%4.2frn,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.2ft%4.2ft%4.2frn,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.2frn, temperature_degc); } hal_delay(100); /* user code end while */ /* user code begin 3 */ } /* user code end 3 */演示
锂电产业全面进入超级产能过剩时代
不锈钢压力表的安装说明及注意事项
易飞扬推出几款特色扇出型光模块
数字物联网·乡村智慧科创园项目开工奠基仪式
蓝牙技术普及 或将成为智能家庭互联标准
陀螺仪LSM6DSV16X与AI集成(1)----轮询获取陀螺仪数据
详解数字对讲机常规IP系统的应用实例分析
新款智能汽车大灯-为驾驶员提高安全保障
可编程增量编码器磁性技术7大特点
IBM正在为企业推出完全同态加密测试服务
芯片为什么短缺美国
LED亮度的常用计量方法及公式
8种常见的无线形式介绍
Visa 对外展示数字支付方案,融入了生物识别
专业课程很难办?Mini型多功能移动实验室来助战
人工智能已进入第四代赛道,“人工直觉”成主要方向
荷兰商业街引入普渡科技配送迎宾机器人 开辟全新营销和服务模式
巴黎车展开幕 我们值得期待的新车大盘点
华为方舟编译器正式支持C语言,将继续完全开源
为什么IMU中温度传感器输出存在偏差?