加入星计划,您可以享受以下权益:

  • 创作内容快速变现
  • 行业影响力扩散
  • 作品版权保护
  • 300W+ 专业用户
  • 1.5W+ 优质创作者
  • 5000+ 长期合作伙伴
立即加入

嵌入式外设-BMP280 压强/温度/海拔 读取(BMP280)驱动代码

16小时前
152
服务支持:
技术交流群

完成交易后在“购买成功”页面扫码入群,即可与技术大咖们分享疑惑和经验、收获成长和认同、领取优惠和红包等。

虚拟商品不可退

当前内容为数字版权作品,购买后不支持退换且无法转移使用。

加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论
放大
实物图
相关方案
  • 方案介绍
    • 一、前言
    • 二、简介
    • 三、资料获取
    • 四、设备使用
    • 四、代码编写
    • 五、参考
  • 相关文件
  • 相关推荐
  • 电子产业图谱
申请入驻 产业图谱

一、前言

BMP280 是一款由 Bosch Sensortec 生产的小型、高精度的气压和温度传感器,广泛应用于环境监测、天气预报、室内外导航、无人机飞行控制、物联网设备等领域。它是继 BMP180BMP183 之后的下一代气压传感器,性能更高,功耗更低。

二、简介

主要特性

  1. 气压传感器
    • 测量范围:300 至 1100 hPa(百帕,单位用于衡量气压的标准单位)。
    • 分辨率:最小可达 1 Pa(帕斯卡)。
    • 精度:±1 hPa(气压精度)。
    • 适合用于气压计、气象站和高度计等设备中。
  2. 温度传感器
    • 测量范围:-40°C 至 +85°C。
    • 精度:±1.0°C。
    • 合环境监测、气象研究以及设备温度控制。
  3. 低功耗设计
    • 支持低功耗模式,适合电池供电的应用。
    • 工作电压:1.8V 到 3.6V,工作电流低至几微安(µA)。
  4. I2CSPI 接口
  5. 校准数据
    • 传感器出厂时会进行内部校准,确保高精度测量。
    • 提供温度和气压的校准系数,用于后期数据的补偿计算。
  6. 小型封装
    • 封装尺寸小,通常为 3.6 mm x 3.8 mm,非常适合空间受限的应用。
    • 低重量,适合嵌入到便携设备中。

三、资料获取

关注微信公众号--星之援工作室 发送关键字(BMP280)

代码含重要注释,开源,可自行移植

➡️➡️452c0cf75b1d4e4895194df8a5022c34.png

四、设备使用

实现效果

连接好线 打开串口工具 即可输出获取的数据

接线

连线

        VCC - 3.3
GND - GND
SCL - PB6
SAD - PB7

四、代码编写

main.c

 实现函数调用

/*--------------------------------------------------------*
 *                                       								  *
 *   星之援网络科技工作室学习资料v1.0    									*
 *		 时间:2024.11.14                    								*
 *		 程序介绍:按键实验               								  *
 *		 实现效果:BMP280大气压强读取 								      *
 *                                      							    *
 *--------------------------------------------------------*
 
连线
		VCC - 3.3
		GND - GND
		SCL - PB6
		SAD - PB7

*/

#include "stm32f10x.h"
#include "delay.h"
#include "led.h"
#include "key.h"
#include "usart.h"
#include "bmp280.h"
int main(void)
{
	float bmp280_temp;
	float bmp280_press;
	float bmp280_humi;
	float high;
	delay_init();
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 	 //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	// LED 端口初始化 
	LED_GPIO_Config();

	// 串口初始化
	uart_init(115200);
	
	// 初始化模拟 I2C 和 BMP280
	IIC_Init();	
	bme280Init();
	
	printf("init okn");
  while(1)
	{
		bme280GetData(&bmp280_press,&bmp280_temp,&high);
		// 处理数据,比如通过UART发送
		// 在这里可以使用 UART 输出温度和气压,或者进行其他操作
		printf("bmp280_press: %.2f  hParn",bmp280_press);
		delay_ms(100);
		printf("bmp280_temp: %.2f  Crn",bmp280_temp);
		delay_ms(100);
		printf("bmp280_high : %.2f  Mrnrn",high);
		// 等待1s
		delay_ms(1000);
  }   
}

bmp280.c

实现IIC配置和读取 ,实现BMP280读取

#include "bmp280.h"
#include "delay.h"
#include "math.h"
#include "usart.h"
#include "stdio.h"


unsigned long int hum_raw, temp_raw, pres_raw;
signed long int t_fine;

// 预定义函数原型
static float bme280PressureToAltitude(float* pressure/*, float* groundPressure, float* groundTemp*/);
void writeReg(uint8_t reg_address, uint8_t data);
void readData(void);
void readTrim(void);

// 传感器的校准系数
uint16_t dig_T1;
int16_t dig_T2;
int16_t dig_T3;
uint16_t dig_P1;
int16_t dig_P2;
int16_t dig_P3;
int16_t dig_P4;
int16_t dig_P5;
int16_t dig_P6;
int16_t dig_P7;
int16_t dig_P8;
int16_t dig_P9;
int8_t  dig_H1;
int16_t dig_H2;
int8_t  dig_H3;
int16_t dig_H4;
int16_t dig_H5;
int8_t  dig_H6;

// 初始化设置BME280传感器
void setup()
{
    uint8_t osrs_t = 1;             // 温度超采样 x 1
    uint8_t osrs_p = 1;             // 气压超采样 x 1
    uint8_t osrs_h = 1;             // 湿度超采样 x 1
    uint8_t mode = 3;               // 正常模式
    uint8_t t_sb = 5;               // 温度待机时间 1000ms
    uint8_t filter = 0;             // 关闭滤波器
    uint8_t spi3w_en = 0;           // 3线SPI禁用
    
    // 控制测量寄存器和配置寄存器的值设置
    uint8_t ctrl_meas_reg = (osrs_t << 5) | (osrs_p << 2) | mode;
    uint8_t config_reg    = (t_sb << 5) | (filter << 2) | spi3w_en;
    uint8_t ctrl_hum_reg  = osrs_h;
    
    // 写入寄存器
    writeReg(0xF2, ctrl_hum_reg);  // 湿度控制寄存器
    writeReg(0xF4, ctrl_meas_reg); // 控制测量寄存器
    writeReg(0xF5, config_reg);    // 配置寄存器
    readTrim();                    // 读取校准数据
}

// 读取传感器的校准数据(从寄存器获取)
void readTrim(void)
{
    uint8_t data[32];
	
    // I2C读取传感器的校准数据
    iicDevRead(BME280_ADDRESS, 0x88, 24, &data[0]);
    iicDevRead(BME280_ADDRESS, 0xA1, 1, &data[24]);
    iicDevRead(BME280_ADDRESS, 0xE1, 7, &data[25]);

    // 提取校准数据
    dig_T1 = (data[1] << 8) | data[0];
    dig_T2 = (data[3] << 8) | data[2];
    dig_T3 = (data[5] << 8) | data[4];
    dig_P1 = (data[7] << 8) | data[6];
    dig_P2 = (data[9] << 8) | data[8];
    dig_P3 = (data[11] << 8) | data[10];
    dig_P4 = (data[13] << 8) | data[12];
    dig_P5 = (data[15] << 8) | data[14];
    dig_P6 = (data[17] << 8) | data[16];
    dig_P7 = (data[19] << 8) | data[18];
    dig_P8 = (data[21] << 8) | data[20];
    dig_P9 = (data[23] << 8) | data[22];
    dig_H1 = data[24];
    dig_H2 = (data[26] << 8) | data[25];
    dig_H3 = data[27];
    dig_H4 = (data[28] << 4) | (0x0F & data[29]);
    dig_H5 = (data[30] << 4) | ((data[29] >> 4) & 0x0F);
    dig_H6 = data[31];   
}

// 向BME280写入一个字节数据
void writeReg(uint8_t reg_address, uint8_t data)
{
    iicDevWriteByte(BME280_ADDRESS, reg_address, data);
}

// 读取BME280的原始数据
void readData(void)
{
    u8 data[8];
    
    // 从数据寄存器读取原始数据
    iicDevRead(BME280_ADDRESS, 0xF7, 8, data);
    pres_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4);
    temp_raw = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4);
    hum_raw  = (data[6] << 8) | data[7];
}

// 温度校准函数
signed long int calibration_T(signed long int adc_T)
{
    signed long int var1, var2, T;
    
    // 根据原始温度值和校准参数进行计算
    var1 = ((((adc_T >> 3) - ((signed long int)dig_T1 << 1))) * ((signed long int)dig_T2)) >> 11;
    var2 = (((((adc_T >> 4) - ((signed long int)dig_T1)) * ((adc_T >> 4) - ((signed long int)dig_T1))) >> 12) * ((signed long int)dig_T3)) >> 14;
    
    t_fine = var1 + var2;
    T = (t_fine * 5 + 128) >> 8;
    return T; 
}

// 气压校准函数
unsigned long int calibration_P(signed long int adc_P)
{
    signed long int var1, var2;
    unsigned long int P;
    
    // 根据原始气压值和校准参数进行计算
    var1 = (((signed long int)t_fine) >> 1) - (signed long int)64000;
    var2 = (((var1 >> 2) * (var1 >> 2)) >> 11) * ((signed long int)dig_P6);
    var2 = var2 + ((var1 * ((signed long int)dig_P5)) << 1);
    var2 = (var2 >> 2) + (((signed long int)dig_P4) << 16);
    var1 = (((dig_P3 * (((var1 >> 2) * (var1 >> 2)) >> 13)) >> 3) + ((((signed long int)dig_P2) * var1) >> 1)) >> 18;
    var1 = ((((32768 + var1)) * ((signed long int)dig_P1)) >> 15);
    
    // 避免除以零
    if (var1 == 0)
    {
        return 0;
    }

    // 根据校准后的参数计算气压值
    P = (((unsigned long int)(((signed long int)1048576) - adc_P) - (var2 >> 12))) * 3125;
    
    if (P < 0x80000000)
    {
        P = (P << 1) / ((unsigned long int)var1);   
    }
    else
    {
        P = (P / (unsigned long int)var1) * 2;    
    }
    
    var1 = (((signed long int)dig_P9) * ((signed long int)(((P >> 3) * (P >> 3)) >> 13))) >> 12;
    var2 = (((signed long int)(P >> 2)) * ((signed long int)dig_P8)) >> 13;
    P = (unsigned long int)((signed long int)P + ((var1 + var2 + dig_P7) >> 4));
    
    return P;
}

// 湿度校准函数
unsigned long int calibration_H(signed long int adc_H)
{
    signed long int v_x1;
    
    // 根据湿度原始数据和校准参数进行计算
    v_x1 = (t_fine - ((signed long int)76800));
    v_x1 = (((((adc_H << 14) - (((signed long int)dig_H4) << 20) - (((signed long int)dig_H5) * v_x1)) + ((signed long int)16384)) >> 15) *
            (((((((v_x1 * ((signed long int)dig_H6)) >> 10) * (((v_x1 * ((signed long int)dig_H3)) >> 11) + ((signed long int)32768))) >> 10) + ((signed long int)2097152)) *
            ((signed long int)dig_H2) + 8192) >> 14));
            
    v_x1 = v_x1 - (((((v_x1 >> 15) * (v_x1 >> 15)) >> 7) * ((signed long int)dig_H1)) >> 4);
    if (v_x1 < 0) v_x1 = 0;
    if (v_x1 > 419430400) v_x1 = 419430400;
    return (unsigned long int)(v_x1 >> 12);
}

void bme280Init(void)
{	
	IIC_Init();		                                                           /*初始化I2C*/
  delay_ms(20);
	setup();
}

void bme280GetData(float* pressure,float* temperature,float* asl)
{
    double temp_act = 0.0, press_act = 0.0;
    signed long int temp_cal;
    unsigned long int press_cal;
    readData();
	
    temp_cal = calibration_T(temp_raw);
    press_cal = calibration_P(pres_raw);
    // hum_cal = calibration_H(hum_raw);
    temp_act = (double)temp_cal / 100.0;
    press_act = (double)press_cal / 100.0;
    //hum_act = (double)hum_cal / 1024.0;

//	printf("temp_raw:%ldrn",temp_raw);
//	printf("pres_raw:%ldrn",pres_raw);
//	printf("hum_raw:%ldrn",hum_raw);

	*temperature=temp_act;                                                     /*单位度*/
	*pressure=press_act;	                                                   /*单位hPa*/	
	//*humidity=hum_act;
	*asl=bme280PressureToAltitude(pressure);	                               /*转换成海拔*/	
}

		                                              
/*
 * Converts pressure to altitude above sea level (ASL) in meters
*/
static float bme280PressureToAltitude(float* pressure/*, float* groundPressure, float* groundTemp*/)
{
    if (*pressure>0)
    {
        return((pow((1015.7f/ *pressure),CONST_PF)-1.0f)*(FIX_TEMP+273.15f))/0.0065f;
    }
    else
    {
        return 0;
    }
}

//初始化IIC
void IIC_Init(void)
{					     
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(	SCL_GPIO_CLK, ENABLE );	
	   
	GPIO_InitStructure.GPIO_Pin=SCL_GPIO_PIN|SDA_GPIO_PIN;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP ;                            //推挽输出
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(SCL_GPIO_PORT,&GPIO_InitStructure);
 
	IIC_SCL=1;
	IIC_SDA=1;

}

// 配置双向I/O端口为输出态
static void SDA_OUT()
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(SDA_GPIO_CLK, ENABLE);

	GPIO_InitStructure.GPIO_Pin = SDA_GPIO_PIN; // PC.10  DATA
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(SDA_GPIO_PORT, &GPIO_InitStructure); // 初始化GPIOC.10
}
// 配置双向I/O端口为输入态
static void SDA_IN()
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(SDA_GPIO_CLK, ENABLE);
	GPIO_InitStructure.GPIO_Pin = SDA_GPIO_PIN; // PC.10 DATA
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(SDA_GPIO_PORT, &GPIO_InitStructure); // 初始化GPIOC.10
}


//产生IIC起始信号
void IIC_Start(void)
{
	SDA_OUT();                                                                 //sda线输出
	IIC_SDA=1;	  	  
	IIC_SCL=1;
	delay_us(4);
 	IIC_SDA=0;                                                                 //START:when CLK is high,DATA change form high to low 
	delay_us(4);
	IIC_SCL=0;                                                                 //钳住I2C总线,准备发送或接收数据 
}	  
//产生IIC停止信号
void IIC_Stop(void)
{
	SDA_OUT();                                                                 //sda线输出
	IIC_SCL=0;
	IIC_SDA=0;                                                                 //STOP:when CLK is high DATA change form low to high
 	delay_us(4);
	IIC_SCL=1; 
	IIC_SDA=1;                                                                 //发送I2C总线结束信号
	delay_us(4);							   	
}
//等待应答信号到来
//返回值:1,接收应答失败
//        0,接收应答成功
u8 IIC_Wait_Ack(void)
{
	u8 ucErrTime=0;
	SDA_IN();                                                                  //SDA设置为输入  
	IIC_SDA=1;delay_us(1);	   
	IIC_SCL=1;delay_us(1);	 
	while(READ_SDA)
	{
		ucErrTime++;
		if(ucErrTime>250)
		{
			IIC_Stop();
			return 1;
		}
	}
	IIC_SCL=0;                                                                 //时钟输出0 	   
	return 0;  
} 
//产生ACK应答
void IIC_Ack(void)
{
	IIC_SCL=0;
	SDA_OUT();
	IIC_SDA=0;
	delay_us(2);
	IIC_SCL=1;
	delay_us(2);
	IIC_SCL=0;
}
//不产生ACK应答		    
void IIC_NAck(void)
{
	IIC_SCL=0;
	SDA_OUT();
	IIC_SDA=1;
	delay_us(2);
	IIC_SCL=1;
	delay_us(2);
	IIC_SCL=0;
}					 				     
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答			  
void IIC_Send_Byte(u8 txd)
{                        
    u8 t;   
	SDA_OUT(); 	    
    IIC_SCL=0;                                                                 //拉低时钟开始数据传输
    for(t=0;t<8;t++)
    {              
        IIC_SDA=(txd&0x80)>>7;
        txd<<=1; 	  
		delay_us(2);                                                           //对TEA5767这三个延时都是必须的
		IIC_SCL=1;
		delay_us(2); 
		IIC_SCL=0;	
		delay_us(2);
    }	 
} 	    
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
u8 IIC_Read_Byte(unsigned char ack)
{
	unsigned char i,receive=0;
	SDA_IN();                                                                  //SDA设置为输入
    for(i=0;i<8;i++ )
	{
        IIC_SCL=0; 
        delay_us(2);
		IIC_SCL=1;
        receive<<=1;
        if(READ_SDA)receive++;   
		delay_us(1); 
    }					 
    if (!ack)
        IIC_NAck();                                                            //发送nACK
    else
        IIC_Ack();                                                             //发送ACK   
    return receive;
}

//从指定地址读出一个数据
//ReadAddr:开始读数的地址  
//返回值  :读到的数据
u8 iicDevReadByte(u8 devaddr,u8 addr)
{				  
	u8 temp=0;		  	    																 
	IIC_Start();  
	IIC_Send_Byte(devaddr);                                                    //发送器件写命令 	   
	IIC_Wait_Ack(); 
	IIC_Send_Byte(addr);                                                       //发送低地址
	IIC_Wait_Ack();	

	IIC_Start();  	 	   
	IIC_Send_Byte(devaddr|1);                                                  //发送器件读命令			   
	IIC_Wait_Ack();	 
	temp=IIC_Read_Byte(0);			   
	IIC_Stop();                                                                //产生一个停止条件	    
	return temp;
}

//连续读多个字节
//addr:起始地址
//rbuf:读数据缓存
//len:数据长度
void iicDevRead(u8 devaddr,u8 addr,u8 len,u8 *rbuf)
{
	int i=0;
	IIC_Start();  
	IIC_Send_Byte(devaddr);  
	IIC_Wait_Ack();	
	IIC_Send_Byte(addr);                                                       //地址自增  
	IIC_Wait_Ack();	

	IIC_Start();  	
	IIC_Send_Byte(devaddr|1);  	
	IIC_Wait_Ack();	
	for(i=0; i<len; i++)
	{
		if(i==len-1)
		{
			rbuf[i]=IIC_Read_Byte(0);                                          //最后一个字节不应答
		}
		else
			rbuf[i]=IIC_Read_Byte(1);
	}
	IIC_Stop( );	
}


void iicDevReadCal1(u8 devaddr,u8 addr,u8 len,u8 *rbuf)
{
	int i=0;
	IIC_Start();  
	IIC_Send_Byte(devaddr);  
	IIC_Wait_Ack();	
	IIC_Send_Byte(0x88);                                                       //地址自增  
	IIC_Wait_Ack();	
	len=24;
	for(i=0; i<len; i++)
	{
		if(i==len-1)
		{
			rbuf[i]=IIC_Read_Byte(0);                                          //最后一个字节不应答
		}
		else
			rbuf[i]=IIC_Read_Byte(1);
	}
	IIC_Stop( );	
	delay_us(100);
	
	IIC_Start();  
	IIC_Send_Byte(0x76);  
	IIC_Wait_Ack();	
	IIC_Send_Byte(0xA1);                                                       //地址自增  
	IIC_Wait_Ack();	
	rbuf[i++]=IIC_Read_Byte(0); 
	IIC_Stop( );
	delay_us(100);
	
	IIC_Start();  
	IIC_Send_Byte(0x76);  
	IIC_Wait_Ack();	
	IIC_Send_Byte(0xE1);                                                       //地址自增  
	IIC_Wait_Ack();	
	len=32;
	for(; i<len; i++)
	{
		if(i==len-1)
		{
			rbuf[i]=IIC_Read_Byte(0);                                          //最后一个字节不应答
		}
		else
			rbuf[i]=IIC_Read_Byte(1);
	}
	IIC_Stop( );	
}

//连续读多个字节
//addr:起始地址
//rbuf:读数据缓存
//len:数据长度
void iicDevReadCal(u8 devaddr,u8 addr,u8 len,bme280Calib *bme280Ctype)
{
	int i=0;
	u8 rbuf[32];
	IIC_Start();  
	IIC_Send_Byte(devaddr);  
	IIC_Wait_Ack();	
	IIC_Send_Byte(0x88);                                                       //地址自增  
	IIC_Wait_Ack();	
	len=24;
	for(i=0; i<len; i++)
	{
		if(i==len-1)
		{
			rbuf[i]=IIC_Read_Byte(0);                                          //最后一个字节不应答
		}
		else
			rbuf[i]=IIC_Read_Byte(1);
	}
	IIC_Stop( );	
	delay_us(100);
	
	IIC_Start();  
	IIC_Send_Byte(devaddr);  
	IIC_Wait_Ack();	
	IIC_Send_Byte(0xA1);                                                       //地址自增  
	IIC_Wait_Ack();	
	rbuf[i++]=IIC_Read_Byte(0); 
	IIC_Stop( );
	delay_us(100);
	
	IIC_Start();  
	IIC_Send_Byte(devaddr);  
	IIC_Wait_Ack();	
	IIC_Send_Byte(0xE1);                                                       //地址自增  
	IIC_Wait_Ack();	
	len=32;
	for(; i<len; i++)
	{
		if(i==len-1)
		{
			rbuf[i]=IIC_Read_Byte(0);                                          //最后一个字节不应答
		}
		else
			rbuf[i]=IIC_Read_Byte(1);
	}
	IIC_Stop( );
	
	bme280Ctype->dig_T1=(rbuf[1] << 8) | rbuf[0];
	bme280Ctype->dig_T2=(rbuf[3] << 8) | rbuf[2];
	bme280Ctype->dig_T3=(rbuf[5] << 8) | rbuf[4];
	bme280Ctype->dig_P1=(rbuf[7] << 8) | rbuf[6];
	bme280Ctype->dig_P2=(rbuf[9] << 8) | rbuf[8];
	bme280Ctype->dig_P3=(rbuf[11]<< 8) | rbuf[10];
	bme280Ctype->dig_P4=(rbuf[13]<< 8) | rbuf[12];
	bme280Ctype->dig_P5=(rbuf[15]<< 8) | rbuf[14];
	bme280Ctype->dig_P6=(rbuf[17]<< 8) | rbuf[16];
	bme280Ctype->dig_P7=(rbuf[19]<< 8) | rbuf[18];
	bme280Ctype->dig_P8=(rbuf[21]<< 8) | rbuf[20];
	bme280Ctype->dig_P9=(rbuf[23]<< 8) | rbuf[22];
	bme280Ctype->dig_H1=rbuf[24];
	bme280Ctype->dig_H2=(rbuf[26]<< 8) | rbuf[25];
	bme280Ctype->dig_H3=rbuf[27];
	bme280Ctype->dig_H4=(rbuf[28]<< 4) | (0x0F & rbuf[29]);
	bme280Ctype->dig_H5=(rbuf[30] << 4) | ((rbuf[29] >> 4) & 0x0F);
	bme280Ctype->dig_H6=rbuf[31];  
}

//从指定地址写入一个数据
//WriteAddr :写入数据的目的地址    
//DataToWrite:要写入的数据
void iicDevWriteByte(u8 devaddr,u8 addr,u8 data)
{				   	  	    																 
	IIC_Start();  
	IIC_Send_Byte(devaddr);                                                    //发送器件写命令 	 
	IIC_Wait_Ack();	   
	IIC_Send_Byte(addr);                                                       //发送低地址
	IIC_Wait_Ack(); 	 										  		   
	IIC_Send_Byte(data);                                                       //发送字节							   
	IIC_Wait_Ack();  		    	   
	IIC_Stop();		                                                           //产生一个停止条件 	 
}

//连续写多个字节
//addr:起始地址
//wbuf:写数据缓存
//len:数据的长度
void iicDevWrite(u8 devaddr,u8 addr,u8 len,u8 *wbuf)
{
	int i=0;
	IIC_Start();  
	IIC_Send_Byte(devaddr);  	
	IIC_Wait_Ack();	
	IIC_Send_Byte(addr);  //地址自增
	IIC_Wait_Ack();	
	for(i=0; i<len; i++)
	{
		IIC_Send_Byte(wbuf[i]);  
		IIC_Wait_Ack();		
	}
	IIC_Stop( );	
}

bmp280.h

配置函数

#ifndef __BMP280_H
#define __BMP280_H

#include "stm32f10x.h"
#include "sys.h"
#include "stdbool.h"

#define SCL_GPIO_PORT GPIOB              /* GPIO端口 */
#define SCL_GPIO_CLK RCC_APB2Periph_GPIOB /* GPIO端口时钟 */
#define SCL_GPIO_PIN GPIO_Pin_6          /* 连接到SCL时钟线的GPIO */

#define SDA_GPIO_PORT GPIOB              /* GPIO端口 */
#define SDA_GPIO_CLK RCC_APB2Periph_GPIOB /* GPIO端口时钟 */
#define SDA_GPIO_PIN GPIO_Pin_7          /* 连接到SCL时钟线的GPIO */

//IO操作函数	 
#define IIC_SCL    PBout(6)                                                   //SCL
#define IIC_SDA    PBout(7)                                                   //SDA	 
#define READ_SDA   PBin(7)                                                    //输入SDA 

// BME280的I2C地址,通常为0xEC
#define BME280_ADDRESS 0XEC
#define BME280_ADDR						(0x76)
#define BME280_DEFAULT_CHIP_ID			(0x60)

#define BME280_CHIP_ID					(0xD0)                                 /* Chip ID Register */
#define BME280_RST_REG					(0xE0)                                 /* Softreset Register */
#define BME280_CTRL_HUM                 (0xF2)                                 /* Ctrl Humidity Register */
#define BME280_STAT_REG					(0xF3)                                 /* Status Register */
#define BME280_CTRL_MEAS_REG			(0xF4)                                 /* Ctrl Measure Register */
#define BME280_CONFIG_REG				(0xF5)                                 /* Configuration Register */
#define BME280_PRESSURE_MSB_REG			(0xF7)                                 /* Pressure MSB Register */
#define BME280_PRESSURE_LSB_REG			(0xF8)                                 /* Pressure LSB Register */
#define BME280_PRESSURE_XLSB_REG		(0xF9)                                 /* Pressure XLSB Register */
#define BME280_TEMPERATURE_MSB_REG		(0xFA)                                 /* Temperature MSB Reg */
#define BME280_TEMPERATURE_LSB_REG		(0xFB)                                 /* Temperature MSB Reg */
#define BME280_TEMPERATURE_XLSB_REG		(0xFC)                                 /* Temperature XLSB Reg */
#define BME280_HUMIDITY_MSB_REG			(0xFD)                                 /* Humidity MSB Reg */
#define BME280_HUMIDITY_LSB_REG		    (0xFE)                                 /* Humidity LSB Reg */

#define BME280_SLEEP_MODE				(0x00)
#define BME280_FORCED_MODE				(0x01)
#define BME280_NORMAL_MODE				(0x03)

#define BME280_TEMPERATURE_CALIB_DIG_T1_LSB_REG             (0x88)
#define BME280_PRESSURE_TEMPERATURE_CALIB_DATA_LENGTH       (32)
#define BME280_DATA_FRAME_SIZE			(8)

#define BME280_OVERSAMP_SKIPPED			(0x00)
#define BME280_OVERSAMP_1X				(0x01)
#define BME280_OVERSAMP_2X				(0x02)
#define BME280_OVERSAMP_4X				(0x03)
#define BME280_OVERSAMP_8X				(0x04)
#define BME280_OVERSAMP_16X				(0x05)


#define CONST_PF 0.1902630958	                                               //(1/5.25588f) Pressure factor
#define FIX_TEMP 25				                                               // Fixed Temperature. ASL is a function of pressure and temperature, but as the temperature changes so much (blow a little towards the flie and watch it drop 5 degrees) it corrupts the ASL estimates.
						
typedef struct 
{
    u16 dig_T1;                                                                /* calibration T1 data */
    s16 dig_T2;                                                                /* calibration T2 data */
    s16 dig_T3;                                                                /* calibration T3 data */
    u16 dig_P1;                                                                /* calibration P1 data */
    s16 dig_P2;                                                                /* calibration P2 data */
    s16 dig_P3;                                                                /* calibration P3 data */
    s16 dig_P4;                                                                /* calibration P4 data */
    s16 dig_P5;                                                                /* calibration P5 data */
    s16 dig_P6;                                                                /* calibration P6 data */
    s16 dig_P7;                                                                /* calibration P7 data */
    s16 dig_P8;                                                                /* calibration P8 data */
    s16 dig_P9;                                                                /* calibration P9 data */
	u8  dig_H1;                                                                /* calibration H1 data */
	s16 dig_H2;                                                                /* calibration H2 data */
	u8  dig_H3;                                  							   /* calibration H3 data */
	s16 dig_H4;                                                                /* calibration H4 data */
	s16 dig_H5;                                                                /* calibration H5 data */
	u8  dig_H6;                                                                /* calibration H6 data */
    s32 t_fine;                                                                /* calibration t_fine data */
} bme280Calib;

// BMP280
void bme280Init(void);
void bme280GetData(float* pressure,float* temperature,float* asl);


//IIC所有操作函数
void IIC_Init(void);                                                           //初始化IIC的IO口				 
void IIC_Start(void);				                                           //发送IIC开始信号
void IIC_Stop(void);	  			                                           //发送IIC停止信号
void IIC_Send_Byte(u8 txd);			                                           //IIC发送一个字节
u8 IIC_Read_Byte(unsigned char ack);                                           //IIC读取一个字节
u8 IIC_Wait_Ack(void); 				                                           //IIC等待ACK信号
void IIC_Ack(void);					                                           //IIC发送ACK信号
void IIC_NAck(void);				                                           //IIC不发送ACK信号

void IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);
u8 IIC_Read_One_Byte(u8 daddr,u8 addr);	
			 
u8 iicDevReadByte(u8 devaddr,u8 addr);	                                       /*读一字节*/
void iicDevWriteByte(u8 devaddr,u8 addr,u8 data);	                           /*写一字节*/
void iicDevRead(u8 devaddr,u8 addr,u8 len,u8 *rbuf);                           /*连续读取多个字节*/
void iicDevWrite(u8 devaddr,u8 addr,u8 len,u8 *wbuf);                          /*连续写入多个字节*/
void iicDevReadCal(u8 devaddr,u8 addr,u8 len,bme280Calib *bme280Ctype);  
void iicDevReadCal1(u8 devaddr,u8 addr,u8 len,u8 *rbuf);



#endif // __BMP280_H

五、参考

STM32驱动BMP280模块icon-default.png?t=O83Ahttps://blog.csdn.net/bdjsm_hh/article/details/107623788?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522fe7a480a09ea26ca74d82092835ed6ec%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=fe7a480a09ea26ca74d82092835ed6ec&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-107623788-null-null.142%5Ev100%5Epc_search_result_base9&utm_term=BMP280%20stm32%E9%A9%B1%E5%8A%A8&spm=1018.2226.3001.4187

联系方式 微信号:13648103287

  • 联系方式.docx

相关推荐

电子产业图谱

方案定制,程序设计方案、单片机程序设计与讲解、APP定制开发。本公众号致力于向读者传递关于程序设计和开发的相关知识,并分享一些关于软件开发的最佳实践。如果您有什么问题或建议,请随时联系我们。我们将竭诚为您服务