加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入

嵌入式外設(shè)-BMP280 壓強(qiáng)/溫度/海拔 讀取(BMP280)驅(qū)動代碼

17小時(shí)前
152
服務(wù)支持:
技術(shù)交流群

完成交易后在“購買成功”頁面掃碼入群,即可與技術(shù)大咖們分享疑惑和經(jīng)驗(yàn)、收獲成長和認(rèn)同、領(lǐng)取優(yōu)惠和紅包等。

虛擬商品不可退

當(dāng)前內(nèi)容為數(shù)字版權(quán)作品,購買后不支持退換且無法轉(zhuǎn)移使用。

加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論
放大
實(shí)物圖
相關(guān)方案
  • 方案介紹
    • 一、前言
    • 二、簡介
    • 三、資料獲取
    • 四、設(shè)備使用
    • 四、代碼編寫
    • 五、參考
  • 相關(guān)文件
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

一、前言

BMP280 是一款由 Bosch Sensortec 生產(chǎn)的小型、高精度的氣壓和溫度傳感器,廣泛應(yīng)用于環(huán)境監(jiān)測、天氣預(yù)報(bào)、室內(nèi)外導(dǎo)航、無人機(jī)飛行控制、物聯(lián)網(wǎng)設(shè)備等領(lǐng)域。它是繼 BMP180BMP183 之后的下一代氣壓傳感器,性能更高,功耗更低。

二、簡介

主要特性

  1. 氣壓傳感器
    • 測量范圍:300 至 1100 hPa(百帕,單位用于衡量氣壓的標(biāo)準(zhǔn)單位)。
    • 分辨率:最小可達(dá) 1 Pa(帕斯卡)。
    • 精度:±1 hPa(氣壓精度)。
    • 適合用于氣壓計(jì)、氣象站和高度計(jì)等設(shè)備中。
  2. 溫度傳感器
    • 測量范圍:-40°C 至 +85°C。
    • 精度:±1.0°C。
    • 合環(huán)境監(jiān)測、氣象研究以及設(shè)備溫度控制。
  3. 低功耗設(shè)計(jì)
    • 支持低功耗模式,適合電池供電的應(yīng)用。
    • 工作電壓:1.8V 到 3.6V,工作電流低至幾微安(μA)。
  4. I2CSPI 接口
  5. 校準(zhǔn)數(shù)據(jù)
    • 傳感器出廠時(shí)會進(jìn)行內(nèi)部校準(zhǔn),確保高精度測量。
    • 提供溫度和氣壓的校準(zhǔn)系數(shù),用于后期數(shù)據(jù)的補(bǔ)償計(jì)算。
  6. 小型封裝
    • 封裝尺寸小,通常為 3.6 mm x 3.8 mm,非常適合空間受限的應(yīng)用。
    • 低重量,適合嵌入到便攜設(shè)備中。

三、資料獲取

關(guān)注微信公眾號--星之援工作室 發(fā)送關(guān)鍵字(BMP280)

代碼含重要注釋,開源,可自行移植

????452c0cf75b1d4e4895194df8a5022c34.png

四、設(shè)備使用

實(shí)現(xiàn)效果

連接好線 打開串口工具 即可輸出獲取的數(shù)據(jù)

接線

連線

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

?

四、代碼編寫

main.c

?實(shí)現(xiàn)函數(shù)調(diào)用

/*--------------------------------------------------------*
 *                                       								  *
 *   星之援網(wǎng)絡(luò)科技工作室學(xué)習(xí)資料v1.0    									*
 *		 時(shí)間:2024.11.14                    								*
 *		 程序介紹:按鍵實(shí)驗(yàn)               								  *
 *		 實(shí)現(xiàn)效果:BMP280大氣壓強(qiáng)讀取 								      *
 *                                      							    *
 *--------------------------------------------------------*
 
連線
		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); 	 //設(shè)置NVIC中斷分組2:2位搶占優(yōu)先級,2位響應(yīng)優(yōu)先級
	// LED 端口初始化 
	LED_GPIO_Config();

	// 串口初始化
	uart_init(115200);
	
	// 初始化模擬 I2C 和 BMP280
	IIC_Init();	
	bme280Init();
	
	printf("init okn");
  while(1)
	{
		bme280GetData(&bmp280_press,&bmp280_temp,&high);
		// 處理數(shù)據(jù),比如通過UART發(fā)送
		// 在這里可以使用 UART 輸出溫度和氣壓,或者進(jìn)行其他操作
		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

實(shí)現(xiàn)IIC配置和讀取 ,實(shí)現(xiàn)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;

// 預(yù)定義函數(shù)原型
static float bme280PressureToAltitude(float* pressure/*, float* groundPressure, float* groundTemp*/);
void writeReg(uint8_t reg_address, uint8_t data);
void readData(void);
void readTrim(void);

// 傳感器的校準(zhǔn)系數(shù)
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;

// 初始化設(shè)置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;               // 溫度待機(jī)時(shí)間 1000ms
    uint8_t filter = 0;             // 關(guān)閉濾波器
    uint8_t spi3w_en = 0;           // 3線SPI禁用
    
    // 控制測量寄存器和配置寄存器的值設(shè)置
    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();                    // 讀取校準(zhǔn)數(shù)據(jù)
}

// 讀取傳感器的校準(zhǔn)數(shù)據(jù)(從寄存器獲取)
void readTrim(void)
{
    uint8_t data[32];
	
    // I2C讀取傳感器的校準(zhǔn)數(shù)據(jù)
    iicDevRead(BME280_ADDRESS, 0x88, 24, &data[0]);
    iicDevRead(BME280_ADDRESS, 0xA1, 1, &data[24]);
    iicDevRead(BME280_ADDRESS, 0xE1, 7, &data[25]);

    // 提取校準(zhǔn)數(shù)據(jù)
    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寫入一個(gè)字節(jié)數(shù)據(jù)
void writeReg(uint8_t reg_address, uint8_t data)
{
    iicDevWriteByte(BME280_ADDRESS, reg_address, data);
}

// 讀取BME280的原始數(shù)據(jù)
void readData(void)
{
    u8 data[8];
    
    // 從數(shù)據(jù)寄存器讀取原始數(shù)據(jù)
    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];
}

// 溫度校準(zhǔn)函數(shù)
signed long int calibration_T(signed long int adc_T)
{
    signed long int var1, var2, T;
    
    // 根據(jù)原始溫度值和校準(zhǔn)參數(shù)進(jìn)行計(jì)算
    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; 
}

// 氣壓校準(zhǔn)函數(shù)
unsigned long int calibration_P(signed long int adc_P)
{
    signed long int var1, var2;
    unsigned long int P;
    
    // 根據(jù)原始?xì)鈮褐岛托?zhǔn)參數(shù)進(jìn)行計(jì)算
    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;
    }

    // 根據(jù)校準(zhǔn)后的參數(shù)計(jì)算氣壓值
    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;
}

// 濕度校準(zhǔn)函數(shù)
unsigned long int calibration_H(signed long int adc_H)
{
    signed long int v_x1;
    
    // 根據(jù)濕度原始數(shù)據(jù)和校準(zhǔn)參數(shù)進(jìn)行計(jì)算
    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);	                               /*轉(zhuǎn)換成海拔*/	
}

		                                              
/*
 * 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端口為輸出態(tài)
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端口為輸入態(tài)
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
}


//產(chǎn)生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總線,準(zhǔn)備發(fā)送或接收數(shù)據(jù) 
}	  
//產(chǎn)生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;                                                                 //發(fā)送I2C總線結(jié)束信號
	delay_us(4);							   	
}
//等待應(yīng)答信號到來
//返回值:1,接收應(yīng)答失敗
//        0,接收應(yīng)答成功
u8 IIC_Wait_Ack(void)
{
	u8 ucErrTime=0;
	SDA_IN();                                                                  //SDA設(shè)置為輸入  
	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;                                                                 //時(shí)鐘輸出0 	   
	return 0;  
} 
//產(chǎn)生ACK應(yīng)答
void IIC_Ack(void)
{
	IIC_SCL=0;
	SDA_OUT();
	IIC_SDA=0;
	delay_us(2);
	IIC_SCL=1;
	delay_us(2);
	IIC_SCL=0;
}
//不產(chǎn)生ACK應(yīng)答		    
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發(fā)送一個(gè)字節(jié)
//返回從機(jī)有無應(yīng)答
//1,有應(yīng)答
//0,無應(yīng)答			  
void IIC_Send_Byte(u8 txd)
{                        
    u8 t;   
	SDA_OUT(); 	    
    IIC_SCL=0;                                                                 //拉低時(shí)鐘開始數(shù)據(jù)傳輸
    for(t=0;t<8;t++)
    {              
        IIC_SDA=(txd&0x80)>>7;
        txd<<=1; 	  
		delay_us(2);                                                           //對TEA5767這三個(gè)延時(shí)都是必須的
		IIC_SCL=1;
		delay_us(2); 
		IIC_SCL=0;	
		delay_us(2);
    }	 
} 	    
//讀1個(gè)字節(jié),ack=1時(shí),發(fā)送ACK,ack=0,發(fā)送nACK   
u8 IIC_Read_Byte(unsigned char ack)
{
	unsigned char i,receive=0;
	SDA_IN();                                                                  //SDA設(shè)置為輸入
    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();                                                            //發(fā)送nACK
    else
        IIC_Ack();                                                             //發(fā)送ACK   
    return receive;
}

//從指定地址讀出一個(gè)數(shù)據(jù)
//ReadAddr:開始讀數(shù)的地址  
//返回值  :讀到的數(shù)據(jù)
u8 iicDevReadByte(u8 devaddr,u8 addr)
{				  
	u8 temp=0;		  	    																 
	IIC_Start();  
	IIC_Send_Byte(devaddr);                                                    //發(fā)送器件寫命令 	   
	IIC_Wait_Ack(); 
	IIC_Send_Byte(addr);                                                       //發(fā)送低地址
	IIC_Wait_Ack();	

	IIC_Start();  	 	   
	IIC_Send_Byte(devaddr|1);                                                  //發(fā)送器件讀命令			   
	IIC_Wait_Ack();	 
	temp=IIC_Read_Byte(0);			   
	IIC_Stop();                                                                //產(chǎn)生一個(gè)停止條件	    
	return temp;
}

//連續(xù)讀多個(gè)字節(jié)
//addr:起始地址
//rbuf:讀數(shù)據(jù)緩存
//len:數(shù)據(jù)長度
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);                                          //最后一個(gè)字節(jié)不應(yīng)答
		}
		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);                                          //最后一個(gè)字節(jié)不應(yīng)答
		}
		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);                                          //最后一個(gè)字節(jié)不應(yīng)答
		}
		else
			rbuf[i]=IIC_Read_Byte(1);
	}
	IIC_Stop( );	
}

//連續(xù)讀多個(gè)字節(jié)
//addr:起始地址
//rbuf:讀數(shù)據(jù)緩存
//len:數(shù)據(jù)長度
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);                                          //最后一個(gè)字節(jié)不應(yīng)答
		}
		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);                                          //最后一個(gè)字節(jié)不應(yīng)答
		}
		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];  
}

//從指定地址寫入一個(gè)數(shù)據(jù)
//WriteAddr :寫入數(shù)據(jù)的目的地址    
//DataToWrite:要寫入的數(shù)據(jù)
void iicDevWriteByte(u8 devaddr,u8 addr,u8 data)
{				   	  	    																 
	IIC_Start();  
	IIC_Send_Byte(devaddr);                                                    //發(fā)送器件寫命令 	 
	IIC_Wait_Ack();	   
	IIC_Send_Byte(addr);                                                       //發(fā)送低地址
	IIC_Wait_Ack(); 	 										  		   
	IIC_Send_Byte(data);                                                       //發(fā)送字節(jié)							   
	IIC_Wait_Ack();  		    	   
	IIC_Stop();		                                                           //產(chǎn)生一個(gè)停止條件 	 
}

//連續(xù)寫多個(gè)字節(jié)
//addr:起始地址
//wbuf:寫數(shù)據(jù)緩存
//len:數(shù)據(jù)的長度
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

配置函數(shù)

#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端口時(shí)鐘 */
#define SCL_GPIO_PIN GPIO_Pin_6          /* 連接到SCL時(shí)鐘線的GPIO */

#define SDA_GPIO_PORT GPIOB              /* GPIO端口 */
#define SDA_GPIO_CLK RCC_APB2Periph_GPIOB /* GPIO端口時(shí)鐘 */
#define SDA_GPIO_PIN GPIO_Pin_7          /* 連接到SCL時(shí)鐘線的GPIO */

//IO操作函數(shù)	 
#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所有操作函數(shù)
void IIC_Init(void);                                                           //初始化IIC的IO口				 
void IIC_Start(void);				                                           //發(fā)送IIC開始信號
void IIC_Stop(void);	  			                                           //發(fā)送IIC停止信號
void IIC_Send_Byte(u8 txd);			                                           //IIC發(fā)送一個(gè)字節(jié)
u8 IIC_Read_Byte(unsigned char ack);                                           //IIC讀取一個(gè)字節(jié)
u8 IIC_Wait_Ack(void); 				                                           //IIC等待ACK信號
void IIC_Ack(void);					                                           //IIC發(fā)送ACK信號
void IIC_NAck(void);				                                           //IIC不發(fā)送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);	                                       /*讀一字節(jié)*/
void iicDevWriteByte(u8 devaddr,u8 addr,u8 data);	                           /*寫一字節(jié)*/
void iicDevRead(u8 devaddr,u8 addr,u8 len,u8 *rbuf);                           /*連續(xù)讀取多個(gè)字節(jié)*/
void iicDevWrite(u8 devaddr,u8 addr,u8 len,u8 *wbuf);                          /*連續(xù)寫入多個(gè)字節(jié)*/
void iicDevReadCal(u8 devaddr,u8 addr,u8 len,bme280Calib *bme280Ctype);  
void iicDevReadCal1(u8 devaddr,u8 addr,u8 len,u8 *rbuf);



#endif // __BMP280_H

五、參考

STM32驅(qū)動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

聯(lián)系方式 微信號:13648103287

  • 聯(lián)系方式.docx

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

方案定制,程序設(shè)計(jì)方案、單片機(jī)程序設(shè)計(jì)與講解、APP定制開發(fā)。本公眾號致力于向讀者傳遞關(guān)于程序設(shè)計(jì)和開發(fā)的相關(guān)知識,并分享一些關(guān)于軟件開發(fā)的最佳實(shí)踐。如果您有什么問題或建議,請隨時(shí)聯(lián)系我們。我們將竭誠為您服務(wù)