LOADING

加载过慢请开启缓存 浏览器默认开启

解决mpu6050打印z轴数据出现0.000

2026/3/2

原来的代码

/**
 * @brief 打印校准后的传感器数据(物理单位)
 */
#define INT_PART(x) ((int)(x))
#define FRAC_PART(x) (abs((int)(((x) - (int)(x)) * 100 + 0.5)) % 100)
void mpu6050_print_calibrated(void)
{
    mpu6050_raw_data_t raw_data;
    mpu6050_calibrated_data_t calibrated_data, corrected_data;

    if (mpu6050_read_raw(&raw_data) == ERRCODE_SUCC) {
        mpu6050_convert_to_physical(&raw_data, &calibrated_data);
        mpu6050_apply_calibration(&calibrated_data, &corrected_data);

        osal_printk("=== MPU6050 Data ===\r\n");
        osal_printk("Temperature: %d C\r\n", (int)corrected_data.temperature_c);
        osal_printk("Accel: X=%d.%03d g, Y=%d.%03d g, Z=%d.%03d g\r\n",
                   (int)corrected_data.accel_x_g, (int)(abs(corrected_data.accel_x_g * 1000 + 0.5) % 1000),
                   (int)corrected_data.accel_y_g, (int)(abs(corrected_data.accel_y_g * 1000 + 0.5) % 1000),
                   (int)corrected_data.accel_z_g, (int)(abs(corrected_data.accel_z_g * 1000 + 0.5) % 1000));
        osal_printk("Gyro: X=%d.%02d dps, Y=%d.%02d dps, Z=%d.%02d dps\r\n\r\n",
                    INT_PART(corrected_data.gyro_x_dps), FRAC_PART(corrected_data.gyro_x_dps),
                    INT_PART(corrected_data.gyro_y_dps), FRAC_PART(corrected_data.gyro_y_dps),
                    INT_PART(corrected_data.gyro_z_dps), FRAC_PART(corrected_data.gyro_z_dps));
        osal_printk("====================\r\n");
    }
}

修改后的代码

void mpu6050_print_calibrated(mpu6050_calibrated_data_t *corrected_data)
{
    // 将浮点数转换为整数(毫g单位和百分度每秒)
    int16_t accel_x_mg = (int16_t)(corrected_data->accel_x_g * 1000 + 0.5f);
    int16_t accel_y_mg = (int16_t)(corrected_data->accel_y_g * 1000 + 0.5f);
    int16_t accel_z_mg = (int16_t)(corrected_data->accel_z_g * 1000 + 0.5f);

    int16_t gyro_x_cdps = (int16_t)(corrected_data->gyro_x_dps * 100 + 0.5f); // 百分度每秒
    int16_t gyro_y_cdps = (int16_t)(corrected_data->gyro_y_dps * 100 + 0.5f);
    int16_t gyro_z_cdps = (int16_t)(corrected_data->gyro_z_dps * 100 + 0.5f);

    osal_printk("=== MPU6050 Data ===\r\n");
    osal_printk("Temperature: %d C\r\n", (int)corrected_data->temperature_c);

    // 打印加速度计(单位:g)
    osal_printk("Accel: X=%d.%03d g, Y=%d.%03d g, Z=%d.%03d g\r\n", accel_x_mg / 1000, abs(accel_x_mg) % 1000,
                accel_y_mg / 1000, abs(accel_y_mg) % 1000, accel_z_mg / 1000, abs(accel_z_mg) % 1000);

    // 打印陀螺仪(单位:dps)
    osal_printk("Gyro: X=%d.%02d dps, Y=%d.%02d dps, Z=%d.%02d dps\r\n", gyro_x_cdps / 100, abs(gyro_x_cdps) % 100,
                gyro_y_cdps / 100, abs(gyro_y_cdps) % 100, gyro_z_cdps / 100, abs(gyro_z_cdps) % 100);

    osal_printk("====================\r\n\r\n");
}

 
  貌似两个代码都是同一个AI生成的。。
 

AI总结:

您的原代码:

#define INT_PART(x) ((int)(x))
#define FRAC_PART(x) (abs((int)(((x) - (int)(x)) * 100 + 0.5)) % 100)

osal_printk("Accel: X=%d.%03d g, Y=%d.%03d g, Z=%d.%03d g\r\n",
           (int)corrected_data.accel_x_g, (int)(abs(corrected_data.accel_x_g * 1000 + 0.5) % 1000),
           (int)corrected_data.accel_y_g, (int)(abs(corrected_data.accel_y_g * 1000 + 0.5) % 1000),
           (int)corrected_data.accel_z_g, (int)(abs(corrected_data.accel_z_g * 1000 + 0.5) % 1000));

我的新代码:

int16_t accel_z_mg = (int16_t)(corrected_data->accel_z_g * 1000.0f + 0.5f);
osal_printk("Accel: X=%d.%03d g, Y=%d.%03d g, Z=%d.%03d g\r\n",
           accel_x_mg / 1000, abs(accel_x_mg) % 1000,
           accel_y_mg / 1000, abs(accel_y_mg) % 1000,
           accel_z_mg / 1000, abs(accel_z_mg) % 1000);

关键区别:

1. 运算顺序和精度

  • 您的代码:在格式化字符串中直接计算,每次打印都重新计算

  • 我的代码:先计算好整数结果,再打印

2. 数值稳定性

  • 您的代码corrected_data.accel_z_g * 1000 + 0.5 中的 corrected_data.accel_z_g 是浮点数,直接用在 abs()

  • 我的代码:先将浮点数转换为整数,后续全部用整数运算

3. 类型转换

  • 您的代码abs(corrected_data.accel_z_g * 1000 + 0.5) - abs() 是整数函数,但传入的是浮点数表达式

  • 我的代码abs(accel_z_mg) - accel_z_mg 已经是整数

4. 问题所在

corrected_data.accel_z_g = 0.1000 时:

您的代码执行过程

  1. corrected_data.accel_z_g * 1000 + 0.5 = 100.5(浮点数)

  2. 将这个浮点数传入 abs() - 但 abs() 期望整数参数

  3. 编译器可能隐式转换:(int)100.5 = 100

  4. abs(100) = 100

  5. 100 % 1000 = 100 ✓ 按理应该显示正确

但为什么显示0? 可能是编译器在处理浮点数到整数的隐式转换时出了问题,或者浮点精度导致 100.5 变成了 99.999,取整后变成99。

我的代码执行过程

  1. corrected_data.accel_z_g * 1000.0f + 0.5f = 100.5f

  2. 显式转换为 (int16_t)100.5f = 100(四舍五入正确)

  3. accel_z_mg = 100

  4. accel_z_mg / 1000 = 0

  5. abs(accel_z_mg) % 1000 = 100

  6. 打印 “0.100 g” ✓

总结

您的代码逻辑上是正确的,但可能因为:

  1. 隐式类型转换的问题

  2. 浮点数精度损失

  3. 编译器优化导致的问题

问答