41-BMP280 气压传感器

BMP280 气压传感器

1.

2.

c 复制代码
//默认配置
BMP280_Data_t bmp_test;
BMP280_Config_t DefaultConfig =
{
    .dev_addr = BMP280_ADDR,
    .osrs_t = BMP280_OS_2X,
    .osrs_p = BMP280_OS_16X,
    .mode = BMP280_MODE_NORMAL,
    .filter = BMP280_FILTER_4,
    .standby = BMP280_STANDBY_62_5MS
};
BMP280_Init(&DefaultConfig);
while(1)
{
	BMP280_ReadData(&bmp_test);
	bmp_test.altitude=BMP280_CalculateAltitude(bmp_test.pressure, 101325.0f);
}
c 复制代码
// BMP280 I2CµØÖ·
#define BMP280_ADDR_ALT         0x76    // SDO½ÓµØ
#define BMP280_ADDR             0x77    // SDO½ÓVCC
#define BMP280_CHIP_ID          0x58

// BMP280¼Ä´æÆ÷µØÖ·
#define BMP280_REG_ID           0xD0	//
#define BMP280_REG_RESET        0xE0
#define BMP280_REG_STATUS       0xF3
#define BMP280_REG_CTRL_MEAS    0xF4
#define BMP280_REG_CONFIG       0xF5
#define BMP280_REG_PRESS_MSB    0xF7
#define BMP280_REG_PRESS_LSB    0xF8
#define BMP280_REG_PRESS_XLSB   0xF9
#define BMP280_REG_TEMP_MSB     0xFA
#define BMP280_REG_TEMP_LSB     0xFB
#define BMP280_REG_TEMP_XLSB    0xFC

#define BMP280_DIG_T1_LSB_REG   0x88
#define BMP280_DIG_T1_MSB_REG   0x89
#define BMP280_DIG_T2_LSB_REG   0x8A
#define BMP280_DIG_T2_MSB_REG   0x8B
#define BMP280_DIG_T3_LSB_REG   0x8C
#define BMP280_DIG_T3_MSB_REG   0x8D
#define BMP280_DIG_P1_LSB_REG   0x8E
#define BMP280_DIG_P1_MSB_REG   0x8F
#define BMP280_DIG_P2_LSB_REG   0x90
#define BMP280_DIG_P2_MSB_REG   0x91
#define BMP280_DIG_P3_LSB_REG   0x92
#define BMP280_DIG_P3_MSB_REG   0x93
#define BMP280_DIG_P4_LSB_REG   0x94
#define BMP280_DIG_P4_MSB_REG   0x95
#define BMP280_DIG_P5_LSB_REG   0x96
#define BMP280_DIG_P5_MSB_REG   0x97
#define BMP280_DIG_P6_LSB_REG   0x98
#define BMP280_DIG_P6_MSB_REG   0x99
#define BMP280_DIG_P7_LSB_REG   0x9A
#define BMP280_DIG_P7_MSB_REG   0x9B
#define BMP280_DIG_P8_LSB_REG   0x9C
#define BMP280_DIG_P8_MSB_REG   0x9D
#define BMP280_DIG_P9_LSB_REG   0x9E
#define BMP280_DIG_P9_MSB_REG   0x9F

// У׼Êý¾Ý¼Ä´æÆ÷ÆðʼµØÖ·
#define BMP280_REG_CALIB        0x88
#define BMP280_REG_CALIB_END    0xA1

// ¹¤×÷ģʽ
typedef enum
{
    BMP280_MODE_SLEEP          = 0x00,
    BMP280_MODE_FORCED         = 0x01,
    BMP280_MODE_NORMAL         = 0x03
} BMP280_Mode_t;

// ¹ý²ÉÑùÉèÖÃ
typedef enum 
{
    BMP280_OS_SKIPPED          = 0x00,  // Ìø¹ý
    BMP280_OS_1X               = 0x01,  // 1±¶
    BMP280_OS_2X               = 0x02,  // 2±¶
    BMP280_OS_4X               = 0x03,  // 4±¶
    BMP280_OS_8X               = 0x04,  // 8±¶
    BMP280_OS_16X              = 0x05   // 16±¶
} BMP280_OS_t;

// Â˲¨Æ÷ϵÊý
typedef enum 
{
    BMP280_FILTER_OFF          = 0x00,
    BMP280_FILTER_2            = 0x01,
    BMP280_FILTER_4            = 0x02,
    BMP280_FILTER_8            = 0x03,
    BMP280_FILTER_16           = 0x04
} BMP280_Filter_t;

// ´ý>>úʱ¼ä£¨NormalģʽÏ£©
typedef enum 
{
    BMP280_STANDBY_0_5MS       = 0x00,
    BMP280_STANDBY_62_5MS      = 0x01,
    BMP280_STANDBY_125MS       = 0x02,
    BMP280_STANDBY_250MS       = 0x03,
    BMP280_STANDBY_500MS       = 0x04,
    BMP280_STANDBY_1000MS      = 0x05,
    BMP280_STANDBY_2000MS      = 0x06,
    BMP280_STANDBY_4000MS      = 0x07
} BMP280_Standby_t;

// ÅäÖýṹÌå
typedef struct
{
    uint8_t     dev_addr;           // I2CÉ豸µØÖ·
    BMP280_OS_t osrs_t;             // ζȹý²ÉÑù
    BMP280_OS_t osrs_p;             // ÆøÑ¹¹ý²ÉÑù
    BMP280_Mode_t mode;             // ¹¤×÷ģʽ
    BMP280_Filter_t filter;         // Â˲¨Æ÷ϵÊý
    BMP280_Standby_t standby;       // ´ý>>úʱ¼ä
} BMP280_Config_t;

// У׼Êý¾Ý½á¹¹Ìå
typedef struct 
{
    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;
} BMP280_Calib_t;

// ½á¹û½á¹¹Ìå
typedef struct 
{
    float temperature;   // ÎÂ¶È (¡ãC)
    float pressure;      // ÆøÑ¹ (Pa)
    float altitude;      // º£°Î (m)
} BMP280_Data_t;

// ========== API ==========
u8 BMP280_Init(BMP280_Config_t *config);///初始化
u8 BMP280_GetChipID(void);//获取芯片ID
u8 BMP280_ReadCalibration(void);//读取校准参数
u8 BMP280_SetConfig(BMP280_Config_t *config);//配置寄存器
u8 BMP280_ReadData(BMP280_Data_t *result);//获取气压与温度数据
u8 BMP280_ReadRawData(int32_t *raw_temp, int32_t *raw_press);//获取原始数据
float BMP280_CalculateAltitude(float pressure, float sea_level_pressure);//计算海拔
double bmp280_compensate_T_double(int32_t adc_T);//根据寄存器数据,计算最终的温度值
double bmp280_compensate_P_double(int32_t adc_P);//根据寄存器数据,计算最终的压力值
void BMP280_PrintCalib(void);//打印参数
#endif
c 复制代码
BMP280_Calib_t g_calib = {0};
BMP280_Config_t g_config = {0};
double t_fine = 0;  // ??double??
extern BMP280_Config_t DefaultConfig;
// 默认配置
//static const BMP280_Config_t DefaultConfig =
//{
//    .dev_addr = BMP280_ADDR,
//    .osrs_t = BMP280_OS_2X,
//    .osrs_p = BMP280_OS_16X,
//    .mode = BMP280_MODE_NORMAL,
//    .filter = BMP280_FILTER_4,
//    .standby = BMP280_STANDBY_62_5MS
//};

uint8_t BMP280_GetChipID(void)
{
    uint8_t id = 0;
    if (I2C_Read(DefaultConfig.dev_addr, BMP280_REG_ID, &id, 1)) return 0;
    return id;
}
//读出原始校准参数
u8 BMP280_ReadCalibration(void)
{
    uint8_t calib_data[24] = {0};
    uint8_t addr = BMP280_REG_CALIB;
    
    if (I2C_Read(DefaultConfig.dev_addr, addr, calib_data, 24))  return 0;
		
    // 温度校准
    g_calib.dig_T1 = (uint16_t)((calib_data[1] << 8) | calib_data[0]);
    g_calib.dig_T2 = (int16_t)((calib_data[3] << 8) | calib_data[2]);
    g_calib.dig_T3 = (int16_t)((calib_data[5] << 8) | calib_data[4]);
    
    // 气压校准
    g_calib.dig_P1 = (uint16_t)((calib_data[7] << 8) | calib_data[6]);
    g_calib.dig_P2 = (int16_t)((calib_data[9] << 8) | calib_data[8]);
    g_calib.dig_P3 = (int16_t)((calib_data[11] << 8) | calib_data[10]);
    g_calib.dig_P4 = (int16_t)((calib_data[13] << 8) | calib_data[12]);
    g_calib.dig_P5 = (int16_t)((calib_data[15] << 8) | calib_data[14]);
    g_calib.dig_P6 = (int16_t)((calib_data[17] << 8) | calib_data[16]);
    g_calib.dig_P7 = (int16_t)((calib_data[19] << 8) | calib_data[18]);
    g_calib.dig_P8 = (int16_t)((calib_data[21] << 8) | calib_data[20]);
    g_calib.dig_P9 = (int16_t)((calib_data[23] << 8) | calib_data[22]);
    
    return 1;
}
u8 BMP280_SetConfig(BMP280_Config_t *config)
{
    uint8_t ctrl_meas = 0;
    uint8_t config_reg = 0;
    
    if (config == NULL) g_config = DefaultConfig;  
    else g_config = *config;
    
    // 构建 CTRL_MEAS 寄存器值
    ctrl_meas = (g_config.osrs_t << 5) | (g_config.osrs_p << 2) | g_config.mode;
    
    // 构建 CONFIG 寄存器值
    config_reg = (g_config.standby << 5) | (g_config.filter << 2);
    
    // 写入配置
    if (I2C_Write(g_config.dev_addr, BMP280_REG_CONFIG, &config_reg, 1)) 
        return 0;
   
    // 写入测量控制
    if (I2C_Write(g_config.dev_addr, BMP280_REG_CTRL_MEAS, &ctrl_meas, 1)) {
        return 0;
    }
    // 等待配置生效
    for (volatile int i = 0; i < 5000; i++);
    
    return 1;
}
//初始化
u8 BMP280_Init(BMP280_Config_t *config)
{
    // 检查芯片是否存在
    if (BMP280_GetChipID() != BMP280_CHIP_ID) return 0;
    // 读取校准数据
    if (!BMP280_ReadCalibration()) return 0;
    // 配置传感器
    if (!BMP280_SetConfig(config)) return 0;
    return 1;
}
//读出原始数据
u8 BMP280_ReadRawData(int32_t *raw_temp, int32_t *raw_press)
{
    uint8_t data[8] = {0};
    
    // 读取所有数据 (从0xF7开始连续读8字节)
    if (I2C_Read(g_config.dev_addr, BMP280_REG_PRESS_MSB, data, 6)) 
        return 0;
		
    // 气压: 20bit (MSB, LSB, XLSB[7:4])
    *raw_press = (int32_t)(((uint32_t)data[0] << 12) | 
                           ((uint32_t)data[1] << 4) | 
                           ((uint32_t)data[2] >> 4));
    
    // 温度: 20bit (MSB, LSB, XLSB[7:4])
    *raw_temp = (int32_t)(((uint32_t)data[3] << 12) | 
                          ((uint32_t)data[4] << 4) | 
                          ((uint32_t)data[5] >> 4));
    
    return 1;
}
//双精度计算温度
double bmp280_compensate_T_double(int32_t adc_T)
{
    double var1, var2, T;
    
    var1 = (((double)adc_T) / 16384.0 - ((double)g_calib.dig_T1) / 1024.0) * ((double)g_calib.dig_T2);
    var2 = ((((double)adc_T) / 131072.0 - ((double)g_calib.dig_T1) / 8192.0) *
            (((double)adc_T) / 131072.0 - ((double)g_calib.dig_T1) / 8192.0)) * ((double)g_calib.dig_T3);
    
    t_fine = var1 + var2;
    T = (var1 + var2) / 5120.0;
    return T;
}
//双精度计算压力
double bmp280_compensate_P_double(int32_t adc_P)
{
    double var1, var2, p;
    
    var1 = ((double)t_fine / 2.0) - 64000.0;
    var2 = var1 * var1 * ((double)g_calib.dig_P6) / 32768.0;
    var2 = var2 + var1 * ((double)g_calib.dig_P5) * 2.0;
    var2 = (var2 / 4.0) + (((double)g_calib.dig_P4) * 65536.0);
    
    var1 = (((double)g_calib.dig_P3) * var1 * var1 / 524288.0 + ((double)g_calib.dig_P2) * var1) / 524288.0;
    var1 = (1.0 + var1 / 32768.0) * ((double)g_calib.dig_P1);
    
    if (var1 == 0.0) {
        return 0.0;  // ????
    }
    
    p = 1048576.0 - (double)adc_P;
    p = (p - (var2 / 4096.0)) * 6250.0 / var1;
    
    var1 = ((double)g_calib.dig_P9) * p * p / 2147483648.0;
    var2 = p * ((double)g_calib.dig_P8) / 32768.0;
    p = p + (var1 + var2 + ((double)g_calib.dig_P7)) / 16.0;
    
    return p;
}
//计算海拔
float BMP280_CalculateAltitude(float pressure, float sea_level_pressure)
{
    if (sea_level_pressure == 0) 
		{
        sea_level_pressure = 101325.0f;  // 标准大气压
    }
    return 44330.0f * (1.0f - powf(pressure / sea_level_pressure, 1.0f / 5.255f));
}
//主函数循环读取
u8 BMP280_ReadData(BMP280_Data_t *result)
{
    int32_t raw_temp = 0;
    int32_t raw_press = 0;
    
    if (result == NULL) return 0;
    
    // 读取原始数据
    if (!BMP280_ReadRawData(&raw_temp, &raw_press)) return 0;
    
    // 补偿计算
    result->temperature = bmp280_compensate_T_double(raw_temp);
    result->pressure = bmp280_compensate_P_double(raw_press);
    
    return 1;
}
//打印数据
void BMP280_PrintCalib(void)
{
    printf("=== BMP280 ???? ===\r\n");
    printf("dig_T1 = %u\r\n", g_calib.dig_T1);
    printf("dig_T2 = %d\r\n", g_calib.dig_T2);
    printf("dig_T3 = %d\r\n", g_calib.dig_T3);
    printf("dig_P1 = %u\r\n", g_calib.dig_P1);
    printf("dig_P2 = %d\r\n", g_calib.dig_P2);
    printf("dig_P3 = %d\r\n", g_calib.dig_P3);
    printf("dig_P4 = %d\r\n", g_calib.dig_P4);
    printf("dig_P5 = %d\r\n", g_calib.dig_P5);
    printf("dig_P6 = %d\r\n", g_calib.dig_P6);
    printf("dig_P7 = %d\r\n", g_calib.dig_P7);
    printf("dig_P8 = %d\r\n", g_calib.dig_P8);
    printf("dig_P9 = %d\r\n", g_calib.dig_P9);
}
c 复制代码
void Iic_Gpio_Init()
{
	GPIO_InitTypeDef  GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	 
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13;				 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; 		 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 
	GPIO_Init(GPIOB, &GPIO_InitStructure);					 
	GPIO_SetBits(GPIOB,GPIO_Pin_12|GPIO_Pin_13);						
}

void IIC_Start(void)
{    
	IIC_SDA=1;	  	  
	IIC_SCL=1;
	delay_us(2);
 	IIC_SDA=0;     
	delay_us(2);
	IIC_SCL=0;   
	delay_us(2);  
}
void IIC_Stop(void)
{
	IIC_SCL=0;
	IIC_SDA=0;
 	delay_us(2);
	IIC_SCL=1;
	delay_us(2);	
	IIC_SDA=1;
	delay_us(2);							   	
}
u8 IIC_Wait_Ack(void)
{
	u8 ucErrTime=0;    
	IIC_SDA=1;
	IIC_SCL=0;
	delay_us(2);	   
	IIC_SCL=1;
	delay_us(2);	 
	while(READ_SDA)
	{
		ucErrTime++;
		if(ucErrTime>250)
		{
			IIC_Stop();
			return 0;
		}
	}
	delay_us(2);	
	IIC_SCL=0;	 
	delay_us(2);  
	return 0;  
} 
void IIC_Ack(void)
{
	IIC_SDA=0;
	IIC_SCL=0;
	delay_us(2);
	IIC_SCL=1;
	delay_us(4);
	IIC_SCL=0;
	delay_us(2);
}
void IIC_NAck(void)
{
	IIC_SDA=1;
	IIC_SCL=0;
	delay_us(2);
	IIC_SCL=1;
	delay_us(4);
	IIC_SCL=0;
	delay_us(2);
}
u8 IIC_Send_Byte(u8 txd)
{                        
  u8 t;       
  IIC_SCL=0;
  for(t=0;t<8;t++)    
  {              
		if((txd&0x80)>>7)IIC_SDA=1;
		else IIC_SDA=0;
		txd<<=1; 	  
		delay_us(2);   
		IIC_SCL=1;
		delay_us(4); 
		IIC_SCL=0;	
		delay_us(2);
  }	 
	return IIC_Wait_Ack();
} 	
u8 IIC_Read_Byte(u8 ack)
{
	unsigned char i,receive=0;
	IIC_SCL=0;
	IIC_SDA=1;
  for(i=0;i<8;i++ )
	{
    delay_us(2);
		IIC_SCL=1;
		delay_us(2);
    receive<<=1;
    if(READ_SDA)receive++;   
		delay_us(2); 
		IIC_SCL=0; 
		delay_us(2); 
  }					 
  if (!ack)IIC_NAck();
  else IIC_Ack(); 
  return receive;
}


u8 I2C_Write(u8 dev_addr, u8 reg_addr,u8 *data, u8 len)
{
  u8 i, result = 0;
	IIC_Start();
	//
	result=IIC_Send_Byte(dev_addr << 1);
	if(result != 0) return result;
	//
	result=IIC_Send_Byte(reg_addr);
	if(result != 0) return result;
	//
	for (i=0; i<len; i++)
	{
		result=IIC_Send_Byte(data[i]);
		if (result != 0) return result;
	}
	IIC_Stop();
	return 0x00;
}
u8 I2C_Read(u8 dev_addr, u8 reg_addr,u8 *data, u8 len)
{
	uint8_t result;

	IIC_Start();
	result  = IIC_Send_Byte(dev_addr << 1);
	if(result != 0) return result;
	//
	result = IIC_Send_Byte(reg_addr);
	if(result != 0) return result;
	//
	IIC_Start();
	result = IIC_Send_Byte(dev_addr << 1 | 0x01);
	if(result != 0) return result;
	//
  while (len)
	{
		if (len == 1)*data = IIC_Read_Byte(0);
		else *data = IIC_Read_Byte(1);
    data ++;
    len --;
	}
	IIC_Stop();
  return 0x00;
}
//
相关推荐
星河单片机23 分钟前
STM32+VK2828U7G5模块GPS定位+NMEA解析
stm32·单片机·嵌入式硬件
白搞电子24 分钟前
ESP-Mosaico 掌上游戏开发:LVGL 抛硬币动画、音频混音与 BMI270 摇晃触发
单片机·嵌入式硬件·物联网·游戏·音视频
深圳市恒锐丰科技杨生25 分钟前
EG1163 (S) 高压大电流降压同步整流 DC‑DC 控制器|外置 MOS 降压电源方案
嵌入式硬件·硬件工程
安河桥。42 分钟前
V4L2架构在工程实践中的应用
嵌入式硬件·音视频
启芯硬件1 小时前
《硬件电路设计实战100例》专栏核心信息,定位及设计案例分享
人工智能·经验分享·嵌入式硬件·硬件工程·高速仿真
深圳市恒锐丰科技杨生1 小时前
EG1162 高压大电流降压同步整流 DC‑DC 控制器|外置 MOS 降压电源方案
嵌入式硬件·硬件工程
Yiran_G2 小时前
LoRa在智慧农业中的应用:无线传感网络如何实现远程环境监测?
嵌入式硬件·物联网
佳児素花痴╮2 小时前
STM32U575RIT6(SPI+数码管+LED)
stm32·单片机·嵌入式硬件
艾芯微科技2 小时前
B1040A2|DFN1006‑2L 超微型肖特基二极管,便携设备高频整流优选国产器件
网络·单片机·嵌入式硬件·集成测试·51单片机