目录
一、配置
二、MS5637工作流程
1、复位
2、读取出厂校准参数
3、开启ADC及转换
4、读取数据(重复开启和读取,分别得到温度和气压值)
5、通过参数和数据计算得到标准单位的数据
三、代码
1. h
2. c
3.main
在这之前有发过IIC的博客,见:STM32CubeIDE HAL库操作IIC (一)配置篇
MX的配置方法同该篇,此次没有用到中断和DMA。(MS5637最高支持400KHz的速率)
MS5637的IIC通信模式与MPU6050等读写寄存器方法不同,部分操作不需读写寄存器。
MS5637的SCK和SDA两引脚需要外部上拉电阻(本人用的3.3V电源,4.7KΩ上拉电阻)。
发送0x1E,使芯片复位。
从0xA2开始分别读取6个16bit的参数。
有不同的转换精度决定不同的命令,上表OSR=256时,D1传输0x40,D2传输0x50。
转换时间由精度决定,OSR为256时,需要等待约0.52ms。其他等待时间t ≈ OSR / 256 * 0.52ms。
温度数据和气压数据都存在同一个起始位置0x00,24bit数据。
(不同精度读取方法都一样,包括之后的计算方法。只是延迟有所不同)
计算方法:
温度在低于20℃时,还需温度补偿计算:
#include "main.h"
#define MS5637_WriteAddr 0xec
#define MS5637_ReadAddr 0xed
#define MS5637_CMD_RES 0x1E//复位
#define MS5637_CMD_PresConv_256 0x40//气压ADC转换
#define MS5637_CMD_TempConv_256 0x50//温度ADC转换
#define MS5637_CMD_PresConv_8192 0x4A//气压ADC转换
#define MS5637_CMD_TempConv_8192 0x5A//温度ADC转换
#define MS5637_C1_REG_H 0xA2
#define MS5637_C2_REG_H 0xA4
#define MS5637_C3_REG_H 0xA6
#define MS5637_C4_REG_H 0xA8
#define MS5637_C5_REG_H 0xAA
#define MS5637_C6_REG_H 0xAC
#define MS5637_data_REG_H 0x00
extern uint16_t C1,C2,C3,C4,C5,C6;
extern uint32_t D1,D2;
extern float cTemp,fTemp,pressure;
void MS5637_INIT(void);
void MS5637_Calculate_Val(void);
void GetPressandTemp(void);
#include "main.h"
#include "ms5637.h"
#include "i2c.h"
uint8_t TBuff[1];
uint8_t RBuff[3];
float cTemp,fTemp,pressure;
uint16_t C1,C2,C3,C4,C5,C6;
uint32_t D1,D2;
uint8_t HALIIC_ReadMultByteFromSlave(uint8_t dev, uint8_t reg, uint8_t length, uint8_t *data)
{
return HAL_I2C_Mem_Read(&hi2c1, dev, reg, I2C_MEMADD_SIZE_8BIT, data, length, 200);
}
void MS5637_INIT(void)
{
// 0x1E(30) Reset command
TBuff[0]=MS5637_CMD_RES;
HAL_I2C_Master_Transmit(&hi2c1,MS5637_WriteAddr,TBuff,1,100);
HAL_Delay(1);
// Read 12 bytes of calibration data
// Read pressure sensitivity
HALIIC_ReadMultByteFromSlave(MS5637_ReadAddr,MS5637_C1_REG_H,2,RBuff);
C1 = RBuff[0] * 256 + RBuff[1];
// Read pressure offset
HALIIC_ReadMultByteFromSlave(MS5637_ReadAddr,MS5637_C2_REG_H,2,RBuff);
C2 = RBuff[0] * 256 + RBuff[1];
// Read temperature coefficient of pressure sensitivity
HALIIC_ReadMultByteFromSlave(MS5637_ReadAddr,MS5637_C3_REG_H,2,RBuff);
C3 = RBuff[0] * 256 + RBuff[1];
// Read temperature coefficient of pressure offset
HALIIC_ReadMultByteFromSlave(MS5637_ReadAddr,MS5637_C4_REG_H,2,RBuff);
C4 = RBuff[0] * 256 + RBuff[1];
// Read reference temperature
HALIIC_ReadMultByteFromSlave(MS5637_ReadAddr,MS5637_C5_REG_H,2,RBuff);
C5 = RBuff[0] * 256 + RBuff[1];
// Read temperature coefficient of the temperature
HALIIC_ReadMultByteFromSlave(MS5637_ReadAddr,MS5637_C6_REG_H,2,RBuff);
C6 = RBuff[0] * 256 + RBuff[1];
}
void GetPressandTemp(void)
{
// 0x1E(30) Reset command
TBuff[0]=MS5637_CMD_RES;
HAL_I2C_Master_Transmit(&hi2c1,MS5637_WriteAddr,TBuff,1,100);
HAL_Delay(1);
// 0x4A(74) Pressure conversion(OSR = 8192) command
TBuff[0]=MS5637_CMD_PresConv_8192;
HAL_I2C_Master_Transmit(&hi2c1,MS5637_WriteAddr,TBuff,1,100);
HAL_Delay(17);
// Read digital pressure value
// Read data back from 0x00(0), 3 bytes
// D1 MSB2, D1 MSB1, D1 LSB
HALIIC_ReadMultByteFromSlave(MS5637_ReadAddr,MS5637_data_REG_H,3,RBuff);
D1 = RBuff[0] * 65536 + RBuff[1] * 256 + RBuff[2];
// MS5637_02BA03 address, 0x76(118)
// 0x5A(74) Temperature conversion(OSR = 8192) command
TBuff[0]=MS5637_CMD_TempConv;
HAL_I2C_Master_Transmit(&hi2c1,MS5637_WriteAddr,TBuff,1,100);
HAL_Delay(17);
// Read digital temperature value
// Read data back from 0x00(0), 3 bytes
// D2 MSB2, D2 MSB1, D2 LSB
HALIIC_ReadMultByteFromSlave(MS5637_ReadAddr,MS5637_data_REG_H,3,RBuff);
D2 = RBuff[0] * 65536 + RBuff[1] * 256 + RBuff[2];
}
void MS5637_Calculate_Val(void)
{
int32_t dT;
float TEMP,k,T2;
int64_t OFF,SENS,OFF2,SENS2;
dT = D2 - C5 * 256;
TEMP = 2000 + (float)dT / 2048 * ((float)C6 / 4096);
OFF =(int64_t)C2 * 131072 + (int64_t)((double)C4 / 64 * dT );
SENS =(int64_t)C1 * 65536 + (int64_t)((double)C3 / 128 * dT );
T2 = 0;
OFF2 = 0;
SENS2 = 0;
if (TEMP > 2000)
{
k = ((float)dT /524288);//2^19
T2 = (5 * k * k);
OFF2 = 0;
SENS2 = 0;
}
else if (TEMP < 2000 )
{
k = (float)dT / 65536 ;
T2 = (1.5 * k * k);
OFF2 = (int64_t)(61 * ((float)(TEMP - 2000) * (TEMP - 2000)) / 16);
SENS2 = (int64_t)(29 * ((float)(TEMP - 2000) * (TEMP - 2000)) / 16);
if (TEMP < -1500)
{
OFF2 = OFF2 + 17 * ((float)(TEMP + 1500) * (TEMP + 1500));
SENS2 = SENS2 + 9 * ((float)(TEMP + 1500) * (TEMP +1500));
}
}
TEMP = TEMP - T2;
OFF = OFF - OFF2;
SENS = SENS - SENS2;
pressure = (float)((((double)(D1 * SENS) / 2097152) - OFF) / 32768.0)/100.0;
cTemp = (float)(TEMP / 100.0);
fTemp = cTemp * 1.8 + 32;
}
#include "ms5637.h"
MS5637_INIT();
printf("C1 %d,C2 %d,C3 %d,C4 %d,C5 %d,C6 %d\r\n",C1,C2,C3,C4,C5,C6);
GetPressandTemp();
printf("D1 %d,D2 %d\r\n",D1,D2);
MS5637_Calculate_Val();
printf("Pressure : %.2f mbar\r\n",pressure);
printf("Temperature in Celsius : %.2f C\r\n",cTemp);
printf("Temperature in Fahrenheit : %.2f F\r\n",fTemp);
参考:
GitHub - ControlEverythingCommunity/MS5637-02BA03