LIS3DH低功耗加速度传感器驱动程序

一、芯片核心特性与低功耗设计

LIS3DH是ST公司推出的超低功耗三轴加速度传感器,核心优势在于微安级功耗(低至2μA),支持多种低功耗模式,适用于电池供电设备(如可穿戴、IoT节点)。

低功耗关键特性

  • 工作模式 :正常模式(11μA@100Hz)、低功耗模式(2μA@1Hz)

  • 数据速率:1Hz~5.3kHz可编程,低速率下功耗线性降低

  • 电源管理:支持软复位、睡眠/唤醒控制

  • 中断驱动:通过单击/双击、自由落体等事件唤醒MCU,减少轮询功耗

二、完整驱动程序(模块化设计)

2.1 头文件 lis3dh.h(寄存器定义+函数声明)

c 复制代码
#ifndef __LIS3DH_H
#define __LIS3DH_H

#include <stdint.h>
#include <stdbool.h>

// ==================== I2C地址 ====================
#define LIS3DH_I2C_ADDR 0x18  // SDO接地(默认)
// #define LIS3DH_I2C_ADDR 0x19  // SDO接VCC

// ==================== 寄存器地址 ====================
#define LIS3DH_REG_WHO_AM_I   0x0F  // 设备ID(固定0x33)
#define LIS3DH_REG_CTRL_REG1  0x20  // 控制寄存器1(ODR、低功耗模式)
#define LIS3DH_REG_CTRL_REG4  0x23  // 控制寄存器4(量程、分辨率)
#define LIS3DH_REG_STATUS_REG 0x27  // 状态寄存器(数据就绪)
#define LIS3DH_REG_OUT_X_L    0x28  // X轴加速度低字节
#define LIS3DH_REG_OUT_X_H    0x29  // X轴加速度高字节
#define LIS3DH_REG_OUT_Y_L    0x2A  // Y轴加速度低字节
#define LIS3DH_REG_OUT_Y_H    0x2B  // Y轴加速度高字节
#define LIS3DH_REG_OUT_Z_L    0x2C  // Z轴加速度低字节
#define LIS3DH_REG_OUT_Z_H    0x2D  // Z轴加速度高字节
#define LIS3DH_REG_CTRL_REG2  0x21  // 高通滤波控制
#define LIS3DH_REG_CTRL_REG3  0x22  // 中断控制
#define LIS3DH_REG_INT1_THS   0x32  // 中断1阈值
#define LIS3DH_REG_INT1_DUR   0x33  // 中断1持续时间

// ==================== 枚举定义 ====================
// 数据输出速率(ODR)
typedef enum {
  LIS3DH_ODR_1HZ    = 0x10,  // 1Hz(低功耗)
  LIS3DH_ODR_10HZ   = 0x20,  // 10Hz
  LIS3DH_ODR_25HZ   = 0x30,  // 25Hz
  LIS3DH_ODR_50HZ   = 0x40,  // 50Hz
  LIS3DH_ODR_100HZ  = 0x50,  // 100Hz(正常模式)
  LIS3DH_ODR_POWERDOWN = 0x00 // 掉电模式(最低功耗)
} lis3dh_odr_t;

// 量程(FS)
typedef enum {
  LIS3DH_FS_2G  = 0x00,  // ±2g(灵敏度1mg/LSB)
  LIS3DH_FS_4G  = 0x10,  // ±4g(灵敏度2mg/LSB)
  LIS3DH_FS_8G  = 0x20,  // ±8g(灵敏度4mg/LSB)
  LIS3DH_FS_16G = 0x30   // ±16g(灵敏度12mg/LSB)
} lis3dh_fs_t;

// 工作模式
typedef enum {
  LIS3DH_MODE_NORMAL    = 0x00,  // 正常模式(12位分辨率)
  LIS3DH_MODE_LOW_POWER = 0x08   // 低功耗模式(8位分辨率)
} lis3dh_mode_t;

// ==================== 数据结构 ====================
typedef struct {
  int16_t x;       // X轴原始加速度(16位)
  int16_t y;       // Y轴原始加速度(16位)
  int16_t z;       // Z轴原始加速度(16位)
  float x_g;       // X轴加速度(g)
  float y_g;       // Y轴加速度(g)
  float z_g;       // Z轴加速度(g)
} lis3dh_data_t;

typedef struct {
  uint8_t i2c_addr;       // I2C地址
  lis3dh_fs_t fs;         // 当前量程
  lis3dh_mode_t mode;     // 当前模式
  float sensitivity;      // 灵敏度(mg/LSB)
  bool initialized;       // 初始化标志
} lis3dh_dev_t;

// ==================== 函数声明 ====================
// 底层I2C接口(用户需根据硬件实现)
extern bool i2c_write(uint8_t addr, uint8_t reg, uint8_t data);
extern bool i2c_read(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len);
extern void delay_ms(uint32_t ms);

// 传感器驱动函数
bool lis3dh_init(lis3dh_dev_t *dev, uint8_t i2c_addr);  // 初始化传感器
bool lis3dh_config(lis3dh_dev_t *dev, lis3dh_odr_t odr, lis3dh_fs_t fs, lis3dh_mode_t mode);  // 配置参数
bool lis3dh_read_data(lis3dh_dev_t *dev, lis3dh_data_t *data);  // 读取加速度数据
bool lis3dh_enter_low_power(lis3dh_dev_t *dev);  // 进入低功耗模式(掉电)
bool lis3dh_wakeup(lis3dh_dev_t *dev, lis3dh_odr_t odr);  // 唤醒并设置ODR
bool lis3dh_config_click(lis3dh_dev_t *dev, uint8_t threshold, uint8_t duration);  // 配置单击检测(中断唤醒)

#endif // __LIS3DH_H

2.2 源文件 lis3dh.c(驱动逻辑实现)

c 复制代码
#include "lis3dh.h"
#include <math.h>

// ==================== 私有函数 ====================
// 写寄存器
static bool write_reg(lis3dh_dev_t *dev, uint8_t reg, uint8_t data) {
  return i2c_write(dev->i2c_addr, reg, data);
}

// 读寄存器
static bool read_reg(lis3dh_dev_t *dev, uint8_t reg, uint8_t *data) {
  return i2c_read(dev->i2c_addr, reg, data, 1);
}

// 读多个寄存器
static bool read_regs(lis3dh_dev_t *dev, uint8_t reg, uint8_t *buf, uint8_t len) {
  return i2c_read(dev->i2c_addr, reg, buf, len);
}

// 获取灵敏度(mg/LSB)
static float get_sensitivity(lis3dh_fs_t fs, lis3dh_mode_t mode) {
  if (mode == LIS3DH_MODE_LOW_POWER) {
    switch (fs) {
      case LIS3DH_FS_2G: return 16.0f;   // 8位低功耗模式
      case LIS3DH_FS_4G: return 32.0f;
      case LIS3DH_FS_8G: return 62.0f;
      case LIS3DH_FS_16G: return 186.0f;
      default: return 16.0f;
    }
  } else {
    switch (fs) {
      case LIS3DH_FS_2G: return 1.0f;    // 12位正常模式
      case LIS3DH_FS_4G: return 2.0f;
      case LIS3DH_FS_8G: return 4.0f;
      case LIS3DH_FS_16G: return 12.0f;
      default: return 1.0f;
    }
  }
}

// ==================== 公有函数实现 ====================
// 初始化传感器
bool lis3dh_init(lis3dh_dev_t *dev, uint8_t i2c_addr) {
  if (!dev) return false;
  dev->i2c_addr = i2c_addr;
  dev->initialized = false;

  // 读取WHO_AM_I验证连接(固定0x33)
  uint8_t id;
  if (!read_reg(dev, LIS3DH_REG_WHO_AM_I, &id) || id != 0x33) {
    return false;  // 设备未连接或ID错误
  }

  // 软件复位(CTRL_REG5 bit7=1)
  write_reg(dev, 0x24, 0x80);  // CTRL_REG5
  delay_ms(10);

  dev->initialized = true;
  return true;
}

// 配置传感器参数(ODR/量程/模式)
bool lis3dh_config(lis3dh_dev_t *dev, lis3dh_odr_t odr, lis3dh_fs_t fs, lis3dh_mode_t mode) {
  if (!dev || !dev->initialized) return false;

  // 配置CTRL_REG1(ODR+低功耗模式)
  uint8_t ctrl1 = odr;
  if (mode == LIS3DH_MODE_LOW_POWER) ctrl1 |= 0x08;  // 低功耗位
  if (!write_reg(dev, LIS3DH_REG_CTRL_REG1, ctrl1)) return false;

  // 配置CTRL_REG4(量程+分辨率)
  uint8_t ctrl4 = fs;
  if (mode == LIS3DH_MODE_NORMAL) ctrl4 |= 0x08;  // 高分辨率位
  if (!write_reg(dev, LIS3DH_REG_CTRL_REG4, ctrl4)) return false;

  // 更新设备状态
  dev->fs = fs;
  dev->mode = mode;
  dev->sensitivity = get_sensitivity(fs, mode);
  return true;
}

// 读取加速度数据(原始值+g值)
bool lis3dh_read_data(lis3dh_dev_t *dev, lis3dh_data_t *data) {
  if (!dev || !data || !dev->initialized) return false;

  // 检查数据就绪(STATUS_REG bit3=1)
  uint8_t status;
  if (!read_reg(dev, LIS3DH_REG_STATUS_REG, &status) || !(status & 0x08)) {
    return false;  // 数据未就绪
  }

  // 读6字节加速度数据(X_L, X_H, Y_L, Y_H, Z_L, Z_H)
  uint8_t buf[6];
  if (!read_regs(dev, LIS3DH_REG_OUT_X_L, buf, 6)) return false;

  // 组合16位数据(小端格式)
  data->x = (int16_t)((buf[1] << 8) | buf[0]);
  data->y = (int16_t)((buf[3] << 8) | buf[2]);
  data->z = (int16_t)((buf[5] << 8) | buf[4]);

  // 转换为g值(1g=1000mg)
  data->x_g = (float)data->x * dev->sensitivity / 1000.0f;
  data->y_g = (float)data->y * dev->sensitivity / 1000.0f;
  data->z_g = (float)data->z * dev->sensitivity / 1000.0f;
  return true;
}

// 进入低功耗模式(掉电,仅保留寄存器配置)
bool lis3dh_enter_low_power(lis3dh_dev_t *dev) {
  if (!dev || !dev->initialized) return false;
  // 设置CTRL_REG1为0x00(ODR=0,所有轴关闭)
  return write_reg(dev, LIS3DH_REG_CTRL_REG1, 0x00);
}

// 唤醒传感器(设置ODR并启动测量)
bool lis3dh_wakeup(lis3dh_dev_t *dev, lis3dh_odr_t odr) {
  if (!dev || !dev->initialized) return false;
  // 配置CTRL_REG1(ODR+使能三轴)
  uint8_t ctrl1 = odr | 0x07;  // 0x07=使能X/Y/Z轴
  if (dev->mode == LIS3DH_MODE_LOW_POWER) ctrl1 |= 0x08;  // 低功耗位
  return write_reg(dev, LIS3DH_REG_CTRL_REG1, ctrl1);
}

// 配置单击检测(中断1唤醒MCU)
bool lis3dh_config_click(lis3dh_dev_t *dev, uint8_t threshold, uint8_t duration) {
  if (!dev || !dev->initialized) return false;
  // 1. 配置中断1:单击检测(X/Y/Z轴)
  if (!write_reg(dev, LIS3DH_REG_INT1_CFG, 0x2A)) return false;  // 0x2A=Z_HI+Y_HI+X_HI
  // 2. 设置阈值(1LSB=灵敏度,如2g量程下1LSB=16mg@低功耗)
  if (!write_reg(dev, LIS3DH_REG_INT1_THS, threshold)) return false;
  // 3. 设置持续时间(1LSB=1/ODR,如100Hz下1LSB=10ms)
  if (!write_reg(dev, LIS3DH_REG_INT1_DUR, duration)) return false;
  // 4. 使能中断1(CTRL_REG3 bit6=1)
  return write_reg(dev, LIS3DH_REG_CTRL_REG3, 0x40);
}

2.3 平台适配层(以STM32 HAL库为例)

c 复制代码
// platform_i2c.c(用户需根据硬件修改)
#include "lis3dh.h"
#include "stm32f1xx_hal.h"  // 替换为实际MCU头文件

extern I2C_HandleTypeDef hi2c1;  // I2C句柄(需在CubeMX中配置)

// I2C写函数(STM32 HAL库实现)
bool i2c_write(uint8_t addr, uint8_t reg, uint8_t data) {
  return HAL_I2C_Mem_Write(&hi2c1, addr<<1, reg, I2C_MEMADD_SIZE_8BIT, &data, 1, 100) == HAL_OK;
}

// I2C读函数(STM32 HAL库实现)
bool i2c_read(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len) {
  return HAL_I2C_Mem_Read(&hi2c1, addr<<1, reg, I2C_MEMADD_SIZE_8BIT, buf, len, 100) == HAL_OK;
}

// 延时函数(STM32 HAL库实现)
void delay_ms(uint32_t ms) {
  HAL_Delay(ms);
}

三、低功耗应用示例(STM32 + 电池供电)

c 复制代码
// main.c(低功耗场景:电池供电,事件驱动唤醒)
#include "lis3dh.h"
#include "stm32f1xx_hal.h"

lis3dh_dev_t accel = {0};

int main(void) {
  HAL_Init();
  SystemClock_Config();
  MX_I2C1_Init();  // 初始化I2C(CubeMX配置)

  // 1. 初始化传感器
  if (!lis3dh_init(&accel, LIS3DH_I2C_ADDR)) {
    Error_Handler();  // 传感器初始化失败
  }

  // 2. 配置低功耗参数(1Hz ODR,±2g量程,低功耗模式)
  lis3dh_config(&accel, LIS3DH_ODR_1HZ, LIS3DH_FS_2G, LIS3DH_MODE_LOW_POWER);

  // 3. 配置单击检测(阈值=20mg@低功耗模式,持续时间=10ms)
  lis3dh_config_click(&accel, 1, 1);  // 阈值=1LSB=16mg,持续1个ODR周期(1s@1Hz)

  while (1) {
    // 4. 进入低功耗模式(仅保留传感器中断唤醒)
    HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
    
    // 5. 唤醒后读取数据(中断触发时执行)
    lis3dh_data_t data;
    if (lis3dh_read_data(&accel, &data)) {
      // 处理数据(如通过BLE发送)
    }
  }
}

参考代码 低功耗加速度传感器LIS3DH芯片的源程序 www.youwenfan.com/contentcsu/56259.html

四、关键低功耗设计说明

  1. 模式切换 :通过lis3dh_enter_low_power()进入掉电模式(2μA),lis3dh_wakeup()唤醒并设置ODR(1Hz时功耗~2.5μA)。

  2. 事件驱动:配置单击/自由落体中断,传感器检测到事件时触发INT1引脚,唤醒MCU(避免轮询)。

  3. 参数优化:低功耗模式下使用8位分辨率(灵敏度16mg/LSB@±2g),降低数据量;1Hz ODR减少采样频率。

五、使用注意事项

  • I2C地址:根据SDO引脚电平选择0x18(接地)或0x19(接VCC)。

  • 灵敏度计算:低功耗模式(8位)灵敏度=量程/128,正常模式(12位)=量程/4096。

  • 中断配置:INT1引脚需配置为上拉输入,下降沿触发(LIS3DH默认高电平有效)。

相关推荐
三维频道2 小时前
注塑件变形怎么调优?全尺寸3D检测如何助力精密注塑“减废增效”
3d·制造·智能制造·3d扫描仪·新拓三维·注塑模具质检·三维尺寸偏差分析
AI前沿资讯2 小时前
2026年3D动画制作工具推荐:从传统工作流到AI一站式创作
人工智能·3d
bryant_meng19 小时前
【3D】Stereo Matching learning notes
计算机视觉·3d·双目匹配
三维频道1 天前
工业级三维扫描实测:汽车灯具复杂结构件的全尺寸 3D 测量方案分析
java·人工智能·python·数码相机·3d·汽车·汽车轻量化制造
MapVillage1 天前
3D Gaussian Splats 高斯泼溅技术
3d
杀生丸学AI1 天前
【三维重建】Neural Gabor Splatting:基于神经Gabor的增强型3DGS(高频表面重建)
3d·aigc·扩散模型·视觉大模型·点云分割·高斯泼溅·空间智能
a1117761 天前
Web3D 在线3D模型骨骼动画编辑器(开源 Reze Studio)
前端·3d·开源·html
Hody911 天前
【XR技术介绍】AI快速扫描3D场景技术全景解析:水平、路径与技术选型
人工智能·3d·xr
课灵_klhubs2 天前
课灵h5p-3D 模型 (3D Model)教程
前端·3d·课程设计·教程·课灵·h5p