STM32CubeIDE HAL库IIC实现气压计MS5637的数据读取

目录

一、配置

二、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Ω上拉电阻)。

二、MS5637工作流程

STM32CubeIDE HAL库IIC实现气压计MS5637的数据读取_第1张图片

1、复位

发送0x1E,使芯片复位。

2、读取出厂校准参数

从0xA2开始分别读取6个16bit的参数。

3、开启ADC及转换

有不同的转换精度决定不同的命令,上表OSR=256时,D1传输0x40,D2传输0x50。

转换时间由精度决定,OSR为256时,需要等待约0.52ms。其他等待时间t ≈ OSR / 256 * 0.52ms。

4、读取数据(重复开启和读取,分别得到温度和气压值)

温度数据和气压数据都存在同一个起始位置0x00,24bit数据。

(不同精度读取方法都一样,包括之后的计算方法。只是延迟有所不同)

5、通过参数和数据计算得到标准单位的数据

计算方法:

STM32CubeIDE HAL库IIC实现气压计MS5637的数据读取_第2张图片

 

温度在低于20℃时,还需温度补偿计算:

STM32CubeIDE HAL库IIC实现气压计MS5637的数据读取_第3张图片

三、代码

1. h

#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);

2. c

#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;
}

3.main

#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

你可能感兴趣的:(STM32,嵌入式,stm32,传感器)