一、前言
BMP280 是一款由 Bosch Sensortec 生產(chǎn)的小型、高精度的氣壓和溫度傳感器,廣泛應(yīng)用于環(huán)境監(jiān)測(cè)、天氣預(yù)報(bào)、室內(nèi)外導(dǎo)航、無人機(jī)飛行控制、物聯(lián)網(wǎng)設(shè)備等領(lǐng)域。它是繼 BMP180 和 BMP183 之后的下一代氣壓傳感器,性能更高,功耗更低。
二、簡(jiǎn)介
主要特性
- 氣壓傳感器:
- 測(cè)量范圍:300 至 1100 hPa(百帕,單位用于衡量氣壓的標(biāo)準(zhǔn)單位)。
- 分辨率:最小可達(dá) 1 Pa(帕斯卡)。
- 精度:±1 hPa(氣壓精度)。
- 適合用于氣壓計(jì)、氣象站和高度計(jì)等設(shè)備中。
- 溫度傳感器:
- 測(cè)量范圍:-40°C 至 +85°C。
- 精度:±1.0°C。
- 適合環(huán)境監(jiān)測(cè)、氣象研究以及設(shè)備溫度控制。
- 低功耗設(shè)計(jì):
- I2C 和 SPI 接口:
- 支持 I2C 和 SPI 通信接口,能夠輕松與微控制器(如 Arduino、ESP32、STM32 等)連接。
- I2C 地址:0x76 或 0x77(根據(jù)連接的引腳而定)。
- SPI 接口:適合需要高速數(shù)據(jù)傳輸的應(yīng)用。
- 校準(zhǔn)數(shù)據(jù):
- 傳感器出廠時(shí)會(huì)進(jìn)行內(nèi)部校準(zhǔn),確保高精度測(cè)量。
- 提供溫度和氣壓的校準(zhǔn)系數(shù),用于后期數(shù)據(jù)的補(bǔ)償計(jì)算。
- 小型封裝:
- 封裝尺寸小,通常為 3.6 mm x 3.8 mm,非常適合空間受限的應(yīng)用。
- 低重量,適合嵌入到便攜設(shè)備中。
三、資料獲取
關(guān)注微信公眾號(hào)--星之援工作室 發(fā)送關(guān)鍵字(BMP280)
代碼含重要注釋,開源,可自行移植
????
四、設(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)先級(jí),2位響應(yīng)優(yōu)先級(jí)
// 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禁用
// 控制測(cè)量寄存器和配置寄存器的值設(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); // 控制測(cè)量寄存器
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起始信號(hào)
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停止信號(hào)
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é)束信號(hào)
delay_us(4);
}
//等待應(yīng)答信號(hào)到來
//返回值: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); //對(duì)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開始信號(hào)
void IIC_Stop(void); //發(fā)送IIC停止信號(hào)
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信號(hào)
void IIC_Ack(void); //IIC發(fā)送ACK信號(hào)
void IIC_NAck(void); //IIC不發(fā)送ACK信號(hào)
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ū)動(dòng)BMP280模塊https://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)系方式 微信號(hào):13648103287