Files
motor-controller/docs/JY901_Sensor_Guide.md

6.6 KiB
Raw Blame History

JY-901 姿态传感器使用指南

1. 传感器简介

JY-901 是一款 9 轴姿态传感器,集成了:

  • 三轴加速度计 (Accelerometer)
  • 三轴陀螺仪 (Gyroscope)
  • 三轴磁力计 (Magnetometer)

传感器通过 I2C 接口 与 STM32 通信,默认 I2C 地址为 0x50,支持最大 400kHz 通信速率。


2. 数据寄存器

2.1 寄存器映射

寄存器 地址 说明 量程
AX, AY, AZ 0x34-0x36 加速度计原始数据 ±16g
GX, GY, GZ 0x37-0x39 陀螺仪原始数据 ±2000°/s
HX, HY, HZ 0x3A-0x3C 磁力计原始数据 -
Roll, Pitch, Yaw 0x3D-0x3F 解算后的角度 ±180°

2.2 数据格式

所有寄存器数据均为 16 位有符号整数 (int16_t),采用小端格式存储。


3. 数据获取与转换

3.1 加速度计 (ACC)

物理意义:测量物体在三个轴向上的加速度,单位为重力加速度 g (1g ≈ 9.8m/s²)。

寄存器读取

int16_t ax_raw = sReg[AX];    // X 轴原始数据
int16_t ay_raw = sReg[AY];    // Y 轴原始数据
int16_t az_raw = sReg[AZ];    // Z 轴原始数据

转换公式

加速度 (g) = 原始值 / 32768 × 16

代码实现

// 方法 1浮点数输出需要启用浮点 printf 支持)
float acc_x = ax_raw / 32768.0f * 16.0f;

// 方法 2定点数输出推荐节省空间
int32_t acc_scaled = (ax_raw * 16 * 1000) / 32768;  // 放大 1000 倍
int32_t acc_int = acc_scaled / 1000;                // 整数部分
int32_t acc_frac = acc_scaled % 1000;               // 小数部分

典型值

  • 静止水平放置时AX≈0, AY≈0, AZ≈1g (1000mg)
  • 加速度计可以用于检测设备的倾斜角度和运动状态

3.2 陀螺仪 (GYRO)

物理意义:测量物体绕三个轴旋转的角速度,单位为度每秒 (°/s 或 dps)。

寄存器读取

int16_t gx_raw = sReg[GX];    // X 轴原始数据
int16_t gy_raw = sReg[GY];    // Y 轴原始数据
int16_t gz_raw = sReg[GZ];    // Z 轴原始数据

转换公式

角速度 (°/s) = 原始值 / 32768 × 2000

代码实现

// 方法 1浮点数输出
float gyro_x = gx_raw / 32768.0f * 2000.0f;

// 方法 2定点数输出推荐
int32_t gyro_scaled = (gx_raw * 2000 * 1000) / 32768;
int32_t gyro_int = gyro_scaled / 1000;
int32_t gyro_frac = gyro_scaled % 1000;

典型值

  • 静止时GX≈0, GY≈0, GZ≈0可能有少量零偏
  • 陀螺仪可以用于检测设备的旋转运动和角振动

注意:陀螺仪存在零漂,长时间积分会产生累积误差,通常需要与加速度计融合使用。


3.3 角度 (ANGLE)

物理意义:传感器通过内部姿态解算算法(互补滤波或卡尔曼滤波)计算出的姿态角,单位为度 (°)。

寄存器读取

int16_t roll_raw = sReg[Roll];    // 横滚角
int16_t pitch_raw = sReg[Pitch];  // 俯仰角
int16_t yaw_raw = sReg[Yaw];      // 航向角

转换公式

角度 (°) = 原始值 / 32768 × 180

代码实现

// 方法 1浮点数输出
float roll = roll_raw / 32768.0f * 180.0f;

// 方法 2定点数输出推荐
int32_t angle_scaled = (roll_raw * 180 * 1000) / 32768;
int32_t angle_int = angle_scaled / 1000;
int32_t angle_frac = angle_scaled % 1000;

角度定义

角度 范围 说明
Roll (横滚角) ±180° 绕 X 轴旋转的角度
Pitch (俯仰角) ±90° 绕 Y 轴旋转的角度
Yaw (航向角) ±180° 绕 Z 轴旋转的角度(电子罗盘)

典型应用

  • Roll/Pitch用于平衡车、云台稳定、姿态控制
  • Yaw用于航向指示、指南针功能

4. 软件架构

4.1 驱动层

User/Sensors/
├── j901p.c/h/reg.h    # 官方 SDK
└── j901p_hal.c/h      # HAL 硬件 I2C 适配层

关键函数

  • J901P_HAL_Init(0x50) - 初始化传感器
  • WitReadReg(AX, 12) - 读取 12 个寄存器AX 到 Yaw
  • WitRegisterCallBack(CopeSensorData) - 注册数据更新回调

4.2 数据读取流程

1. 调用 WitReadReg(AX, 12)
       ↓
2. I2C 读取 12 个寄存器到缓冲区
       ↓
3. 解析数据到 sReg[] 数组
       ↓
4. 触发回调函数 CopeSensorData()
       ↓
5. 设置数据更新标志 s_cDataUpdate
       ↓
6. 主任务读取 sReg[] 并转换

4.3 FreeRTOS 任务

void StartControlTask(void *argument)
{
    // 初始化
    J901P_HAL_Init(0x50);
    WitRegisterCallBack(CopeSensorData);
    
    // 主循环
    for(;;)
    {
        if(s_cDataUpdate)
        {
            WitReadReg(AX, 12);  // 读取数据
            
            // 转换并输出加速度
            if(s_cDataUpdate & 0x01) {
                // 处理加速度数据
            }
            
            // 转换并输出角速度
            if(s_cDataUpdate & 0x02) {
                // 处理陀螺仪数据
            }
            
            // 转换并输出角度
            if(s_cDataUpdate & 0x04) {
                // 处理角度数据
            }
            
            s_cDataUpdate = 0;
            osDelay(200);  // 200ms 采样率
        }
    }
}

5. 数据输出示例

5.1 串口输出格式

ACC: 0.098 0.030 0.968
GYRO: 0.015 -0.023 0.008
ANGLE: 0.125 -0.089 89.992

5.2 数据解读

静止水平放置时

ACC: 0.000 0.000 1.000     # Z 轴为 1gX/Y 轴为 0
GYRO: 0.000 0.000 0.000    # 静止,角速度为 0
ANGLE: 0.000 0.000 0.000   # 水平,角度为 0

倾斜 45 度时

ACC: 0.707 0.000 0.707     # X/Z 轴分量
ANGLE: 45.000 0.000 0.000  # Roll 角 45 度

6. 常见问题

Q1: 数据全为 0

  • 检查 I2C 接线SDA/SCL 是否接反)
  • 检查传感器供电3.3V 或 5V
  • 确认 I2C 地址是否正确(默认 0x50

Q2: 加速度数据异常?

  • 确认传感器安装方向
  • 检查是否有强烈振动
  • 静态时应该有 1g 的重力分量

Q3: 角度漂移?

  • 陀螺仪零漂是正常现象
  • 长时间运行后需要重新校准
  • 可以使用传感器融合算法优化

Q4: 浮点数无法打印?

  • ARM GCC 默认不支持浮点 printf
  • 使用定点数格式(本代码已实现)
  • 或启用浮点支持:-u _printf_float

7. 参考资料


文档版本: v1.0
更新日期: 2026-03-30
作者: CloudPlant Team