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工作流程

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、通過參數和數據計算得到標準單位的數據

計算方法:

 

溫度在低於20℃時,還需溫度補償計算:

三、代碼

1. h<MS5637.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<MS5637.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<main.c>

#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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章