STM32 Cube BMP180 获取温度、气压、海拔

一. 介绍

BMP180中内置有E2PROM,所以要获取数据,就要使用I2C读写E2PROM来实现获取数据!

BMP180的整个流程: 

 

1. 首先要初始化,读取几个E2PROM地址上的值共11个,用于温度和气压的计算

2. 读温度:

        (1)使用:0xEE 写入操作,向地址:0xF4 ,数据: 0x2E 。 表示:我要读温度啦

        (2) 等待 5ms 

        (3)使用:0xEF 读取操作,从0xF6,0xF7 上读取:温度未转化值

3. 读气压

        (1)使用:0xEE 写入操作,向地址:0xF4 ,数据: 0xF4 。 表示:我要读气压啦

        (2) 等待 26 ms

        (3)使用:0xEF 读取操作,从0xF6,0xF7,0xF8 上读取:气压未转化值

       

这个表里:标注了 oss,  延迟时间,写入的数据字

4. 对初始化的11个数据和读取到的值进行数据运算,从而获取到温度,气压,海拔等参数

这里既然使用 E2PROM,我们就直接用 HAL库的,HAL_I2C_Mem_Write ,HAL_I2C_Mem_Read就能实现数据的读取和写入

二. 源码:

#include "main.h"
#include "i2c.h"
#include "usart.h"
#include "gpio.h"
#include "stdio.h"
#include "math.h"


//BMP180
uint16_t BMP180_ADDR_W = 0xEE; // 气压传感器的写
uint16_t BMP180_MADDR_W= 0xF4; //写入的地址
uint16_t BMP180_CMD_WD = 0x2E; //温度,需要延迟4.5ms
uint16_t BMP180_CMD_QY = 0xF4;  //气压,需要延迟25.5ms
int osrs = 3;
uint16_t BMP180_ADDR_R = 0xEF; // 读,后的内容为 (MSB - 高位, LSB 低位 )
uint16_t BMP180_MADDR_R = 0xF6;  // 读 F6,F7 2位
//BMP初始化
uint16_t BMP180_AC_BE = 0xAA; //从AA ~ BE
//定义BMP初始化变量
typedef struct {
	int16_t AC1;
	int16_t AC2;
	int16_t AC3;
	uint16_t AC4;
	uint16_t AC5;
	uint16_t AC6;
	int16_t B1;
	int16_t B2;
	int16_t MB;
	int16_t MC;
	int16_t MD;
	int32_t B5;
} BMP180_Calibration_TypeDef;
BMP180_Calibration_TypeDef BMP180_Calibration;



//485发送
void send485(uint8_t *pData,uint8_t len){
	// 485
	//接收:DE为0,RE为0,设置为接收
	//发送:DE为1,RE为 1,设置为发送

	//设置为发送
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET); //PB0 = DE = 1
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET); //PB1 = RE = 1
	//发送内容
	HAL_UART_Transmit(&huart3, pData, len, 1000);
	//重置为接收
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); //PB0 = DE = 0
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET); //PB1 = RE = 0
}


/** I2C气压读取 **/
//初始化所有默认值
void BMP180_Init()
{
	uint8_t buffer[22];
	HAL_I2C_Mem_Read(&hi2c1, BMP180_ADDR_R, BMP180_AC_BE, I2C_MEMADD_SIZE_8BIT, (uint8_t *)buffer, 22, 3000);
	BMP180_Calibration.AC1 = (buffer[0]  << 8) | buffer[1];
	BMP180_Calibration.AC2 = (buffer[2]  << 8) | buffer[3];
	BMP180_Calibration.AC3 = (buffer[4]  << 8) | buffer[5];
	BMP180_Calibration.AC4 = (buffer[6]  << 8) | buffer[7];
	BMP180_Calibration.AC5 = (buffer[8]  << 8) | buffer[9];
	BMP180_Calibration.AC6 = (buffer[10]  << 8) | buffer[11];
	BMP180_Calibration.B1 = (buffer[12]  << 8) | buffer[13];
	BMP180_Calibration.B2 = (buffer[14]  << 8) | buffer[15];
	BMP180_Calibration.MB = (buffer[16]  << 8) | buffer[17];
	BMP180_Calibration.MC = (buffer[18]  << 8) | buffer[19];
	BMP180_Calibration.MD =(buffer[20]  << 8) | buffer[21];
}
//温度计算
int16_t BMP180_Calc_WD(uint16_t UT)
{
	BMP180_Calibration.B5  = (((int32_t)UT - (int32_t)BMP180_Calibration.AC6) * (int32_t)BMP180_Calibration.AC5) >> 15;
	BMP180_Calibration.B5 += ((int32_t)BMP180_Calibration.MC << 11) / (BMP180_Calibration.B5 + BMP180_Calibration.MD);
	return (BMP180_Calibration.B5 + 8) >> 4;
}
//气压计算
int32_t BMP180_Calc_QY(uint32_t UP, uint8_t oss)
{
	int32_t B3,B6,X3,p;
	uint32_t B4,B7;

	B6 = BMP180_Calibration.B5 - 4000;
	X3 = ((BMP180_Calibration.B2 * ((B6 * B6) >> 12)) >> 11) + ((BMP180_Calibration.AC2 * B6) >> 11);
	B3 = (((((int32_t)BMP180_Calibration.AC1) * 4 + X3) << oss) + 2) >> 2;
	X3 = (((BMP180_Calibration.AC3 * B6) >> 13) + ((BMP180_Calibration.B1 * ((B6 * B6) >> 12)) >> 16) + 2) >> 2;
	B4 = (BMP180_Calibration.AC4 * (uint32_t)(X3 + 32768)) >> 15;
	B7 = ((uint32_t)UP - B3) * (50000 >> oss);
	if (B7 < 0x80000000) p = (B7 << 1) / B4; else p = (B7 / B4) << 1;
	p = p + (((((p >> 8) * (p >> 8) * 3038) >> 16) + ((-7357 * p) >> 16) + 3791) >> 4);
	return p;
}
//海拔计算
int32_t BMP180_Calc_HB(int32_t Pa)
{
	return 44330 * (1 - pow( Pa/ 101325.0f, 1.0f / 5.255f));
}

//读取值
void BMP180_Value()
{
	uint8_t wddata[2];
	uint8_t qydata[3];

	//先读温度
	HAL_I2C_Mem_Write(&hi2c1, BMP180_ADDR_W, BMP180_MADDR_W, I2C_MEMADD_SIZE_8BIT, (uint8_t *)&BMP180_CMD_WD, 1, 1000);
	HAL_Delay(5);//5ms
	HAL_I2C_Mem_Read(&hi2c1, BMP180_ADDR_R, BMP180_MADDR_R, I2C_MEMADD_SIZE_8BIT, (uint8_t *)wddata, 2, 1000);

	//再读气压
	HAL_I2C_Mem_Write(&hi2c1, BMP180_ADDR_W, BMP180_MADDR_W, I2C_MEMADD_SIZE_8BIT, (uint8_t *)&BMP180_CMD_QY, 1, 1000);
	HAL_Delay(26);//26ms
	HAL_I2C_Mem_Read(&hi2c1, BMP180_ADDR_R, BMP180_MADDR_R, I2C_MEMADD_SIZE_8BIT, (uint8_t *)qydata, 3, 1000);

	//做一下温度计算
	uint16_t UT = (wddata[0]<<8 ) | wddata[1];
	uint16_t temperature = BMP180_Calc_WD(UT);
	uint8_t tem[2];
	tem[0] = (temperature >> 8)&0xff;
	tem[1] = temperature &0xff;
	//发送到485
	send485((uint8_t *)tem, 2);
	HAL_Delay(200);
	//做气压运算
	uint32_t UP = (qydata[0] << 16) | (qydata[1] <<8) | qydata[2] >> (8 - osrs);
	uint32_t pressure = BMP180_Calc_QY(UP,osrs); //气压值
	uint8_t pre[4];
	pre[0] = pressure >> 24;
	pre[1] = (pressure >> 16)&0xff;
	pre[2] = (pressure >> 8)&0xff;
	pre[3] = pressure &0xff ;
	send485((uint8_t *)pre, 4);
	HAL_Delay(200);
	//计算海拔
	uint32_t high = BMP180_Calc_HB(pressure);
	uint8_t hi[4];
	hi[0] = high >> 24;
	hi[1] = (high >> 16)&0xff;
	hi[2] = (high >> 8)&0xff;
	hi[3] = high &0xff ;
	send485((uint8_t *)hi, 4);
	HAL_Delay(200);
}

int main(void)
{
  
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_I2C1_Init();
  MX_USART3_UART_Init();

  BMP180_Init();
  while (1)
  {
	BMP180_Value();
	HAL_Delay(5000);
  }
}

三.演示效果:

1次共收到3行数据:

第一行:温度 ,0147(H) = 32.7℃

第二行:气压 ,17FFA = 982.99 hpa

第三行:海拔 , 00 FF = 255 m 

感谢您的支持,写的文章如对您有所帮助,开源不易,请您打赏,谢谢啦~

 

  • 6
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 14
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值