LIS2DW12驱动,功耗,数据可视化

LIS2DW12,LIS2DH,LIS3DH驱动基本一样。

一、首先获取官方驱动文件,不要自己写寄存器,浪费时间还容易出错。

地址:STMems_Standard_C_drivers/lis2dw12_STdC at master · STMicroelectronics/STMems_Standard_C_drivers · GitHub

官方提供了各个功能的例程,然后移植你自己需要的。

二、LIS2DW12的常用功能,

1.轮询模式

2.fifo+中断模式

3.唤醒模式

三、具体代码配置

1.轮询模式

复制代码
//轮询模式
uint8_t lis2dw12_config_polling(void)
{
  /* Enable Block Data Update. */ 
  lis2dw12_block_data_update_set(&dev_ctx, PROPERTY_ENABLE);
  lis2dw12_full_scale_set(&dev_ctx, LIS2DW12_2g);//量程
  //platform_delay(1);
  lis2dw12_filter_path_set(&dev_ctx, LIS2DW12_LPF_ON_OUT);//低通滤波
  //platform_delay(1);
  lis2dw12_filter_bandwidth_set(&dev_ctx, LIS2DW12_ODR_DIV_4);//带宽
  //platform_delay(1);LIS2DW12_HIGH_PERFORMANCE  、 LIS2DW12_CONT_LOW_PWR_LOW_NOISE_4
  lis2dw12_power_mode_set(&dev_ctx, LIS2DW12_HIGH_PERFORMANCE);//高性能
  //platform_delay(1);
  lis2dw12_data_rate_set(&dev_ctx, LIS2DW12_XL_ODR_25Hz);//频率

  dev_ctx.mdelay(5);

  return 1;
}

//轮询获取数据XYZ
uint8_t lis2dw12_polling_get_data(float *data)
{
    uint8_t ret = 0;
    uint8_t reg;

    //printf("2\r\n");

    lis2dw12_flag_data_ready_get(&dev_ctx, &reg);
    if (reg)
    {
        //printf("2\r\n");
        /* Read accelerometer data */
        memset(data_raw_acceleration, 0x00, 3 * sizeof(int16_t));
        lis2dw12_acceleration_raw_get(&dev_ctx, data_raw_acceleration);
        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]);

        memcpy(data, acceleration_mg, 12);

        //printf(" x :%.2f, y :%.2f, z :%.2f\r\n",acceleration_mg[0],acceleration_mg[1],acceleration_mg[2]);
        //printf("x %.2f,y %.2f,z %.2f\r\n" ,data[0],data[1],data[2]);
        ret = 1;
    }
    return ret;
}

2.fifo模式,FIFO分为好几种模式,常用的是新数据会覆盖旧数据,还有就是新数据不会覆盖旧数据,要读取完旧数据才会继续采样最新的数据,配置具体看数据手册的5.3

复制代码
//fifo新数据覆盖旧数据
uint8_t lis2dw12_config_fifo_stream(void)
{
    dev_ctx.mdelay(2);

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

    lis2dw12_full_scale_set(&dev_ctx, LIS2DW12_2g);

    lis2dw12_filter_path_set(&dev_ctx, LIS2DW12_LPF_ON_OUT);

    lis2dw12_filter_bandwidth_set(&dev_ctx, LIS2DW12_ODR_DIV_2);

    /* Configure FIFO */
    lis2dw12_fifo_watermark_set(&dev_ctx, 30);

    lis2dw12_fifo_mode_set(&dev_ctx, LIS2DW12_STREAM_MODE);

    /* Configure power mode */
    lis2dw12_power_mode_set(&dev_ctx, LIS2DW12_HIGH_PERFORMANCE);

    // lis2dw12_power_mode_set(&dev_ctx, LIS2DW12_CONT_LOW_PWR_LOW_NOISE_12bit);
    /* Set Output Data Rate */
    lis2dw12_data_rate_set(&dev_ctx, LIS2DW12_XL_ODR_12Hz5);

    dev_ctx.mdelay(2);

    return 1;
}
//fifo 新数据不覆盖旧数据,需要读取才能继续更新 打开INT1使能中断
uint8_t lis2dw12_config_fifo_int1(void)
{
    dev_ctx.mdelay(2);

    /* Enable Block Data Update */
    lis2dw12_block_data_update_set(&dev_ctx, PROPERTY_ENABLE);
    // platform_delay(1);
    lis2dw12_full_scale_set(&dev_ctx, LIS2DW12_2g);
    // platform_delay(1);
    lis2dw12_filter_path_set(&dev_ctx, LIS2DW12_LPF_ON_OUT); // 低通
    // platform_delay(1);
    lis2dw12_filter_bandwidth_set(&dev_ctx, LIS2DW12_ODR_DIV_2); // 带通

    /* Configure power mode */
    lis2dw12_power_mode_set(&dev_ctx, LIS2DW12_HIGH_PERFORMANCE); // 禁止低噪声高性能模式

    lis2dw12_data_rate_set(&dev_ctx, LIS2DW12_XL_ODR_12Hz5);

    lis2dw12_fifo_watermark_set(&dev_ctx, 30);            // fifo个数
    lis2dw12_fifo_mode_set(&dev_ctx, LIS2DW12_FIFO_MODE); // FIFO新数据不会覆盖旧数据模式,需要读取后才继续更新

    // #if LIS2DW12_INT1_ENABLE
    lis2dw12_pin_int1_route_get(&dev_ctx, &int_route.ctrl4_int1_pad_ctrl);
    int_route.ctrl4_int1_pad_ctrl.int1_fth = PROPERTY_ENABLE; // 阈值溢出中断
    lis2dw12_pin_int1_route_set(&dev_ctx, &int_route.ctrl4_int1_pad_ctrl);

    // #endif

    dev_ctx.mdelay(2);

    return 1;
}

//获取FIFO数据
uint8_t lis2dw12_polling_get_fifo(float *data,uint8_t *fifo_len)
{
    uint8_t val, i;

    lis2dw12_fifo_wtm_flag_get(&dev_ctx, &val);

    if (val) 
    {
        lis2dw12_fifo_data_level_get(&dev_ctx, &val);

        *fifo_len = val;
       
        //printf("fifo=%d,\r\n",*fifo);
        for (i = 0; i < val; i++) {
            /* 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_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]);

            data[i*3+0]  = acceleration_mg[0];                      
            data[i*3+1]  = acceleration_mg[1]; 
            data[i*3+2]  = acceleration_mg[2]; 
        }
        //memcpy(acc,fifo_acc,12*val);

    }
    else
    {
        return 0;
    }

    return 1;
}

3.唤醒模式和单机模式也是常用的,需要配合中断使用。

复制代码
//单击模式
uint8_t lis2dw12_config_tap_single(void)
{

    dev_ctx.mdelay(2);
    /* Set full scale */
    lis2dw12_full_scale_set(&dev_ctx, LIS2DW12_2g);
    /* Configure power mode */
    lis2dw12_power_mode_set(&dev_ctx,
                            LIS2DW12_CONT_LOW_PWR_LOW_NOISE_12bit);
    /* Set Output Data Rate */
    lis2dw12_data_rate_set(&dev_ctx, LIS2DW12_XL_ODR_400Hz);
    /* Enable Tap detection on X, Y, Z */
    lis2dw12_tap_detection_on_z_set(&dev_ctx, PROPERTY_ENABLE);
    lis2dw12_tap_detection_on_y_set(&dev_ctx, PROPERTY_ENABLE);
    lis2dw12_tap_detection_on_x_set(&dev_ctx, PROPERTY_ENABLE);
    /* Set Tap threshold on all axis */
    lis2dw12_tap_threshold_x_set(&dev_ctx, 1);//阈值,时候固定安装
    lis2dw12_tap_threshold_y_set(&dev_ctx, 1);
    lis2dw12_tap_threshold_z_set(&dev_ctx, 1);
    /* Configure Single Tap parameter */
    lis2dw12_tap_quiet_set(&dev_ctx, 1);
    lis2dw12_tap_shock_set(&dev_ctx, 2);
    /* Enable Single Tap detection only */
    lis2dw12_tap_mode_set(&dev_ctx, LIS2DW12_ONLY_SINGLE);
    /* Enable single tap detection interrupt */

    //int1中断
    lis2dw12_pin_int1_route_get(&dev_ctx, &int_route.ctrl4_int1_pad_ctrl);
    int_route.ctrl4_int1_pad_ctrl.int1_single_tap = PROPERTY_ENABLE;//单击中断源
    lis2dw12_pin_int1_route_set(&dev_ctx, &int_route.ctrl4_int1_pad_ctrl);

    dev_ctx.mdelay(2);

    return 1;
}

//唤醒模式
uint8_t lis2dw12_config_wake_up(void)
{
    dev_ctx.mdelay(2);

    /* Set full scale */
    lis2dw12_full_scale_set(&dev_ctx, LIS2DW12_2g);
    /* Configure power mode */
    lis2dw12_power_mode_set(&dev_ctx,
                            LIS2DW12_CONT_LOW_PWR_LOW_NOISE_12bit);
    /* Set Output Data Rate */
    lis2dw12_data_rate_set(&dev_ctx, LIS2DW12_XL_ODR_100Hz);
    /* Apply high-pass digital filter on Wake-Up function */
    lis2dw12_filter_path_set(&dev_ctx, LIS2DW12_LPF_ON_OUT);
    /* Apply high-pass digital filter on Wake-Up function
     * Duration time is set to zero so Wake-Up interrupt signal
     * is generated for each X,Y,Z filtered data exceeding the
     * configured threshold
     */
    lis2dw12_wkup_dur_set(&dev_ctx, 0);
    /* Set wake-up threshold
     * Set Wake-Up threshold: 1 LSb corresponds to FS_XL/2^6
     */
    lis2dw12_wkup_threshold_set(&dev_ctx, 1); // 灵敏度


    lis2dw12_pin_int1_route_get(&dev_ctx, &int_route.ctrl4_int1_pad_ctrl);
    int_route.ctrl4_int1_pad_ctrl.int1_wu = PROPERTY_ENABLE; // 唤醒源
    lis2dw12_pin_int1_route_set(&dev_ctx, &int_route.ctrl4_int1_pad_ctrl);

    dev_ctx.mdelay(2);

    return 1;
}

驱动代码基本就是这样子,更多功能要看数据手册,顺便说一下IIC驱动和功耗问题。

IIC驱动,我使用的是硬件IIC,驱动文件的lis2dw12.c里面已经封装了读写函数,只需要把自己IIC的驱动替换就上去好了。

复制代码
#ifdef LIS2DW12DRIVE_MODE_I2C_ENABLE
#if CONFIG_I2C_HARD
#include "./py_iic/py_i2c_hard.h"

#else
#include "./py_iic/py_iic.h"
#endif

#define I2Cx_SLAVE_ADDRESS  (0x19 << 1)
#define I2Cx_CLOCK  10000

#endif

//写数据
static int32_t platform_write(void *handle, uint8_t reg, const uint8_t *bufp,uint16_t len)
{
    if (len > 1){
        reg = reg | 0x80;
    }
#if CONFIG_I2C_HARD
    return py_i2c_hard_write_buff(I2Cx_SLAVE_ADDRESS,reg,bufp,len,1);
#endif    
#if CONFIG_I2C_SOFT
    return i2c_sotf_write_buff(I2Cx_SLAVE_ADDRESS,reg,bufp,len,1);
#endif 
}
//读数据
static int32_t platform_read(void *handle, uint8_t reg, uint8_t *bufp, uint16_t len)
{
    if (len > 1){
        reg = reg | 0x80;
    }
#if CONFIG_I2C_HARD
    return py_i2c_hard_read_buff(I2Cx_SLAVE_ADDRESS,reg,bufp,len,1);
#endif 
#if CONFIG_I2C_SOFT
  return i2c_sotf_read_buff(I2Cx_SLAVE_ADDRESS,reg,bufp,len,1);
#endif 
}


uint8_t lis2dw12_config_mode(Lis2dw12ConfigMode mode)
{
    static uint8_t start=0;
   // uint8_t ret=0;

    if(start == 0)
    {
        dev_ctx.handle = NULL;
        dev_ctx.mdelay = platform_delay;
        dev_ctx.write_reg = platform_write;
        dev_ctx.read_reg = platform_read;

#if LIS2DW12_INT1_ENABLE
    lis2dw12_platform_int1_init();
    
#endif
        start = 1;
    }

    dev_ctx.mdelay(50);



    lis2dw12_device_id_get(&dev_ctx, &whoamI);
     if (whoamI != LIS2DW12_ID) {
        printf("lis2dw12-error id = %x\r\n",whoamI);
         return 0;
     }
    
    //恢复默认设置
    lis2dw12_reset_set(&dev_ctx, PROPERTY_ENABLE);
    dev_ctx.mdelay(50);
    // do {
    //   lis2dw12_reset_get(&dev_ctx, &rst);
    // } while (rst);



    switch (mode)
    {
    case LIS2DW12_LOW_POWER_STANDBY:
        lis2dw12_config_low_power_standby();
        break;
    case LIS2DW12_POLLING_MODE:
        lis2dw12_config_polling();
        break;
    case LIS2DW12_FIFO_STREAM_MODE:
        lis2dw12_config_fifo_stream();
        break;
    case LIS2DW12_FIFO_INT1_MODE:
        lis2dw12_config_fifo_int1();
        break;
    case LIS2DW12_TAP_SINGLE_MODE:
        lis2dw12_config_tap_single();
        break;
    case LIS2DW12_WAKEUP_MODE:
        lis2dw12_config_wake_up();
        break;

    default:
        return 0;
        break;
    }

    return 1;
}

类似封装一下,更方便调用。

功耗方面:

影响加速度传感器功耗最主要的就是性能模式和频率。

复制代码
    lis2dw12_power_mode_set(&dev_ctx, LIS2DW12_CONT_LOW_PWR_12bit);//低功耗12位
 
    lis2dw12_data_rate_set(&dev_ctx, LIS2DW12_XL_ODR_1Hz6_LP_ONLY);//频率 

设置成LOW-POWER MODE 1,1.6赫兹,最低功耗连1uA不到,

复制代码
    /* Configure power mode */
    lis2dw12_power_mode_set(&dev_ctx,
                            LIS2DW12_CONT_LOW_PWR_LOW_NOISE_12bit);
    /* Set Output Data Rate */
    lis2dw12_data_rate_set(&dev_ctx, LIS2DW12_XL_ODR_100Hz);

唤醒模式,LIS2DW12_CONT_LOW_PWR_LOW_NOISE_12bit,LIS2DW12_XL_ODR_100Hz才7uA,可以在休眠状态下判断是否震动。

数据可视化,看下水平时放置时数据波动。

qt自己写个上位机,使用qcustomplot模块

加速度矢量值

看下噪声干扰,使用方差的方式

电路图:

相关推荐
Nice__J2 小时前
Mcu架构以及原理——2.Cortex-M流水线与指令集
单片机·嵌入式硬件·架构
小白橘颂2 小时前
【C语言】基础概念梳理(一)
c语言·开发语言·stm32·单片机·mcu·物联网·51单片机
aini_lovee3 小时前
SIM7600模块STM32控制程序
stm32·单片机·嵌入式硬件
是翔仔呐3 小时前
第13章 超声波测距传感器驱动:HC-SR04底层原理与C语言实现
c语言·开发语言·单片机·嵌入式硬件·gitee
鲨辣椒100864 小时前
51单片机核心钉子户——温度采集模块
单片机·嵌入式硬件·51单片机
xiangw@GZ5 小时前
CapSense底层逻辑:硬件设计规范
单片机·嵌入式硬件·设计规范
Nice__J5 小时前
Mcu架构以及原理——3.存储器架构
单片机·嵌入式硬件·架构
weiyvyy5 小时前
嵌入式硬件接口的定义与作用
单片机·嵌入式硬件·信息与通信·信息化系统
senijusene5 小时前
依赖51 单片机的 Modbus 协议温度采集与外设控制系统的实现
c语言·单片机·嵌入式硬件·51单片机·keil