STM32 I2C Library for MS5611 temperature and pressure sensor
Please read Liability Disclaimer and License Agreement CAREFULLY
Before going further please read MS5611 datasheet
Usage example
MS5611_Init();
MS5611_read();//get pressure and temperature takes about 10ms ToDo use non blocking mode
printf("Pressure = %f Bar Temperature = %f C\n", MS5611_Val.Pressure/100000.0, MS5611_Val.Temperature/100.0);
MS5611.h
#ifndef __MS5611_I2C_H
#define __MS5611_I2C_H
#ifdef __cplusplus
extern "C" {
#endif
#include "i2c.h"
#define OneByte 1
#define TwoBytes 2
#define ThreeBytes 3
#define MS5611_I2C_ADDR 0xEC
#define CONVERSION_TIME 10 // conversion time in miliseconds
#define MS561101BA_2K 2000
#define MS561101BA_1K5 1500
#define CMD_MS5611_RESET 0x1E
//#define CMD_MS5611_PROM_Setup 0xA0
#define CMD_MS5611_PROM_C1 0xA2
#define CMD_MS5611_PROM_C2 0xA4
#define CMD_MS5611_PROM_C3 0xA6
#define CMD_MS5611_PROM_C4 0xA8
#define CMD_MS5611_PROM_C5 0xAA
#define CMD_MS5611_PROM_C6 0xAC
//#define CMD_MS5611_PROM_CRC 0xAE
#define CMD_MS5611_PRES 0x48 // Maximum resolution (oversampling)
#define CMD_MS5611_TEMP 0x58 // Maximum resolution (oversampling)
#define FIX_TEMP 25
#define CONST_PF 0.1902630958f //(1/5.25588f) Pressure factor
struct _MS5611_msg {
int32_t Pressure;
int32_t Temperature;
};
extern struct _MS5611_msg MS5611_Val;
void MS5611_Init(void);
void MS5611_read(void);
//float MS5611_getAltitude(void); // in meter units
#ifdef __cplusplus
}
#endif
#endif /* __MS5611_I2C_H */
MS5611.c
#include "MS5611_I2C.h"
#include "i2c.h"
#include "gpio.h"
#include <math.h>
struct _MS5611_msg MS5611_Val;
uint16_t C1, C2, C3, C4, C5, C6;
//uint32_t D1, D2;
uint8_t data[3] = {0, 0, 0};
//const float sea_press = 1013.25;
static uint16_t MS5611_read_16bits(uint8_t reg)
{
//if(HAL_I2C_Mem_Read(&hi2c1, MS5611_I2C_ADDR, reg, I2C_MEMADD_SIZE_8BIT, data, TwoBytes, I2C_TIMEOUT)!= HAL_OK)
// printf ("HAL_SPI_TransmitReceive \n");
HAL_I2C_Mem_Read(&hi2c1, MS5611_I2C_ADDR, reg, I2C_MEMADD_SIZE_8BIT, data, TwoBytes, PORT_TIMEOUT);
return ((uint16_t)data[0] << 8) | ((uint16_t)data[1] & 0xFF);
}
static void MS5611_write(uint8_t reg)
{
//if(HAL_I2C_Master_Transmit(&hi2c1, MS5611_I2C_ADDR, ®, OneByte, I2C_TIMEOUT) != HAL_OK)
// printf ("HAL_SPI_Transmit \n");
HAL_I2C_Master_Transmit(&hi2c1, MS5611_I2C_ADDR, ®, OneByte, PORT_TIMEOUT);
}
static uint32_t MS5611_Convert(uint8_t cmd)
{
MS5611_write(cmd);
HAL_Delay(CONVERSION_TIME);
//if(HAL_I2C_Mem_Read(&hi2c1, MS5611_I2C_ADDR, 0x00, I2C_MEMADD_SIZE_8BIT, data, ThreeBytes, I2C_TIMEOUT)!= HAL_OK)
// printf ("HAL_SPI_TransmitReceive \n");
HAL_I2C_Mem_Read(&hi2c1, MS5611_I2C_ADDR, 0x00, I2C_MEMADD_SIZE_8BIT, data, ThreeBytes, PORT_TIMEOUT);
return ((uint32_t)data[0] << 16) | ((uint32_t)data[1] << 8) | ((uint32_t)data[2]);
}
void MS5611_Init(void)
{
MS5611_write(CMD_MS5611_RESET);
HAL_Delay(4);
// We read the factory calibration
// The on-chip CRC is not used
C1 = MS5611_read_16bits(CMD_MS5611_PROM_C1);
C2 = MS5611_read_16bits(CMD_MS5611_PROM_C2);
C3 = MS5611_read_16bits(CMD_MS5611_PROM_C3);
C4 = MS5611_read_16bits(CMD_MS5611_PROM_C4);
C5 = MS5611_read_16bits(CMD_MS5611_PROM_C5);
C6 = MS5611_read_16bits(CMD_MS5611_PROM_C6);
//printf("C1 = %d C2 = %d C3 = %d C4 = %d C5 = %d C6 = %d\n", C1, C2, C3, C4, C5, C6);
}
void MS5611_read(void){
int64_t dT, OFF, SENS, TEMP, T2, OFF2, SENS2, x1, x2;
int32_t D1, D2;
D1 = MS5611_Convert(CMD_MS5611_PRES);//raw press
D2 = MS5611_Convert(CMD_MS5611_TEMP);// raw temp
//printf("D1 = %d D2 = %d\n", D1, D2);
// Difference between actual and reference temperature = D2 - Tref
dT = D2 - ((uint64_t)C5 << 8);
//printf("dT = %llu\n", dT);
// Actual temperature = 2000 + dT * TEMPSENS
TEMP = (int64_t)MS561101BA_2K + ((dT * (int64_t)C6) >> 23);
//Offset at actual temperature
OFF = ((uint32_t)C2 << 16) + ((dT * (int64_t)C4) >> 7);
SENS = ((int64_t)C1 << 15) + (((int64_t)C3 * dT) >> 8);
// Second order temperature compensation
if (TEMP < MS561101BA_2K)
{
x1 = (TEMP - MS561101BA_2K);
x2 = x1 * x1;
T2 = ((dT * dT) >> 31);
OFF2 = ((5 * x2) >> 1);
SENS2 = ((5 * x2) >> 2);
if(TEMP < -1500)
{
x1 = (TEMP + MS561101BA_1K5);
x2 = x1 * x1;
OFF2 += (7 * x2);
SENS2 += ((11 * x2) >> 1);
}
}
else
{
T2 = 0;
OFF2 = 0 ;
SENS2 = 0 ;
}
OFF = OFF - OFF2;
SENS = SENS - SENS2;
// Temperature compensated pressure = D1 * SENS - OFF
MS5611_Val.Temperature = TEMP - T2;
MS5611_Val.Pressure = ((((D1 * SENS) >> 21) - OFF) >> 15);
}
//float MS5611_getAltitude(void) {
// int32_t _p, _t;
// MS5611_read(&_p, &_t);
// printf("P = %f mbar t = %f degC\n", _p/100.0, _t/100.0);
// return ((pow((1015.7f / _p), CONST_PF) - 1.0f) * (FIX_TEMP + 273.15f)) / 0.0065f;
//}
Comments powered by CComment