STM32 SPI驱动读取LSM6DSRTR

news2024/12/26 15:26:12

提示:通过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.coloradmin.cn/o/1793564.html

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

相关文章

软件测试报告实际案例模板(项目测试文档doc原件)

软件测试报告在软件开发过程中起着至关重要的作用&#xff0c;主要有以下几个主要原因&#xff1a; 1、确保软件质量 2、提供决策支持 3、记录测试过程和结果 4、促进沟通和协作 5、符合标准和法规要求 6、改进测试流程和策略 7、降低风险 软件开发全套资料获取进主页或者本文末…

vue3使用vue3-print-nb打印

打印效果 1.下载插件 Vue2.0版本安装方法 npm install vue-print-nb --saveVue3.0版本安装方法&#xff1a; npm install vue3-print-nb --save2.main.js引入 vue2引入 import Print from vue-print-nb Vue.use(Print)vue3引入 import print from vue3-print-nb // 打印…

如何组织基于Sqlalchemy的项目

在使用 SQLAlchemy 构建项目时&#xff0c;可以遵循一些常用的组织结构和最佳实践&#xff0c;以确保项目清晰、易于维护。下面就是我在构建项目时遇到的一些问题&#xff0c;并做了详细的记录&#xff0c;为了方便大家学习少走一些弯路。 1、问题背景 在基于Sqlalchemy的项目…

超过600万用户的专业且强悍的数据恢复软件

一、简介 1、是一款由苏州开心盒子软件有限公司研发的专业数据恢复软件&#xff0c;旨在帮助用户解决各种数据丢失问题。它支持多种数据恢复场景&#xff0c;包括但不限于误删除文件恢复、回收站清空文件恢复、U盘、硬盘、SD卡等各类存储设备数据恢复。 二、下载 1、下载地址&a…

【漏洞复现】SpringBlade tenant/list SQL 注入漏洞

0x01 产品简介 SpringBlade ,是一个由商业级项目升级优化而来的 SpringCloud 分布式微服务架构、SpingBoot 单体式微服务架构并存的综合型项目。 0x02 漏洞概述 SpringBlade 后台框架 /api/blade-system/tenantist路径存在SQL注入漏洞&#xff0c;攻击者除了可以利用 SQL 注…

【计算机毕业设计】353微信小程序零食批发交易管理系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

如何通过防中毒U盘,实现网络隔离下高密文件传输的安全性?

随着网络安全和数据安全的重视程度增加&#xff0c;越来越多的企业在网络建设时进行了网络隔离&#xff0c;通过网闸、防火墙、VLAN隔离等方式&#xff0c;隔离成内外网&#xff0c;甚至更多细分的网络。但原有的文件和数据传输需求&#xff0c;并不会因为网络的隔离而消失&…

Java大厂面试题第2季

一、本课程前提要求和说明 面试题1&#xff1a; 面试题2&#xff1a; 面试题3&#xff1a; 面试题4&#xff1a; 面试题5&#xff1a; 高频最多的常见笔试面试题目 ArrayList HashMap 底层是什么东东 JVM/GC 多线程与高并发 java集合类

1808java教材交易管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java教材交易管理系统 是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助采用了java设计&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统采用web模式&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&…

买卖股票的各种最佳时机问题

买卖股票的最佳时机 分析 根据题意可知&#xff0c;我们只需要找出来一个最小价格的股票和一个最大价格的股票&#xff0c;并且最小价格的股票出现在最大价格的股票之前。 如果尝试使用暴力解法&#xff0c;时间复杂度为O(N^2)&#xff0c;对于题目中给的长度&#xff0c;显然…

[数据集][目标检测]电力工地场景下的人头检测数据集VOC+YOLO格式7035张1类别

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

(打印表格)编写程序,显示以下表格:

public class HelloWorld {public static void main(String []args) {System.out.println("a a^2 a^3");int i;for(i0;i<4;i){int j1;System.out.println(j j*j j*j*j);j;}} } 运行结果&#xff1a;

java框架树结构实现(带层级、编码、排序)

1、需求 实现一个影像资料库的功能&#xff0c;用树结构对资料进行分类 2、数据结构 通过id、pid表示父子关系 通过code表示层级关系 通过layer表示层级 通过sort进行排序 3、实体类 package org.jeecg.modules.image.entity;import com.baomidou.mybatisplus.annotation…

SQLAlchemy 模型中数据的错误表示

1. 问题背景 在使用 SQLAlchemy 0.6.0 版本&#xff08;也曾尝试使用 0.6.4 版本&#xff09;的 Pylons 应用程序中遇到了一个 SQLAlchemy ORM 问题。该问题出现在使用 psycopg2 作为数据库驱动程序、连接至 Postgresql 8.2 数据库的环境中。定义了一个 User 模型对象&#xf…

Java17 --- Mabbitmq之安装测试

目录 一、拉取运行镜像 1.1、拉取镜像环境 1.2、运行镜像 二、工作模式 2.1、消息的发送者 2.2、消息的接收者 2.3、生产队列模式 2.3.1、消息的发送者 2.3.2、消息的接收者 2.4、发布订阅模式 2.4.1、消息的发送者 2.4.2、消息的接收者 2.5、路由模式 2.5.…

记一次 .NET某工控视觉自动化系统 卡死分析

一&#xff1a;背景 1. 讲故事 今天分享的dump是训练营里一位学员的&#xff0c;从一个啥也不会到现在分析的有模有样&#xff0c;真的是看他成长起来的&#xff0c;调试技术学会了就是真真实实自己的&#xff0c;话不多说&#xff0c;上windbg说话。 二&#xff1a;WinDbg …

如何从官网下载 mysql 二进制安装包

一.下载二进行包 1. 官网网址: https://www.mysql.com/ 如图所示进入官网 2. 点击 DOWNLOADS ,进入如下图 在该页面找到 MySQL Community (GPL) Downloads 点进去 如上图页面&#xff0c;找到 MySQL Community Server 在点进去 下载 linux 通用版 点击最下面 Compressed …

你真的了解SQL语句的执行过程?

SQL查询语句的执行过程 连接器 连接器会对用户身份和访问权限进行校验。会先连接到数据库上&#xff0c;通过连接器跟客户端建立连接、获取权限、维持和管理连接。在建立连接之后&#xff0c;不会立即执行语句&#xff0c;而是将SQL语句同时传给分析器和缓存。 缓存 如果能在…

系统架构设计师【第14章】: 云原生架构设计理论与实践 (核心总结)

文章目录 14.1 云原生架构产生背景14.2 云原生架构内涵14.2.1 云原生架构定义14.2.2 云原生架构原则14.2.3 主要架构模式14.2.4 典型的云原生架构反模式 14.3 云原生架构相关技术14.3.1 容器技术14.3.2 云原生微服务14.3.3 无服务器技术14.3.4 服务网格 14.4 云原生…

linux动态调试 dev_dbg

动态调试使用方法 打开内核动态调试开关&#xff0c;make menuconfig选中CONFIG_DYNAMIC_DEBUG以及CONFIG_DEBUG_FS Linux启动后&#xff0c;使用命令行挂载上dbgfs 1. mkdir /mnt/dbg 2. mount -t debugfs none /mnt/dbg 1.控制某个文件所有dev_dbg()&#xff0c; echo -n &q…