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

  • 6
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
相关TE 样品申请链接: https://url.eefocus.com/tetg3 相关TE 解决方案资料下载链接: https://url.eefocus.com/tetg2 概述 TE Connectivity的Measurement Specialties Weather Shield开发套件可提供必要的硬件,将下列传感器连接到任何利用Arduino/Genuino兼容扩展端口进行I2C通信的系统: HTU21D数字相对湿度传感器 MS5637数字大气压力传感器 TSYS01数字温度传感器 MS8607数字相对湿度和数字压力传感器 TSD305-1C55数字热电堆传感器 有64个插头孔焊盘,能够用于焊接外部器件,然后插在主板上进行测试。 原理图 板载 独立的压力、湿度和温度传感器 TE Connectivity Measurement Specialties HTU21D 的工作电压范围是1.5V至3.6V。MS8607非常适合用于嵌入紧凑型器件的气象站应用以及需要压力、湿度和温度监测的任何应用。 独立的压力和温度传感器 TE Connectivity Measurement Specialties MS5637 的工作电压范围是1.5V至3.6V。该传感器模块包括一个高线性度压力传感器和一个超低功耗24位Δ-Σ ADC,具有内部工厂校准系数。 独立的压力、湿度和温度传感器 TE Connectivity Measurement Specialties MS8607的工作电压范围是1.5V至3.6V。MS8607非常适合用于嵌入紧凑型器件的气象站应用以及需要压力、湿度和温度监测的任何应用。 独立的温度传感器 - TE Connectivity Measurement Specialties TSYS01 的工作电压范围是2.2V至3.6V。TSY01具有适用于功率敏感型应用的低功耗待机模式。 Arduino / Genuino库和示例源代码 https://github.com/TEConnectivity/Weather_Shield_Arduino_Library 相关产品 Arduino Zero开发板是由UNO平台衍生而来的32位扩展版本,旨在用于智能物联网设备、可穿戴技术等领域的创新型项目。Zero开发板具备更高的性能,并可用作出色的教学工具,用于学习如何开发32位应用程序。该开发板由Atmel SAMD21 MCU供电,其配备32位ARM CortexM0+内核。Atmel的嵌入式调试器 (EDBG) 设有完整的调试接口,无需其他硬件即可轻松进行软件调试。EDBG还支持虚拟的COM端口,可用于为设备编程,并具有引导加载功能。 Arduino INDUSTRIAL 101是一款用于Arduino 101 LGA模块的评估板,在基板上集成有ATmega32u4微控制器。该模块支持基于OpenWRT(名为LininoOS)的Linux发行版。该开发板还具有一个内置型WiFi(IEEE 802.11b/g/n工作速度高达150Mbps 1x1 2.4 GHz)和3个GPIO引脚(其中2个用作PWM输出)。该评估板的引脚排针上还设有4路模拟输入、USB和以太网信号,此外,还内置有一个直流/直流转换器。 Arduino UNO 第 3 次修订版微控制器板基于 Atmel ATmega328 8 位微控制器 (MCU),可用于连接 MEAS 天气扩展板。Arduino Uno 具有14个数字输入/输出引脚(其中六个可用作PWM输出)、6 路模拟输入和一个 16MHz石英晶体振荡器。UNO还包含一个USB接口、一个电源插孔、一个在线串行编程 (ICSP) 排针和一个复位按钮。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值