目錄
一、配置
在這之前有發過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);
參考: