MS5837低于二十度读数出很大问题高于二十度正常

链接:https://pan.baidu.com/s/1fohFavHqUvHI97hzcdvqlw
提取码:dbtd
复制这段内容后打开百度网盘手机App,操作更方便哦

2 1

移植ARDUINO代码驱动到STM32F103VET6上,逻辑调试都没什么问题,I2C协议也没问题,其他设备地址和其他数据位都是经过推敲后改好了,高于二十度很正常,单一低于二十度就读数出问题。

可以帮忙看代码分析下吗,我直接使用stm32CUBEMX创建的

30Bar 数据读取时的问题

解算需要根据datasheet计算即可,根据温度值,有不一样的解算过程,你需要检查一下。
以下是我写的参考代码:

/**
 * @brief  获取并计算压力值 并进行温度补偿
 *   除法采用移位为了提高计算效率
 *   计算中的(int64_t)强制类型转换为了防止计算数据溢出
 */
void ms5837_cal_pressure(int fd)
{
    int64_t Ti, OFFi, SENSi;
    int64_t dT_squ; // dT的乘方
    uint32_t temp_minus_squ, temp_plus_squ;

    // 获取原始压力数字量
    ms5837->D1_Pres = ms5837_get_conversion(fd, MS583703BA_D1_OSR_8192);
    // 实际温度偏移
    ms5837->OFF = ((int64_t)ms5837->c[2] << 16) + (((int64_t)(ms5837->c[4] * ms5837->dT)) >> 7);
    // 实际温度灵敏度
    ms5837->SENS = ((int64_t)ms5837->c[1] << 15) + (((int64_t)(ms5837->c[3] * ms5837->dT)) >> 8);

    dT_squ = ((int64_t)ms5837->dT * (int64_t)ms5837->dT);           // dT的2次方
    temp_minus_squ = (2000 - ms5837->TEMP) * (2000 - ms5837->TEMP); // 温度差的2次方

    /* 对温度和压力进行二阶修正 (datasheet P8) */
    if (ms5837->TEMP < 2000) // 低温情况:低于20℃时
    {
        Ti = (3 * dT_squ) >> 33;
        OFFi = 3 * temp_minus_squ / 2;
        SENSi = 5 * temp_minus_squ / 8;

        if (ms5837->TEMP < -1500) // 超低温情况:低于-15℃时
        {
            temp_plus_squ = (ms5837->TEMP + 1500) * (ms5837->TEMP + 1500); // 温度和的2次方
            OFFi += 7 * temp_plus_squ;
            SENSi += 4 * temp_plus_squ;
        }
    }
    else // 高温情况:高于20℃时
    {
        Ti = (2 * dT_squ) >> 37;
        OFFi = temp_minus_squ >> 4;
        SENSi = 0;
    }
    ms5837->OFF -= OFFi;
    ms5837->SENS -= SENSi;

    // 温度补偿后的压力值
    ms5837->P = (((ms5837->D1_Pres * ms5837->SENS) >> 21) - ms5837->OFF) >> 13;

    // 实际温度值
    ms5837->temperature = (float)(ms5837->TEMP - Ti) / 100;
    // 实际压力值
    ms5837->pressure = (float)ms5837->P / 10;
    printf("pressure: %f  %.2f", ms5837->pressure, ms5837->temperature);
}