BMP280 气压传感器
1.
2.
//默认配置
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);
}
// 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
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);
}
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;
}
//