This commit is contained in:
lmx
2025-10-29 16:24:16 +08:00
parent 49a07fa419
commit 7567ddc088
316 changed files with 221568 additions and 213253 deletions

View File

@ -0,0 +1,510 @@
//LIS2DH12驱动
#include "gSensor/gSensor_manage.h"
#include "app_config.h"
#include "math.h"
#include "LIS2DH12.h"
#include "colorful_lights/colorful_lights.h"
#include <string.h> // For memcpy
#define ENABLE_XLOG 1
#ifdef xlog
#undef xlog
#endif
#if ENABLE_XLOG
#define xlog(format, ...) printf("[%s] " format, __func__, ##__VA_ARGS__)
#else
#define xlog(format, ...) ((void)0)
#endif
// #define SAMPLE_COUNT 25 // 定义静止状态检测所需的样本数量
#define SAMPLE_COUNT 6 // 定义静止状态检测所需的样本数量
// #define THRESHOLD 2.00f // 定义静止状态检测的阈值单位g
#define THRESHOLD 10.00f // 定义静止状态检测的阈值, 三轴传感器数据的方差
#define STATIC_MAX_TIME 60*5*5 //传感器静止最大时间,单位 200ms 超过这个值就发数据通知AI询问用户是否需要帮助
#define DORMANCY_MAX_TIME 60*5 //三个角度超过一分钟没有更新就关闭当前灯效,如果有数据刷新就恢复之前的灯效,单位200ms
u8 dormancy_flag = 0; //标识
u8 dormancy_ago_moedl = 0; //记录休眠前灯效
u16 gsensor_static_flag; //记录传感器静止的时间,单位 200ms
axis_info_t current_data[32]; // 全局变量存储当前数据
// Global variables for motion data
static motion_data_t motion_data = {{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}; // 存储运动数据
static axis_info_xtell gravity_vector = {0.0f, 0.0f, 0.0f};// 存储估算的重力方向
static bool sensor_is_stable = false;
u8 gsensor_alarm;
// u8 xtell_uart_Gsensor_static[5]={0xAA,0x55,0x0F,0x55,0xAA}; //发现用户长时间静止时串口发数据给AI芯片
// 假设当前设置的满量程范围
const scale_t CURRENT_SCALE = SCALE_8G;
#define LIS2DH12_FROM_FS_8g_HR_TO_mg(lsb) (float)((int16_t)lsb>>4) * 4.0f
axis_info_xtell gsensor_xtell;
/***使用驱动前请根据实际接线情况配置7bitIIC地址******/
/** LIS2DH12 的SDO 脚接地: 0x30****************/
/** LIS2DH12 的SDO 脚接电源: 0x31****************/
// #define LIS2DH12_W_ADDR (0x31U << 1 | 0x0)
// #define LIS2DH12_R_ADDR (0x31U << 1 | 0x1)
#define LIS2DH12_W_ADDR 0x32
#define LIS2DH12_R_ADDR 0x33
/**IIC 寄存器地址宏定义***************/
#define LIS2DH12_OUT_TEMP_L 0x0C //温度数据低位
#define LIS2DH12_OUT_TEMP_H 0x0D //温度数据高位
#define LIS2DH12_WHO_AM_I 0x0F //读IIC寄存器 自身地址的值正确应该是0x33
#define LIS2DH12_CTRL_RGE0 0x1E //设置SDO 内部上/下拉
#define LIS2DH12_TEMP_CFG_REG 0x1F //使能温度传感器
#define LIS2DH12_CTRL_REG1 0x20
#define LIS2DH12_CTRL_REG2 0x21
#define LIS2DH12_CTRL_REG3 0x22
#define LIS2DH12_CTRL_REG4 0x23
#define LIS2DH12_CTRL_REG5 0x24
#define LIS2DH12_CTRL_REG6 0x25
#define LIS2DH12_REFERENCE 0x26
#define LIS2DH12_STATUS_REG 0x27
#define LIS2DH12_OUT_X_L 0x28
#define LIS2DH12_OUT_X_H 0x29
#define LIS2DH12_OUT_Y_L 0x2A
#define LIS2DH12_OUT_Y_H 0x2B
#define LIS2DH12_OUT_Z_L 0x2C
#define LIS2DH12_OUT_Z_H 0x2D
#define LIS2DH12_FIFO_CTRL_REG 0x2E
#define LIS2DH12_SRC_REG 0x2F
#define LIS2DH12_INT1_CFG 0x30
#define LIS2DH12_INT1_SRC 0x31
#define LIS2DH12_INT1_THS 0x32
#define LIS2DH12_INT1_DURATION 0x33
#define LIS2DH12_INT2_CFG 0x34
#define LIS2DH12_INT2_SRC 0x35
#define LIS2DH12_INT2_THS 0x36
#define LIS2DH12_INT2_DURATION 0x37
#define LIS2DH12_CLICK_CFG 0x38
#define LIS2DH12_CLICK_SRC 0x39
#define LIS2DH12_CLICK_THS 0x3A
#define LIS2DH12_TIME_LIMIT 0x3B
#define LIS2DH12_TIME_LATENCY 0x3C
#define LIS2DH12_TIME_WINDOW 0x3D
#define LIS2DH12_ACT_THS 0x3E
#define LIS2DH12_ACT_DUR 0x3F
u32 SL_MEMS_i2cRead(u8 addr, u8 reg, u8 len, u8 *buf)
{
return _gravity_sensor_get_ndata(addr, reg, buf, len);
}
u8 SL_MEMS_i2cWrite(u8 addr, u8 reg, u8 data)
{
gravity_sensor_command(addr, reg, data);
return 0;
}
/***传感器校验 读 读IIC寄存器 自身地址的值*/
char LIS2DH12_Check()
{
u8 reg_value = 0;
SL_MEMS_i2cRead(LIS2DH12_R_ADDR, LIS2DH12_WHO_AM_I, 1, &reg_value);
xlog("xtell LIS2DH12_Check: reg WHO_AM_I value = %x H\n", reg_value);
if (reg_value == 0x33) {
return 0x01;
} else {
return 0x00;
}
}
/*
传感器配置 初始化
*/
u8 LIS2DH12_Config(void)
{
u8 Check_Flag = 0;
u8 write_num = 0, i = 0;
// u8 ODR = 0x77; //数据速率400HZ 正常模式(低功耗-> 0x7F
u8 ODR = 0x37; //速率25hz,
u8 HP = 0x03; //开启高通滤波 HPCF位对应的表格没找到
// u8 click_int = 0x04; //将Click中断映射到INT1 OVERRUN
u8 range = 0xA0; //8g量程块使能正常模式(10位数据)
u8 fifo_en = 0x40; //使能FIFO模式
u8 fifo_mode = 0x80;//0x40; //流模式
// u8 click_mode = 0x15; //单击3轴触发
Check_Flag = LIS2DH12_Check();
if (Check_Flag == 1) {
// SL_MEMS_i2cWrite(LIS2DH12_W_ADDR, LIS2DH12_TEMP_CFG_REG, 0xC0); //开启温度传感器
SL_MEMS_i2cWrite(LIS2DH12_W_ADDR, LIS2DH12_CTRL_REG1, ODR);
SL_MEMS_i2cWrite(LIS2DH12_W_ADDR, LIS2DH12_CTRL_REG2, HP);
// SL_MEMS_i2cWrite(LIS2DH12_W_ADDR, LIS2DH12_CTRL_REG3, click_int);// 中断的使能,默认都是禁用
SL_MEMS_i2cWrite(LIS2DH12_W_ADDR, LIS2DH12_CTRL_REG4, range); //
SL_MEMS_i2cWrite(LIS2DH12_W_ADDR, LIS2DH12_CTRL_REG5, fifo_en);
SL_MEMS_i2cWrite(LIS2DH12_W_ADDR, LIS2DH12_FIFO_CTRL_REG, fifo_mode);
/*
SL_MEMS_i2cWrite(LIS2DH12_W_ADDR, LIS2DH12_CLICK_CFG, click_mode);//单Z轴
SL_MEMS_i2cWrite(LIS2DH12_W_ADDR, LIS2DH12_CLICK_THS, LIS2DH12_CLICK_TH);//62.6mg(4g)*10
SL_MEMS_i2cWrite(LIS2DH12_W_ADDR, LIS2DH12_TIME_LIMIT, LIS2DH12_CLICK_WINDOWS);
SL_MEMS_i2cWrite(LIS2DH12_W_ADDR, LIS2DH12_TIME_LATENCY, LIS2DH12_CLICK_LATENCY);
*/
// SL_MEMS_i2cWrite(LIS2DH12_W_ADDR, LIS2DH12_CTRL_REG6, LIS2DH12_INT_LEVEL);
xlog(" LIS2DH12 i2c check ok\n");
return 0;
} else {
xlog(" LIS2DH12 i2c check fail\n");
return -1;
}
}
u8 LIS2DH12_disable(void)
{
u8 Check_Flag = LIS2DH12_Check();
if (Check_Flag == 1) {
u8 ODR = 0x00;
SL_MEMS_i2cWrite(LIS2DH12_W_ADDR, LIS2DH12_CTRL_REG1, ODR);
xlog("check ok,LIS2DH12_disable\n");
return 0;
} else {
xlog("check fail\n");
return -1;
}
}
void LIS2DH12_read_data_old(axis_info_t *sl_accel)
{
u8 data[6];
u8 fifo_len = 0;
u8 STATUS_REG_data =0;
SL_MEMS_i2cRead(LIS2DH12_R_ADDR, LIS2DH12_SRC_REG, 1, &fifo_len);
SL_MEMS_i2cRead(LIS2DH12_R_ADDR, LIS2DH12_STATUS_REG, 1, &STATUS_REG_data);
xlog("STATUS_REG vlau = %xH\n",STATUS_REG_data);
xlog("FIFO vlau = %xH\n",fifo_len);
if ((fifo_len & 0x40) == 0x40) { //FIFO 溢出标志
fifo_len = 32;
xlog("FIFO is full\n");
} else {
fifo_len = fifo_len & 0x1f;
}
for (u8 i = 0; i < fifo_len; i++) {
SL_MEMS_i2cRead(LIS2DH12_R_ADDR, LIS2DH12_OUT_X_L, 6, data);
sl_accel[i].x = (short)((data[1] << 8) | data[0]);
// sl_accel[i].x = sl_accel[i].x >> 4;
sl_accel[i].y = (short)((data[3] << 8) | data[2]);
// sl_accel[i].y = sl_accel[i].y >> 4;
sl_accel[i].z = (short)((data[5] << 8) | data[4]);
// sl_accel[i].z = sl_accel[i].z >> 4;
// xlog("group:%2d,sl_accel_x:%5d, sl_accel_y:%5d, sl_accel_z:%5d\n", i, sl_accel[i].x, sl_accel[i].y, sl_accel[i].z);
}
xlog("group:%2d,sl_accel_x:%5d, sl_accel_y:%5d, sl_accel_z:%5d\n", sl_accel[fifo_len -1].x, sl_accel[fifo_len -1].y, sl_accel[fifo_len -1].z);
}
//8.1 小李
// 获取三轴传感器的x,y,z加速度值
/**
* @brief 获取三轴传感器的x,y,z加速度值
*
* @param axis_info_t 参数是axis_info_t类型结构体变量用于存放x,y,z的加速度值
* @return void 此函数无返回值
*/
extern u16 High_g;
void LIS2DH12_read_data(axis_info_t *sl_accel)
{
u8 fifo_src = 0;
u8 samples_available = 0;
u8 data[192]; //32*6
s16 raw_x,raw_y,raw_z;
// print_register_values(); // 打印寄存器值
// 读取FIFO状态
SL_MEMS_i2cRead(LIS2DH12_R_ADDR, LIS2DH12_SRC_REG, 1, &fifo_src);
// xlog("FIFO_SRC_REG: 0x%02X\n", fifo_src);
// 检查FIFO是否为空
// if (fifo_src & 0x20) {
// xlog("FIFO is empty\n");
// LIS2DH12_reinit_fifo(); //重新启用FIFO
// 尝试重新初始化FIFO
// SL_MEMS_i2cWrite(LIS2DH12_W_ADDR, LIS2DH12_CTRL_REG5, 0x40); // 使能FIFO
// SL_MEMS_i2cWrite(LIS2DH12_W_ADDR, LIS2DH12_FIFO_CTRL_REG, 0x40); // FIFO模式
// return;
// }
// 获取可用样本数
samples_available = fifo_src & 0x1F;
// xlog("Available samples: %d\n", samples_available);
// 一次性读取所有FIFO数据
SL_MEMS_i2cRead(LIS2DH12_R_ADDR, LIS2DH12_OUT_X_L | 0x80, samples_available * 6, data);
// if (SL_MEMS_i2cRead(LIS2DH12_R_ADDR, LIS2DH12_OUT_X_L | 0x80, samples_available * 6, data) != 0) {
// xlog("Error reading FIFO data\n");
// return;
// }
// 解析数据
for (u8 i = 0; i < samples_available; i++) {
raw_x = (int16_t)((data[i * 6 + 1] << 8) | data[i * 6]) >> 6; //传感器输出的是10位数据
raw_y = (int16_t)((data[i * 6 + 3] << 8) | data[i * 6 + 2]) >> 6;
raw_z = (int16_t)((data[i * 6 + 5] << 8) | data[i * 6 + 4]) >> 6;
raw_x =convert_10bit_2s_complement(raw_x);
raw_y =convert_10bit_2s_complement(raw_y);
raw_z =convert_10bit_2s_complement(raw_z);
sl_accel[i].x = raw_x;
sl_accel[i].y = raw_y;
sl_accel[i].z = raw_z;
// if (raw_z > 0) {
// // High_g = raw_z * 0.16f;
// High_g = (u8)((float)raw_z * 0.16f);
// } else {
// // High_g = -1.0f * raw_z * 0.16f;
// High_g = (u8)((-1.0f * (float)raw_z) * 0.16f);
// }
// xlog("###High_g == %d\n",High_g);
// xlog("\nSample %d: X=%d, Y=%d, Z=%d\n", i, sl_accel[i].x, sl_accel[i].y, sl_accel[i].z); //打印从寄存器读到的数据
// gsensor_xtell.x = raw_x;
// gsensor_xtell.y = raw_y;
// gsensor_xtell.z = raw_z;
// sl_accel[i].x = raw_x;
// sl_accel[i].y = raw_y;
// sl_accel[i].z = raw_z;
// sl_accel[i].x = (float)raw_x *0.16f; //实际的加速度值 8g 量程
// sl_accel[i].y = (float)raw_y *0.16f;
// sl_accel[i].z = (float)raw_z *0.16f;
// xlog("Sample %d: X=%.2f g, Y=%.2f g, Z=%.2f g\n", i, sl_accel[i].x, sl_accel[i].y, sl_accel[i].z);
}
}
// 判断传感器是否长期静止的函数
bool is_sensor_stable(axis_info_t *accel_data, int sample_count) {
float mean_x = 0, mean_y = 0, mean_z = 0;
float variance_x = 0, variance_y = 0, variance_z = 0;
// 计算每个轴的均值
for (int i = 0; i < sample_count; i++) {
mean_x += accel_data[i].x;
mean_y += accel_data[i].y;
mean_z += accel_data[i].z;
}
mean_x /= sample_count;
mean_y /= sample_count;
mean_z /= sample_count;
// xlog("Mean X: %.2f, Y: %.2f, Z: %.2f\n", mean_x, mean_y, mean_z); //平均数
gsensor_xtell.x = mean_x;
gsensor_xtell.y = mean_y;
gsensor_xtell.z = mean_z;
// 计算每个轴的方差
for (int i = 0; i < sample_count; i++) {
variance_x += (accel_data[i].x - mean_x) * (accel_data[i].x - mean_x);
variance_y += (accel_data[i].y - mean_y) * (accel_data[i].y - mean_y);
variance_z += (accel_data[i].z - mean_z) * (accel_data[i].z - mean_z);
}
variance_x /= (sample_count - 1);
variance_y /= (sample_count - 1);
variance_z /= (sample_count - 1);
// 打印均值和方差,用于调试
// xlog("Variance X: %.2f, Y: %.2f, Z: %.2f\n", variance_x, variance_y, variance_z);
// 判断方差是否在阈值范围内
//非静止状态
if (variance_x > THRESHOLD || variance_y > THRESHOLD || variance_z > THRESHOLD) {
gsensor_static_flag = 0;
gsensor_alarm =0;
// xlog("**********Sensor is not stable\n");
//超过预设值休眠后重新有数据刷新
if(dormancy_flag){
dormancy_flag = 0;
set_rgb(dormancy_ago_moedl);
dormancy_ago_moedl = 0;
}
return false;
}else { //静止状态
gsensor_static_flag++;
if(gsensor_static_flag >= STATIC_MAX_TIME){
gsensor_alarm =0xFF;
// xlog("@@@Do you need help?@@@");
// gsensor_static_flag =0;
}
#if 0 //0表示测试 1表示正式代码
if(gsensor_static_flag >= DORMANCY_MAX_TIME){ //静止时间超过预设值就关闭灯效,有数据刷新再打开之前灯效
if(dormancy_ago_moedl != RGB_model){ //休眠时灯效和当前灯效 不一致就关闭灯效
dormancy_ago_moedl = RGB_model;
dormancy_flag =1;
colorful_lights_function().update_display_mode(COLORFUL_LIGHTS_DISPLAY_NULL); //关闭灯效
// xlog("dormancy close LED\n");
}
}
#endif
return true; // 传感器处于静止状态
}
}
void print_register_values(){
u8 ctrl_reg1, ctrl_reg3, ctrl_reg5, fifo_ctrl;
SL_MEMS_i2cRead(LIS2DH12_R_ADDR, LIS2DH12_CTRL_REG1, 1, &ctrl_reg1);
SL_MEMS_i2cRead(LIS2DH12_R_ADDR, LIS2DH12_CTRL_REG3, 1, &ctrl_reg3);
SL_MEMS_i2cRead(LIS2DH12_R_ADDR, LIS2DH12_CTRL_REG5, 1, &ctrl_reg5);
SL_MEMS_i2cRead(LIS2DH12_R_ADDR, LIS2DH12_FIFO_CTRL_REG, 1, &fifo_ctrl);
// xlog("CTRL_REG1: 0x%02X, CTRL_REG3: 0x%02X, CTRL_REG5: 0x%02X, FIFO_CTRL_REG: 0x%02X\n", ctrl_reg1, ctrl_reg3, ctrl_reg5, fifo_ctrl);
}
void LIS2DH12_reinit_fifo() {
SL_MEMS_i2cWrite(LIS2DH12_W_ADDR, LIS2DH12_CTRL_REG5, 0x00); // 禁用FIFO
SL_MEMS_i2cWrite(LIS2DH12_W_ADDR, LIS2DH12_FIFO_CTRL_REG, 0x00); // 禁用FIFO模式
delay_2ms(1);
SL_MEMS_i2cWrite(LIS2DH12_W_ADDR, LIS2DH12_CTRL_REG5, 0x40); // 重新使能FIFO
SL_MEMS_i2cWrite(LIS2DH12_W_ADDR, LIS2DH12_FIFO_CTRL_REG, 0x40); // 重新设置FIFO模式
}
// 转换函数
float convert_to_g_old(int16_t raw_value, scale_t scale) {
// 将 16 位有符号整数转换为浮点数
float sensitivity;
switch(scale) {
case SCALE_2G:
sensitivity = 1.0f / 16384.0f; // ±2g 范围下的灵敏度
break;
case SCALE_4G:
sensitivity = 1.0f / 8192.0f; // ±4g 范围下的灵敏度
break;
case SCALE_8G:
sensitivity = 1.0f / 4096.0f; // ±8g 范围下的灵敏度
break;
case SCALE_16G:
sensitivity = 1.0f / 2048.0f; // ±16g 范围下的灵敏度
break;
default:
sensitivity = 1.0f / 16384.0f; // 默认使用 ±2g 范围
}
return (float)raw_value * sensitivity * scale / 2.0f;
}
//10位2补码转换
int16_t convert_10bit_2s_complement(int16_t data) {
if (data & 0x200) { // 判断最高位符号位是否为1符号位为1表示2补码时负数
// 如果2补码是负数把2补码转成原码
data = ~(data - 1); // 先减1再按位取反
data &= 0x3FF; // 保留低10位
data = -data; // 加上负号
}
return data;
}
// 将原始数据转换为实际加速度值的函数
float convert_to_g(int16_t raw_value) {
float sensitivity = 0.016f; // 16 mg/digit
// switch(CURRENT_SCALE) {
// case SCALE_2G:
// sensitivity = 0.001f; // 4 mg/digit
// break;
// case SCALE_4G:
// sensitivity = 0.008f; // 8 mg/digit
// break;
// case SCALE_8G:
// sensitivity = 0.016f; // 16 mg/digit
// break;
// case SCALE_16G:
// sensitivity = 0.048f; // 48 mg/digit
// break;
// default:
// sensitivity = 0.004f; // Default to ±2g range
// }
if (raw_value & 0x200) { // 判断最高位符号位是否为1符号位为1表示2补码时负数
// 如果2补码是负数把2补码转成原码
raw_value = ~(raw_value - 1); // 先减1再按位取反
raw_value &= 0x3FF; // 保留低10位
raw_value = -raw_value; // 加上负号
}
// xlog("raw value= %d",raw_value);
// Convert to g
return (float)raw_value * sensitivity;
}
// 读取传感器数据的定时器回调函数
// 在全局变量区域添加:
axis_info_t last_accel_data = {0.0f, 0.0f, 0.0f}; // 用于存储上一时刻的加速度
// --- New functions for motion tracking ---
/**
* @brief 获取当前加速度值,单位 m/s^2
* @return axis_info_xtell 包含x,y,z轴加速度的结构体
*/
axis_info_xtell get_current_accel_mss(void) {
axis_info_xtell accel_mss;
// 1 LSb = 62 mg @ FS = 8 g
// 8g量程: 16 mg/LSB == 0.016 g/LSB
//gADC / (灵敏度LSB/g) = ADC * X g/LSB
//实际加速度 = g * 9.8 m/s^2
accel_mss.x = (float)gsensor_xtell.x * 0.016f * GRAVITY_EARTH;
accel_mss.y = (float)gsensor_xtell.y * 0.016f * GRAVITY_EARTH;
accel_mss.z = (float)gsensor_xtell.z * 0.016f * GRAVITY_EARTH;
return accel_mss;
}
/**
* @brief 获取计算出的运动数据(速度和距离)
* @param data 指向 motion_data_t 结构体的指针,用于存放结果
*/
void get_motion_data(motion_data_t *data) {
if (data) {
// Use a critical section or disable interrupts if this can be called from another thread
memcpy(data, &motion_data, sizeof(motion_data_t));
}
}
void xtell_i2c_test() {
// 获取LIS2DH12三轴加速度
LIS2DH12_read_data(current_data);
//判断是否静止, is_sensor_stable会更新全局变量gsensor_xtell
sensor_is_stable = is_sensor_stable(current_data, SAMPLE_COUNT);
axis_info_xtell current_accel_mss = get_current_accel_mss();
axis_info_xtell linear_accel;
// 低通滤波器,把运动产生的加速度和地球重力产生的加速度分开
gravity_vector.x = LPF_ALPHA * gravity_vector.x + (1.0f - LPF_ALPHA) * current_accel_mss.x;
gravity_vector.y = LPF_ALPHA * gravity_vector.y + (1.0f - LPF_ALPHA) * current_accel_mss.y;
gravity_vector.z = LPF_ALPHA * gravity_vector.z + (1.0f - LPF_ALPHA) * current_accel_mss.z;
// 总加速度中减去重力
linear_accel.x = current_accel_mss.x - gravity_vector.x;
linear_accel.y = current_accel_mss.y - gravity_vector.y;
linear_accel.z = current_accel_mss.z - gravity_vector.z;
// 积分得到速度
motion_data.velocity.x += linear_accel.x * SAMPLING_PERIOD_S;
motion_data.velocity.y += linear_accel.y * SAMPLING_PERIOD_S;
motion_data.velocity.z += linear_accel.z * SAMPLING_PERIOD_S;
// 静止
if (sensor_is_stable) {
xlog("stop now\n");
motion_data.velocity.x = 0.0f;
motion_data.velocity.y = 0.0f;
motion_data.velocity.z = 0.0f;
}
// 再次积分得到距离
motion_data.distance.x += motion_data.velocity.x * SAMPLING_PERIOD_S;
motion_data.distance.y += motion_data.velocity.y * SAMPLING_PERIOD_S;
motion_data.distance.z += motion_data.velocity.z * SAMPLING_PERIOD_S;
float total_distance_magnitude = sqrtf(motion_data.distance.x * motion_data.distance.x +
motion_data.distance.y * motion_data.distance.y +
motion_data.distance.z * motion_data.distance.z);
xlog("================================================================\n");
xlog("Total Distance Magnitude: %.2f m\n", total_distance_magnitude);
xlog("================================================================\n");
}

View File

@ -0,0 +1,57 @@
#ifndef LIS2DH12_H
#define LIS2DH12_H
#include "gSensor/gSensor_manage.h"
// #include <stdatomic.h>
#include "le_rcsp_adv_module.h"
// Constants
#define GRAVITY_EARTH 9.80665f // m/s^2
#define SAMPLING_PERIOD_S 2 // 采样周期s
#define LPF_ALPHA 0.8f // 低通滤波系数
typedef struct {
float x;
float y;
float z;
} axis_info_xtell;
typedef struct {
axis_info_xtell velocity; // m/s
axis_info_xtell distance; // m
} motion_data_t;
// 定义可能的满量程范围
typedef enum {
SCALE_2G = 2,
SCALE_4G = 4,
SCALE_8G = 8,
SCALE_16G = 16
} scale_t;
unsigned char LIS2DH12_Config(void);
char LIS2DH12_Check();
unsigned char LIS2DH12_disable(void);
void LIS2DH12_read_data(axis_info_t *sl_accel);
void print_register_values();
void LIS2DH12_reinit_fifo();
// float convert_to_g(int16_t raw_value, scale_t scale);
float convert_to_g(int16_t raw_value);
void xtell_i2c_test();
// 获取运动数据
void get_motion_data(motion_data_t *data);
axis_info_xtell get_current_accel_mss(void);
//10位2补码转换
int16_t convert_10bit_2s_complement(int16_t data);
// typedef struct {
// short x;
// short y;
// short z;
// } axis_info_t;
#endif

View File

@ -0,0 +1,62 @@
#include "system/includes.h"
/*#include "btcontroller_config.h"*/
#include "btstack/btstack_task.h"
#include "app_config.h"
#include "app_action.h"
#include "asm/pwm_led.h"
#include "tone_player.h"
#include "ui_manage.h"
#include "gpio.h"
#include "app_main.h"
#include "asm/charge.h"
#include "update.h"
#include "app_power_manage.h"
#include "audio_config.h"
#include "app_charge.h"
#include "bt_profile_cfg.h"
#include "dev_manager/dev_manager.h"
#include "update_loader_download.h"
#include "LIS2DH12.h"
#define xlog(format, ...) printf("[%s] " format, __func__, ##__VA_ARGS__)
u16 xtell_i2c_test_id;
u16 print_motion_data_id;
// Task to print motion data periodically
void print_motion_data_task(void) {
motion_data_t current_motion;
axis_info_xtell current_accel;
// Get the latest motion data
get_motion_data(&current_motion);
current_accel = get_current_accel_mss();
xlog("--- Motion Data ---\n");
xlog("Accel (m/s^2): X=%.2f, Y=%.2f, Z=%.2f\n", current_accel.x, current_accel.y, current_accel.z);
xlog("Velo (m/s): X=%.2f, Y=%.2f, Z=%.2f\n", current_motion.velocity.x, current_motion.velocity.y, current_motion.velocity.z);
xlog("Dist (m): X=%.2f, Y=%.2f, Z=%.2f\n", current_motion.distance.x, current_motion.distance.y, current_motion.distance.z);
xlog("-------------------\n");
}
void create_process(u16* pid,char* name, void *priv, void (*func)(void *priv), u32 msec){
xlog("1 name=%s, pid =%d\n",name,*pid);
if (*pid != 0) return;
*pid = sys_timer_add(priv, func, msec);
xlog("2 name=%s, pid =%d\n",name,*pid);
}
void xtell_main(void){
soft_iic_init(0); // 引脚选择在demo_cf.h中
extern u8 LIS2DH12_Config(void);
LIS2DH12_Config();
// This task runs every 200ms to perform the calculations
create_process(&xtell_i2c_test_id, "xtell_i2c_test",NULL, xtell_i2c_test, SAMPLING_PERIOD_S*1000);
// This task runs every 1000ms to print the results
create_process(&print_motion_data_id, "print_motion_data_task", NULL, print_motion_data_task, 1000);
}