STM32 SPI驱动读取LSM6DSRTR

提示:通过SPI驱动读取传感器数据

文章目录

  • 前言
  • 一、LSM6DSRTR
  • 二、配置步骤
    • 1.配置SPI
    • 2.引入 LSM驱动库
    • 3.结果
  • 总结


前言

制作一个倾角传感器,通过SPI读取LSM6DSRTR的加速度数据转换为角度,不用IIC的原因是考虑IIC通讯的协议过于繁琐,且会影响后续的发包速率。


一、LSM6DSRTR

六轴传感器,最好用ST的芯片来读取,主要是ST在这块已经提供好驱动了,其它也行,都一样简单。其次就是,你需要配置好SPI,这个很重要,不然很容易读不出来。

二、配置步骤

1.配置SPI

注意:通过STM32CUBEMX 来构建代码

static void MX_SPI1_Init(void)
{hspi1.Instance = SPI1;hspi1.Init.Mode = SPI_MODE_MASTER;hspi1.Init.Direction = SPI_DIRECTION_2LINES;hspi1.Init.DataSize = SPI_DATASIZE_8BIT;hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;hspi1.Init.NSS = SPI_NSS_SOFT;hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;hspi1.Init.TIMode = SPI_TIMODE_DISABLE;hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;hspi1.Init.CRCPolynomial = 7;if (HAL_SPI_Init(&hspi1) != HAL_OK){Error_Handler();}/* USER CODE BEGIN SPI1_Init 2 *//* USER CODE END SPI1_Init 2 */
}

2.引入 LSM驱动库

在这里插入图片描述
案例代码

#include <string.h>
#include <stdio.h>
#include "lsm6dsr_reg.h"
#include "stm32l0xx_hal.h"
#include "main.h"#define CS_Pin GPIO_PIN_4
#define CS_GPIO_Port GPIOA
#define LED_Pin GPIO_PIN_12
#define LED_GPIO_Port GPIOA
#define BOOT_TIME 10 // ms
#define PI 3.1415926
extern SPI_HandleTypeDef hspi1;extern UART_HandleTypeDef huart1;
static stmdev_ctx_t dev_ctx;/* Private variables ---------------------------------------------------------*/
static int16_t data_raw_acceleration[3];
static int16_t data_raw_angular_rate[3];
static int16_t data_raw_temperature;
static float acceleration_mg[3];
static float angular_rate_mdps[3];
static uint8_t whoamI, rst;
static uint8_t tx_buffer[1000];static int32_t platform_write(void *handle, uint8_t reg, const uint8_t *bufp,uint16_t len);
static int32_t platform_read(void *handle, uint8_t reg, uint8_t *bufp,uint16_t len);
static void tx_com(uint8_t *tx_buffer, uint16_t len);
static void platform_delay(uint32_t ms);/* Main Example --------------------------------------------------------------*/
//在主函数里面调用这个接口就行
void lsm6dsr_read_angle_data_polling(void)
{uint8_t reg;/* Read output only if new xl value is available */lsm6dsr_xl_flag_data_ready_get(&dev_ctx, &reg);if (reg){/* Read acceleration field data */memset(data_raw_acceleration, 0x00, 3 * sizeof(int16_t));lsm6dsr_acceleration_raw_get(&dev_ctx, data_raw_acceleration);acceleration_mg[0] =lsm6dsr_from_fs2g_to_mg(data_raw_acceleration[0]);acceleration_mg[1] =lsm6dsr_from_fs2g_to_mg(data_raw_acceleration[1]);acceleration_mg[2] =lsm6dsr_from_fs2g_to_mg(data_raw_acceleration[2]);/* 注意:atan算出来的是弧度值, 然后1弧度 = 180/Π */float angle_x = atan(acceleration_mg[0] / sqrt(acceleration_mg[2] * acceleration_mg[2] + acceleration_mg[1] * acceleration_mg[1])) * 180 / PI;float angle_y = atan(acceleration_mg[1] / sqrt(acceleration_mg[0] * acceleration_mg[0] + acceleration_mg[2] * acceleration_mg[2])) * 180 / PI;float angle_z = atan(acceleration_mg[2] / sqrt(acceleration_mg[0] * acceleration_mg[0] + acceleration_mg[1] * acceleration_mg[1])) * 180 / PI;sprintf((char *)tx_buffer,"Acceleration [mg]:%4.2f\t%4.2f\t%4.2f\r\n",acceleration_mg[0], acceleration_mg[1], acceleration_mg[2]);//这边是计算出来的角度值sprintf((char *)tx_buffer,"Angle :x %4.2f\t y %4.2f\t z %4.2f\r\n",angle_x, angle_y, angle_z);tx_com(tx_buffer, strlen((char const *)tx_buffer));}// lsm6dsr_gy_flag_data_ready_get(&dev_ctx, &reg);// if (reg)// {//     /* Read angular rate field data *///     memset(data_raw_angular_rate, 0x00, 3 * sizeof(int16_t));//     lsm6dsr_angular_rate_raw_get(&dev_ctx, data_raw_angular_rate);//     angular_rate_mdps[0] =//         lsm6dsr_from_fs2000dps_to_mdps(data_raw_angular_rate[0]);//     angular_rate_mdps[1] =//         lsm6dsr_from_fs2000dps_to_mdps(data_raw_angular_rate[1]);//     angular_rate_mdps[2] =//         lsm6dsr_from_fs2000dps_to_mdps(data_raw_angular_rate[2]);//     sprintf((char *)tx_buffer,//             "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]);//     tx_com(tx_buffer, strlen((char const *)tx_buffer));// }platform_delay(1000);
}/** @brief  Write generic device register (platform dependent)** @param  handle    customizable argument. In this examples is used in*                   order to select the correct sensor bus handler.* @param  reg       register to write* @param  bufp      pointer to data to write in register reg* @param  len       number of consecutive register to write**/
static int32_t platform_write(void *handle, uint8_t reg, const uint8_t *bufp,uint16_t len)
{HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET);HAL_SPI_Transmit(handle, &reg, 1, 1000);HAL_SPI_Transmit(handle, (uint8_t *)bufp, len, 1000);HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);return 0;
}/** @brief  Read generic device register (platform dependent)** @param  handle    customizable argument. In this examples is used in*                   order to select the correct sensor bus handler.* @param  reg       register to read* @param  bufp      pointer to buffer that store the data read* @param  len       number of consecutive register to read**/
static int32_t platform_read(void *handle, uint8_t reg, uint8_t *bufp,uint16_t len)
{reg |= 0x80;HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET);HAL_SPI_Transmit(handle, &reg, 1, 1000);HAL_SPI_Receive(handle, bufp, len, 1000);HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);return 0;
}/** @brief  Send buffer to console (platform dependent)** @param  tx_buffer     buffer to transmit* @param  len           number of byte to send**/
static void tx_com(uint8_t *tx_buffer, uint16_t len)
{HAL_UART_Transmit(&huart1, tx_buffer, len, 1000);
}/** @brief  platform specific delay (platform dependent)** @param  ms        delay in ms**/
static void platform_delay(uint32_t ms)
{HAL_Delay(ms);
}/** @brief  platform specific initialization (platform dependent)*/
void platform_init(void)
{/* Initialize mems driver interface */dev_ctx.write_reg = platform_write;dev_ctx.read_reg = platform_read;dev_ctx.handle = &hspi1;/* Wait sensor boot time */platform_delay(BOOT_TIME);/* Check device ID */while (1){// 考虑如何喂狗lsm6dsr_device_id_get(&dev_ctx, &whoamI);if (whoamI == LSM6DSR_ID){sprintf((char *)tx_buffer,"Read id :0x%2x\r\n",whoamI);tx_com(tx_buffer, strlen((char const *)tx_buffer));break;}platform_delay(BOOT_TIME);}/* Restore default configuration */lsm6dsr_reset_set(&dev_ctx, PROPERTY_ENABLE);do{lsm6dsr_reset_get(&dev_ctx, &rst);} while (rst);/* Disable I3C interface */lsm6dsr_i3c_disable_set(&dev_ctx, LSM6DSR_I3C_DISABLE);/* Enable Block Data Update */lsm6dsr_block_data_update_set(&dev_ctx, PROPERTY_ENABLE);/* Set Output Data Rate */lsm6dsr_xl_data_rate_set(&dev_ctx, LSM6DSR_XL_ODR_12Hz5);lsm6dsr_gy_data_rate_set(&dev_ctx, LSM6DSR_GY_ODR_12Hz5);/* Set full scale */lsm6dsr_xl_full_scale_set(&dev_ctx, LSM6DSR_2g);lsm6dsr_gy_full_scale_set(&dev_ctx, LSM6DSR_2000dps);/* Configure filtering chain(No aux interface)* Accelerometer - LPF1 + LPF2 path*/lsm6dsr_xl_hp_path_on_out_set(&dev_ctx, LSM6DSR_LP_ODR_DIV_100);lsm6dsr_xl_filter_lp2_set(&dev_ctx, PROPERTY_ENABLE);
}

3.结果

在这里插入图片描述


总结

有什么问题,可以评论区里面提一下,看到都会帮忙解决,这个案例只是简单应用,没有涉及复杂的使用过程。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springCloudAlibaba之服务熔断组件---sentinel

sentinel组件学习 sentinel学习sentinel容错机制使用代码方式进行QPS流控-流控规则初体验使用SentinelResource注解进行流控使用注解方式 sentinel学习 服务雪崩 服务雪崩效应&#xff1a;因服务提供者的不可用导致服务调用者的不可用&#xff0c;并将不可用逐渐放大的过程。 …

心链10----查询修改加入队伍业务实现

心链 — 伙伴匹配系统 接口设计 查询队伍列表 :::success 分页展示队伍列表&#xff0c;根据名称、最大人数等搜索队伍 P0&#xff0c;信息流中不展示已过期的队伍 从请求参数中取出队伍名称等查询条件&#xff0c;如果存在则作为查询条件不展示已过期的队伍&#xff08;根…

docker实战命令大全

文章目录 1 环境准备1.1 移除旧版本Docker1.2安装工具包1.3配置docker yum源 2 安装最新docker2.1 设置开机自启docker2.2配置加速器 3 实操-镜像3.1搜索镜像3.2下载镜像3.3查看镜像3.4 删除镜像 4 实操-容器4.1运行nginx容器4.2 查看容器4.3启动容器4.5关闭容器4.6查看容器日志…

功能强大的开源数据中台系统 DataCap 2024.03.5 发布

推荐一套基于 SpringBoot 开发的简单、易用的开源权限管理平台&#xff0c;建议下载使用: https://github.com/devlive-community/authx 推荐一套为 Java 开发人员提供方便易用的 SDK 来与目前提供服务的的 Open AI 进行交互组件&#xff1a;https://github.com/devlive-commun…

2个不同node版本的前端项目,用到的一个node版本管理工具nvm,可一键切换node版本

背景&#xff1a; 对于需要在电脑运行2个不同的前端项目&#xff0c;但是使用的node版本不同&#xff0c;为了快捷切换和管理node版本&#xff0c;所以需要用到一个非常方便的工具&#xff0c;那就是下边的nvm&#xff0c;一个命令就可以非常方便的切换你想要的node。 1、下载…

分布式光纤测温DTS与光纤光栅FBG解调仪有什么区别?

分布式光纤测温DTS和光纤光栅FBG解调仪之间存在本质区别。分布式光纤测温DTS是一种完全分布式的温度监测技术&#xff0c;意味着光纤的整个长度都充当传感器&#xff0c;可以感知任何位置的温度变化。然而&#xff0c;由于空间分辨率的限制&#xff0c;目前国内外的大多数技术只…

Three.js中的Raycasting技术:实现3D场景交互事件的Raycaster详解

前言 在Web开发中&#xff0c;Three.js是一个极为强大的库&#xff0c;它让开发者能够轻松地在浏览器中创建和展示3D图形。随着3D技术在网页设计、游戏开发、数据可视化等领域的广泛应用&#xff0c;用户与3D场景的交互变得日益重要。而要实现这种交互&#xff0c;一个核心的技…

探索地产营销管理系统业务架构的设计与应用

随着城市化进程的加速和人们对居住环境需求的不断提升&#xff0c;地产行业正迎来前所未有的发展机遇和挑战。在这个背景下&#xff0c;地产营销管理系统作为地产开发企业营销管理的重要工具&#xff0c;扮演着至关重要的角色。本文将深入探讨地产营销管理系统业务架构的设计与…

java中的面试高频问题----2

一、进程、线程、协程有什么区别&#xff1f; 1.进程&#xff1a;进程是操作系统中独立运行的程序实例&#xff0c;每个进程都有自己的内存空间和系统资源&#xff1b;进程之间相互独立&#xff0c;每个进程有自己的内存地址空间&#xff0c;一个进程无法直接访问另一个进程的…

H3C运维工程师面经

H3C运维工程师面经 1、常用linux命令:top的作用1.1.系统监控与性能分析:1.2.进程管理:1.3.资源使用统计:1.4.自定义视图与交互操作:2、接触过的linux系统、小版本是多少?2.1CentOS的版本CentOS 8系列:CentOS 7系列:CentOS 6系列:2.2Ubuntu版本Ubuntu LTS版本:Ubuntu非…

手机怎么压缩图片?通过三种压缩操作

手机怎么压缩图片&#xff1f;在智能手机日益普及的今天&#xff0c;拍照分享已成为日常生活的一部分。然而&#xff0c;高质量的照片往往占用较大的存储空间&#xff0c;且在网络上传输时速度较慢。那么&#xff0c;如何在手机上压缩图片呢&#xff1f;本文将介绍三种实用的手…

文件无法在当前环境下执行在 x86_64 系统上运行 ARM 可执行文件

目录 遇到的问题是由于"..."文件无法在当前环境下执行。这个错误通常是因为二进制文件的格式不兼容&#xff0c;可能是因为它是为不同的架构编译的。例如&#xff0c;如果二进制文件是为 x86 架构编译的&#xff0c;但你在 ARM 设备上尝试运行它&#xff0c;就会出现…

Oracle创建索引的LOGGING | NOLOGGING区别

在Oracle中&#xff0c;创建索引时的LOGGING和NOLOGGING选项主要影响索引创建过程中产生的重做日志&#xff08;redo log&#xff09;的数量。这两个选项对于性能和数据恢复能力有着显著的影响。以下是关于这两个选项的详细解释和区别&#xff1a; LOGGING 定义&#xff1a;当…

[数据集][目标检测]道路圆石墩检测数据集VOC+YOLO格式461张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;462 标注数量(xml文件个数)&#xff1a;462 标注数量(txt文件个数)&#xff1a;462 标注类别…

Python怎么做单元测试

在Python中&#xff0c;最常用的单元测试框架是unittest。以下是如何使用unittest进行单元测试的步骤&#xff1a; 导入unittest模块&#xff1a; 首先&#xff0c;你需要导入unittest模块。 import unittest创建测试类&#xff1a; 你需要创建一个继承自unittest.TestCase的类…

运放应用2 - 同相放大电路

1. 前置知识 同相放大电路存在 负反馈电路 &#xff0c;工作在线性区&#xff0c;可以利用 虚短 概念来分析电路。 注&#xff1a;运放的 虚断 特性是一直存在的&#xff0c;虚短 特性则需要运放工作在 线性区 有关运放的基础知识&#xff0c;可以参考我的另外一篇文章&#x…

LeetCode题练习与总结:杨辉三角--118

一、题目描述 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 示例 1: 输入: numRows 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]示例 2: 输入: numRows 1 输出: [[1…

【解决方案】前端React 、Vue工程如何开启GZIP压缩

在前端工程中&#xff0c;React 和 Vue 项目通常通过构建工具&#xff08;如Webpack&#xff09;进行打包&#xff0c;而服务器端配置则负责实际的GZIP压缩。以下是如何在React和Vue项目中开启GZIP压缩的一般步骤&#xff1a; React项目 使用Webpack构建&#xff1a; 如果你的…

单元测试之CppTest测试框架

目录 1 背景2 设计3 实现4 使用4.1 主函数4.2 测试用例4.2.1 定义4.2.2 实现 4.3 运行 1 背景 前面文章CppTest实战演示中讲述如何使用CppTest库。其主函数如下&#xff1a; int main(int argc, char *argv[]) {Test::Suite mainSuite;Test::TextOutput output(Test::TextOut…

Linux系统安全(用户、密码、grub引导密码、增加终端)

目录 系统安全 用户安全 密码安全 PAM认证 命令的历史 用户切换 命令的执行权限 grub引导密码 增加终端 系统安全 用户安全 命令 说明 chattr i /etc/passwd chattr&#xff1a;为文件添加特殊权限 i&#xff1a;指定文件设为不可修改&#xff0c;只有root用户能为…