用户云卷云舒 发表于 2024-6-13 21:23:17

STM32 SPI驱动读取LSM6DSRTR

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


媒介

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

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

1.配置SPI

注意:通过STM32CUBEMX 来构建代码
https://img-blog.csdnimg.cn/direct/7ed80f564aa94982a5f9c44246c63486.png
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驱动库

https://img-blog.csdnimg.cn/direct/f45dade5ae294ca2b2751c83302af72a.png
案例代码
#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;
static int16_t data_raw_angular_rate;
static int16_t data_raw_temperature;
static float acceleration_mg;
static float angular_rate_mdps;
static uint8_t whoamI, rst;
static uint8_t tx_buffer;

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 =
            lsm6dsr_from_fs2g_to_mg(data_raw_acceleration);
      acceleration_mg =
            lsm6dsr_from_fs2g_to_mg(data_raw_acceleration);
      acceleration_mg =
            lsm6dsr_from_fs2g_to_mg(data_raw_acceleration);

      /* 注意:atan算出来的是弧度值, 然后1弧度 = 180/Π */
      float angle_x = atan(acceleration_mg / sqrt(acceleration_mg * acceleration_mg + acceleration_mg * acceleration_mg)) * 180 / PI;
      float angle_y = atan(acceleration_mg / sqrt(acceleration_mg * acceleration_mg + acceleration_mg * acceleration_mg)) * 180 / PI;
      float angle_z = atan(acceleration_mg / sqrt(acceleration_mg * acceleration_mg + acceleration_mg * acceleration_mg)) * 180 / PI;

      sprintf((char *)tx_buffer,
                "Acceleration :%4.2f\t%4.2f\t%4.2f\r\n",
                acceleration_mg, acceleration_mg, acceleration_mg);
      //这边是计算出来的角度值
      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 =
    //         lsm6dsr_from_fs2000dps_to_mdps(data_raw_angular_rate);
    //   angular_rate_mdps =
    //         lsm6dsr_from_fs2000dps_to_mdps(data_raw_angular_rate);
    //   angular_rate_mdps =
    //         lsm6dsr_from_fs2000dps_to_mdps(data_raw_angular_rate);
    //   sprintf((char *)tx_buffer,
    //             "Angular rate :%4.2f\t%4.2f\t%4.2f\r\n",
    //             angular_rate_mdps, angular_rate_mdps, angular_rate_mdps);
    //   tx_com(tx_buffer, strlen((char const *)tx_buffer));
    // }
    platform_delay(1000);
}

/*
* @briefWrite generic device register (platform dependent)
*
* @paramhandle    customizable argument. In this examples is used in
*                   order to select the correct sensor bus handler.
* @paramreg       register to write
* @parambufp      pointer to data to write in register reg
* @paramlen       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;
}

/*
* @briefRead generic device register (platform dependent)
*
* @paramhandle    customizable argument. In this examples is used in
*                   order to select the correct sensor bus handler.
* @paramreg       register to read
* @parambufp      pointer to buffer that store the data read
* @paramlen       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;
}

/*
* @briefSend buffer to console (platform dependent)
*
* @paramtx_buffer   buffer to transmit
* @paramlen         number of byte to send
*
*/
static void tx_com(uint8_t *tx_buffer, uint16_t len)
{
    HAL_UART_Transmit(&huart1, tx_buffer, len, 1000);
}

/*
* @briefplatform specific delay (platform dependent)
*
* @paramms      delay in ms
*
*/
static void platform_delay(uint32_t ms)
{
    HAL_Delay(ms);
}

/*
* @briefplatform 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.结果

https://img-blog.csdnimg.cn/direct/feecc3e0220742f792c5ad361d34ef1a.png
总结

有什么题目,可以评论区内里提一下,看到都会帮助办理,这个案例只是简单应用,没有涉及复杂的使用过程。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: STM32 SPI驱动读取LSM6DSRTR