链接:https://pan.baidu.com/s/1fohFavHqUvHI97hzcdvqlw
提取码:dbtd
复制这段内容后打开百度网盘手机App,操作更方便哦
移植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);
}