版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
文章目录
一、MS5837-30BA相关介绍
1.技术参数
- 陶瓷-金属封装,3.3 x 3.3 x 2.75 mm
- 高分辨率模块,0.2 mbar (1mbar = 100pa)
- 快速转换可达 0.5 ms
- 低功率,0.6 µA(25°C 时待机功率 < 0.1 µA)
- 集成式数字压力传感器(24 位 ΔΣ ADC)
- 电源电压:1.5 至 3.6 V
- I2C 接口,地址:1110110x( Write:x = 0,Read:1 = x)
- 量程:0-30Bar(0-3Mpa)
- 水深分辨率:2mm
2.典型应用电路
3.PROM中的标定参数
每一个模块都是工厂在两种温度和两种压力下单独校准的。结果是6个系数必要的补偿过程变化和温度变化是计算和存储在112-bit每个模块的位PROM。MS5837-30BA包含一个112位的PROM存储器。实现了一个4位CRC来检查数据有效性,在内存中这些位(划分为6个系数C1到C6)必须由单片机软件,并在程序中将D1和D2转换成补偿压力和温度的值。系数C0表示工厂配置和CRC。
C0 CRC 与 工厂配置
C1 压力灵敏度 SENS|T1
C2 压力补偿 OFF|T1
C3 温度压力灵敏度系数 TCS
C4 温度系数的压力补偿 TCO
C5 参考温度 T|REF
C6 温度系数的温度 TEMPSENS
二、MS5837-30BA数据解算
1.解算流程图
2.初始化读取标定参数并进行CRC校验
①MS5837复位
/**
* @brief MS583703BA 复位
* @param None
* @retval None
*/
void MS583703BA_RESET(void)
{
IIC_Start();
IIC_Send_Byte(MS583703BA_SlaveAddress);//CSB接地,主机地址:0XEE,否则 0X77
IIC_Wait_Ack();
IIC_Send_Byte(MS583703BA_RST);//发送复位命令
IIC_Wait_Ack();
IIC_Stop();
}
②MS5837 CRC4-bit 校验官方示例
/**
* @brief MS5837_CRC4校验(4bit校验)【官方数据手册提供】
* @param MS5837 PROM标定参数数组
* @retval 返回CRC校验码
*/
unsigned char MS5837_CRC4(unsigned int n_prom[]) // n_prom defined as 8x unsigned int (n_prom[8])
{
int cnt; // simple counter
unsigned int n_rem=0; // crc remainder
unsigned char n_bit;
n_prom[0]=((n_prom[0]) & 0x0FFF); // CRC byte is replaced by 0
n_prom[7]=0; // Subsidiary value, set to 0
for (cnt = 0; cnt < 16; cnt++) // operation is performed on bytes
{ // choose LSB or MSB
if (cnt%2==1) n_rem ^= (unsigned short) ((n_prom[cnt>>1]) & 0x00FF);
else n_rem ^= (unsigned short) (n_prom[cnt>>1]>>8);
for (n_bit = 8; n_bit > 0; n_bit--)
{
if (n_rem & (0x8000)) n_rem = (n_rem << 1) ^ 0x3000;
else n_rem = (n_rem << 1);
}
}
n_rem= ((n_rem >> 12) & 0x000F); // final 4-bit remainder is CRC code
return (n_rem ^ 0x00);
}
③MS5837初始化 读取标定参数
/**
* @brief MS5837_Init
* @param None
* @retval 返回MS5837初始化是否成功标志:1成功,0失败
*/
u8 MS5837_Init(void)
{
u8 inth,intl,i;
u8 CRC_Check = 0;
for (i=0;i<=6;i++)
{
IIC_Start();
IIC_Send_Byte(MS583703BA_SlaveAddress);
IIC_Wait_Ack();
IIC_Send_Byte(0xA0 + (i*2));
IIC_Wait_Ack();
IIC_Stop();
rt_hw_us_delay(5);
IIC_Start();
IIC_Send_Byte(MS583703BA_SlaveAddress+0x01); //进入接收模式
rt_hw_us_delay(1);
IIC_Wait_Ack();
inth = IIC_Read_Byte(1); //带ACK的读数据
rt_hw_us_delay(1);
intl = IIC_Read_Byte(0); //最后一个字节NACK
IIC_Stop();
Cal_C[i] = (((uint16_t)inth << 8) | intl);
rt_kprintf("Cal_C[%d]:%d\r\n",i,Cal_C[i]);
}
CRC_Check = (u8)((Cal_C[0]&0xF000)>>12);
rt_kprintf("CRC:%d CRC_Check:%d\r\n",MS5837_CRC4(Cal_C),CRC_Check);
if(CRC_Check == MS5837_CRC4(Cal_C)){
return true;
}
else {return false;}
}
3.标定参数软件补偿并解算数据
①MS5837压力参数补偿
//压力补偿参数
OFF_=(uint32_t)Cal_C[2]*65536+((uint32_t)Cal_C[4]*dT)/128;//压力补偿参数
SENS=(uint32_t)Cal_C[1]*32768+((uint32_t)Cal_C[3]*dT)/256;
②MS5837温度转换
/**
* @brief MS583703BA转换温度结果
* @param None
* @retval None
*/
void MS583703BA_getTemperature(void)
{
D2_Temp = MS583703BA_getConversion(MS583703BA_D2_OSR_2048);//4096 出现周期性尖峰(300+)
dT=D2_Temp - (((uint32_t)Cal_C[5])*256);
MS_TEMP=2000+dT*((uint32_t)Cal_C[6])/8388608; //问题在于此处没有出现负号
}
③MS5837气压转换
/**
* @brief MS583703BA转换气压结果
* @param None
* @retval None
*/
void MS583703BA_getPressure(void)
{
D1_Pres= MS583703BA_getConversion(MS583703BA_D1_OSR_8192);//2048
OFF_=(uint32_t)Cal_C[2]*65536+((uint32_t)Cal_C[4]*dT)/128;
SENS=(uint32_t)Cal_C[1]*32768+((uint32_t)Cal_C[3]*dT)/256;
if(MS_TEMP<2000) // LOW Temperature
{
Aux = (2000-MS_TEMP)*(2000-MS_TEMP);
T2 = 3*(dT*dT) /0x80000000;
OFF2 = (uint32_t)1.5*Aux;
SENS2 = 5*Aux/8;
OFF_ = OFF_ - OFF2;
SENS = SENS - SENS2;
}
else{
Aux = (2000-MS_TEMP)*(2000-MS_TEMP);
T2=2*(dT*dT)/137438953472;
OFF2 = 1*Aux/16;
SENS2 = 0;
OFF_ = OFF_ - OFF2;
SENS = SENS - SENS2;
}
MS5837_Pressure = ((D1_Pres*SENS/2097152-OFF_)/8192)/10;
MS_TEMP = (MS_TEMP-T2)/100;
}
3.压力测试
-
高于20摄氏度测试
-
不知道为何 温度转换精度超过2048,温度会出现周期性脉冲尖峰,从而导致气压数据异常(还未找到原因)
-
气压转换精度超过4096,气压数据非常大并且数据不变
-
最后确定 温度精度为2048,气压精度为4096,数据测试正常 ,测试温度区间:4-50℃
-
以上问题已经解决,可能是之前 连线不稳定,后面直接接在板子上,以精度8192可以正常读取数据。