三轴加速度计LIS2DW12开发(1)----轮询获取加速度数据

STM32WB55开发.6--FUS更新

  • 概述
  • 视频教学
  • 通信模式
  • 管脚定义
  • IIC通信模式
  • 速率
  • 生成STM32CUBEMX
  • 串口配置
  • IIC配置
  • CS和SA0设置
  • 串口重定向
  • 参考程序
  • 初始换管脚
  • 获取ID
  • 复位操作
  • BDU设置
  • 设置传感器的量程
  • 配置过滤器链
  • 配置电源模式
  • 设置输出数据速率
  • 轮询获取加速度
  • 演示

概述

本文将介绍如何驱动和利用LIS2DW12传感器,实现精确的运动感应功能。
IS2DW12是一款高性能、超低功耗的三轴线性加速度计,属于“femto”系列,利用了成熟的微机械加速度计制造工艺。这个传感器提供可选择的全量程±2g/±4g/±8g/±16g,能够以1.6 Hz至1600 Hz的数据输出率测量加速度。它包含了一个32级的先进先出(FIFO)缓冲区,用于存储数据,以减少主处理器的干预需求。
此外,LIS2DW12具备自测功能,可在最终应用中验证传感器功能,并集成了一个处理运动和加速度检测的内部引擎。这包括自由落体、唤醒、敲击识别、活动/静止监测、静止/运动检测、纵向/横向检测以及6D/4D定向等功能。

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

在这里插入图片描述

视频教学

通信模式

对于LIS2DW12,可以使用SPI或者IIC进行通讯。
最小系统图如下所示。

在这里插入图片描述

在CS管脚为1的时候,为IIC模式。


本文使用的板子原理图如下所示。
在这里插入图片描述

管脚定义

在这里插入图片描述

IIC通信模式

在使用IIC通讯模式的时候,SA0是用来控制IIC的地址位的。
对于IIC的地址,可以通过SDO/SA0引脚修改。SDO/SA0引脚可以用来修改设备地址的最低有效位。如果SDO/SA0引脚连接到电源电压,LSb(最低有效位)为’1’(地址0011001b);否则,如果SDO/SA0引脚连接到地线,LSb的值为’0’(地址0011000b)。

在这里插入图片描述
对应的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/lis2dw12-pid

初始换管脚

由于需要向LIS2DW12_I2C_ADD_H写入以及为IIC模式。
在这里插入图片描述

所以使能CS为高电平,配置为IIC模式。
配置SA0为高电平。

  HAL_GPIO_WritePin(GPIOC, CS_Pin, GPIO_PIN_SET);
  HAL_GPIO_WritePin(GPIOC, SA0_Pin, GPIO_PIN_SET);

获取ID

我们可以向WHO_AM_I (0Fh)获取固定值,判断是否为0x44。
在这里插入图片描述

lis2dw12_device_id_get为获取函数。
在这里插入图片描述

对应的获取ID驱动程序,如下所示。

  /* Wait sensor boot time */
  platform_delay(BOOT_TIME);
  /* Check device ID */
  lis2dw12_device_id_get(&dev_ctx, &whoamI);
	printf("LIS2DW12_ID=0x%x,whoamI=0x%x",LIS2DW12_ID,whoamI);
  if (whoamI != LIS2DW12_ID)
    while (1) {
      /* manage here device not found */
    }

复位操作

可以向CTRL2 (21h)的SOFT_RESET寄存器写入1进行复位。

在这里插入图片描述
lis2dw12_reset_set为重置函数。

在这里插入图片描述

对应的驱动程序,如下所示。

  /* Restore default configuration */
  lis2dw12_reset_set(&dev_ctx, PROPERTY_ENABLE);

  do {
    lis2dw12_reset_get(&dev_ctx, &rst);
  } while (rst);

BDU设置

在很多传感器中,数据通常被存储在输出寄存器中,这些寄存器分为两部分:MSB和LSB。这两部分共同表示一个完整的数据值。例如,在一个加速度计中,MSB和LSB可能共同表示一个加速度的测量值。
连续更新模式(BDU = ‘0’):在默认模式下,输出寄存器的值会持续不断地被更新。这意味着在你读取MSB和LSB的时候,寄存器中的数据可能会因为新的测量数据而更新。这可能导致一个问题:当你读取MSB时,如果寄存器更新了,接下来读取的LSB可能就是新的测量值的一部分,而不是与MSB相对应的值。这样,你得到的就是一个“拼凑”的数据,它可能无法准确代表任何实际的测量时刻。
块数据更新(BDU)模式(BDU = ‘1’):当激活BDU功能时,输出寄存器中的内容不会在读取MSB和LSB之间更新。这就意味着一旦开始读取数据(无论是先读MSB还是LSB),寄存器中的那一组数据就被“锁定”,直到两部分都被读取完毕。这样可以确保你读取的MSB和LSB是同一测量时刻的数据,避免了读取到代表不同采样时刻的数据。
简而言之,BDU位的作用是确保在读取数据时,输出寄存器的内容保持稳定,从而避免读取到拼凑或错误的数据。这对于需要高精度和稳定性的应用尤为重要。
可以向CTRL2 (21h)的BDU寄存器写入1进行开启。

在这里插入图片描述

对应的驱动程序,如下所示。

/* Enable Block Data Update */
  lis2dw12_block_data_update_set(&dev_ctx, PROPERTY_ENABLE);

设置传感器的量程

FS[1:0] - 全量程选择:这两个位用于设置传感器的量程。量程决定了传感器可以测量的最大加速度值。例如,量程可以设置为±2g、±4g、±8g或±16g。这允许用户根据应用的特定需求调整传感器的灵敏度。
在这里插入图片描述

对应的驱动程序,如下所示。

  /* Set full scale */
  lis2dw12_full_scale_set(&dev_ctx, LIS2DW12_2g);

配置过滤器链

lis2dw12_filter_path_set(&dev_ctx, LIS2DW12_LPF_ON_OUT);:设置加速度计输出的过滤器路径。这里选择了输出上的低通滤波器(LPF),用于去除高频噪声。
lis2dw12_filter_bandwidth_set(&dev_ctx, LIS2DW12_ODR_DIV_4);:设置过滤器的带宽。这里的设置是将输出数据率(ODR)除以4,进一步决定了滤波器的截止频率。

配置电源模式

lis2dw12_power_mode_set(&dev_ctx, LIS2DW12_HIGH_PERFORMANCE);:这个调用设置加速度计的电源模式为高性能模式。这通常意味着更高的功耗,但提供更精确的测量。

设置输出数据速率

lis2dw12_data_rate_set(&dev_ctx, LIS2DW12_XL_ODR_25Hz);:设置加速度计的输出数据速率为每秒25次。输出数据速率决定了传感器多久采集一次数据,并影响数据的实时性和功耗。

  /* Enable Block Data Update */
  lis2dw12_block_data_update_set(&dev_ctx, PROPERTY_ENABLE);
  /* Set full scale */
  lis2dw12_full_scale_set(&dev_ctx, LIS2DW12_2g);
  /* Configure filtering chain
   * Accelerometer - filter path / bandwidth
   */
  lis2dw12_filter_path_set(&dev_ctx, LIS2DW12_LPF_ON_OUT);
  lis2dw12_filter_bandwidth_set(&dev_ctx, LIS2DW12_ODR_DIV_4);
  /* Configure power mode */
  lis2dw12_power_mode_set(&dev_ctx, LIS2DW12_HIGH_PERFORMANCE);
  /* Set Output Data Rate */
  lis2dw12_data_rate_set(&dev_ctx, LIS2DW12_XL_ODR_25Hz);

轮询获取加速度

检查新数据是否可用:
lis2dw12_flag_data_ready_get(&dev_ctx, &reg);:这个函数调用检查加速度计是否有新的数据可读。如果有新数据,reg 变量将被设置为非零值。
主要为读取STATUS (27h)的DRDY位。
在这里插入图片描述
如果 reg 是非零的,说明有新的加速度数据可读。
lis2dw12_acceleration_raw_get(&dev_ctx, data_raw_acceleration);:这个函数调用实际读取加速度计的原始数据,并存储在 data_raw_acceleration 数组中。
数据在28h-2Dh中。

在这里插入图片描述

在这里插入图片描述
加速度数据首先以原始格式(通常是整数)读取,然后需要转换为更有意义的单位,如毫重力(mg)。这里的转换函数 lis2dw12_from_fs2_to_mg() 根据加速度计的量程(这里假设为±2g)将原始数据转换为毫重力单位。
acceleration_mg[0] = lis2dw12_from_fs2_to_mg(data_raw_acceleration[0]); 等三行代码分别转换 X、Y、Z 轴的加速度数据。

在这里插入图片描述

● LIS2DW12 加速度计通常会有一个固定的位分辨率,比如 16 位(即输出值是一个 16 位的整数)。这意味着加速度计可以输出的不同值的总数是 2^16=65536。这些值均匀地分布在 -2g 到 +2g 的范围内。
● 因此,这个范围(4g 或者 4000 mg)被分成了 65536 个步长。
● 每个步长的大小是 4000 mg/65536≈0.061 mg/LSB
所以,函数中的乘法 ((float_t)lsb) * 0.061f 是将原始的整数值转换为以毫重力(mg)为单位的加速度值。这个转换对于将加速度计的原始读数转换为实际的物理测量值是必需的。

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {

    uint8_t reg;
    /* Read output only if new value is available */
    lis2dw12_flag_data_ready_get(&dev_ctx, &reg);

    if (reg) {
      /* Read acceleration data */
      memset(data_raw_acceleration, 0x00, 3 * sizeof(int16_t));
      lis2dw12_acceleration_raw_get(&dev_ctx, data_raw_acceleration);
      //acceleration_mg[0] = lis2dw12_from_fs8_lp1_to_mg(data_raw_acceleration[0]);
      //acceleration_mg[1] = lis2dw12_from_fs8_lp1_to_mg(data_raw_acceleration[1]);
      //acceleration_mg[2] = lis2dw12_from_fs8_lp1_to_mg(data_raw_acceleration[2]);
      acceleration_mg[0] = lis2dw12_from_fs2_to_mg(
                             data_raw_acceleration[0]);
      acceleration_mg[1] = lis2dw12_from_fs2_to_mg(
                             data_raw_acceleration[1]);
      acceleration_mg[2] = lis2dw12_from_fs2_to_mg(
                             data_raw_acceleration[2]);
      printf("Acceleration [mg]:X=%4.2f\tY=%4.2f\tZ=%4.2f\r\n",acceleration_mg[0], acceleration_mg[1], acceleration_mg[2]);
    }
HAL_Delay(100);

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */

演示

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/189942.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

乘波前行的问题

1.问题: 考虑两个信号叠加在一起,比如,一个是工频信号50Hz,一个是叠加的高频信号比如有3KHz,简单起见,两个信号都是幅值固定的标准的正弦波,现在我们期望得到那个高频信号,相对工频…

Linux 网络通信

(一)套接字Socket概念 Socket 中文意思是“插座”,在 Linux 环境下,用于表示进程 x 间网络通信的特殊文件 类型。本质为内核借助缓冲区形成的伪文件。 既然是文件,那么理所当然的,我们可以使用文件描述符引用套接字。Linux 系统…

【MATLAB源码-第88期】基于matlab的灰狼优化算法(GWO)的栅格路径规划,输出做短路径图和适应度曲线

操作环境: MATLAB 2022a 1、算法描述 灰狼优化算法(Grey Wolf Optimizer, GWO)是一种模仿灰狼捕食行为的优化算法。灰狼是群居动物,有着严格的社会等级结构。在灰狼群体中,通常有三个等级:首领&#xff…

聊一聊索引覆盖的好处

问:索引覆盖啥意思? 答:若查询的字段在二级索引的叶子节点中,则可直接返回结果,无需回表。这种通过组合索引避免回表的优化技术也称为索引覆盖(Covering Index)。在叶子节点中的包括索引字段和主…

Python之内置函数和模块

学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。各位小伙伴,如果您: 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持,想组团高效学习… 想写博客但无从下手,急需…

4/5G互操作 EPSFB讲解

今天我们来讲一下4/5G之间之间互操作,以及5G的EPSFB是基于什么实现的~ 目录 4/5G互操作 重选 切换 基于覆盖的切换 基于业务的切换 两个面试问题 想要加快4G切换5G的速度,调哪个参数怎么调高效? 想要减慢5G切换4G的速度调哪个参数怎…

嵌入式硬件电路·电平

目录 1. 电平的概念 1.1 高电平 1.2 低电平 2. 电平的使用场景 2.1 高电平使能 2.2 低电平使能 2.3 失能 1. 电平的概念 电平是指电信号电压的大小或高低状态。在数字电子学中,电平有两种状态,高电平和低电平,用来表示二进制中…

Python之基础语法和六大数据类型

学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。各位小伙伴,如果您: 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持,想组团高效学习… 想写博客但无从下手,急需…

C++ 数据结构之-最小栈(MinStack)

最小栈 最小栈(Min Stack)是一个支持常数时间复杂度获取栈中最小元素的特殊栈数据结构。通常,标准的栈数据结构只支持在常数时间内执行入栈(push)和出栈(pop)操作,但无法在常数时间内…

机器学习基础Matplotlib绘图

一、运行环境 学习工具:jupyter-notebookpython版本:311系统:Win11 二、什么是matplotlib? matplotlib是基于python生态开发的一个可视化绘图库,它的出现让python在数据分析及机器学习方面占了重要的一部分&#…

尺度为什么是sigma?

我们先看中值滤波和均值滤波。 以前,我认为是一样的,没有区分过。 他们说,均值滤波有使图像模糊的效果。 中值滤波有使图像去椒盐的效果。为什么不同呢?试了一下,果然不同,然后追踪了一下定义。 12345&…

论文笔记:详解NEUPSL DSI

《Using Domain Knowledge to Guide Dialog Structure Induction via Neural Probabilistic 》 名词解释 Dialog Structure Induction(DSI)是推断给定目标导向对话的潜在对话结构(即一组对话状态及其时间转换)的任务。它是现代对…

Typescript基础面试题 | 02.精选 ts 面试题

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云…

Qt手写ListView

创建视图: QHBoxLayout* pHLay new QHBoxLayout(this);m_pLeftTree new QTreeView(this);m_pLeftTree->setEditTriggers(QAbstractItemView::NoEditTriggers); //设置不可编辑m_pLeftTree->setFixedWidth(300);创建模型和模型项: m_pLeftTree…

STM32 SCF文件

文章目录 1 SCF文件2 SCT分散加载文件3 SCF文件编写 1 SCF文件 keil编译器在链接的时候,是根据分散加载(.scf后缀的文件)来确定程序的加载域和运行域的。 加载域就是程序运行前在flash中具体分区情况执行域就是程序运行后,程序在flash和ram中的分区情况…

【5G PHY】5G SS/PBCH块介绍(四)

博主未授权任何人或组织机构转载博主任何原创文章,感谢各位对原创的支持! 博主链接 本人就职于国际知名终端厂商,负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作,目前牵头6G算力网络技术标准研究。 博客…

leetcode中“辅助栈”类题目和“单调栈”类题目的异同

1 总结 1 栈中元素的特性 2 单调栈存在一次性连续删除多个栈顶的情况,但是普通的栈,一次只pop掉一个栈顶元素 2 LC1209. 删除字符串中的所有相邻重复项 II - 普通辅助栈 class Solution {public String removeDuplicates(String s, int k) {int ns.l…

windows的bat文件(学习笔记)

简介 通过windows的cmd执行的批处理,扩展名可以是.bat或.cmd(类似linux的shell脚本) 所有语句符号不区分大小写 帮助提示信息:命令 /? 1 基本语法 (1) 注释:rem 注释文本不执行 (2) 关闭盘符输出:e…

城市生命线丨桥梁结构健康监测系统的作用

在城市建设当中,有非常多的城市基本建设,建设当中,桥梁作为不可忽视的一环,也需要有很多桥梁建设的智能监测系统,在这个桥梁结构健康监测系统中,桥梁的各个数值都能被监测得到。 WITBEE万宾使用城市生命线智…

MyBatis 操作数据库(入门)

一:MyBatis概念 (1)MyBatis 💗MyBatis是一款优秀的持久层框架,用于简化JDBC的开发 (2)持久层 1.持久层 💜持久层:持久化操作的层,通常指数据访问层(dao),是用来操作数据库的 2.持久层的规范 ①…