原来的代码
/**
* @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 时:
您的代码执行过程:
-
corrected_data.accel_z_g * 1000 + 0.5= 100.5(浮点数) -
将这个浮点数传入
abs()- 但abs()期望整数参数 -
编译器可能隐式转换:
(int)100.5 = 100 -
abs(100) = 100 -
100 % 1000 = 100✓ 按理应该显示正确
但为什么显示0? 可能是编译器在处理浮点数到整数的隐式转换时出了问题,或者浮点精度导致 100.5 变成了 99.999,取整后变成99。
我的代码执行过程:
-
corrected_data.accel_z_g * 1000.0f + 0.5f= 100.5f -
显式转换为
(int16_t)100.5f= 100(四舍五入正确) -
accel_z_mg = 100 -
accel_z_mg / 1000 = 0 -
abs(accel_z_mg) % 1000 = 100 -
打印 “0.100 g” ✓
总结
您的代码逻辑上是正确的,但可能因为:
-
隐式类型转换的问题
-
浮点数精度损失
-
编译器优化导致的问题