[STM32F1] 基于STM32F103的BMP280使用指南

[复制链接]
107|0
磨砂 发表于 2025-8-15 11:09 | 显示全部楼层 |阅读模式
一、核心特性与性能参数
测量能力
​气压测量​:范围300–1100 hPa(相当于海拔-500m至+9000m),相对精度±0.12 hPa(等效±1米高度差),绝对精度±1 hPa(0–40℃)。
​温度测量​:范围-40℃至+85℃,分辨率0.01℃,用于实时补偿气压漂移(温漂系数1.5 Pa/K)。
功耗与封装
​超低功耗​:典型电流仅2.7μA(1Hz采样率),休眠模式低至0.1μA,适合电池供电设备(如智能手表、四轴飞行器)。
​微型封装​:8引脚LGA金属盖封装,尺寸2.0×2.5×0.95mm²,为移动设备(手机、GPS模块)优化空间占用。
接口与通信
支持​I²C​(最高3.4 MHz)和​SPI​(四线/三线模式,最高10 MHz)双协议,I²C地址可通过SDO引脚配置(0x76或0x77),方便多设备并联。
应用场景








二、硬件连接




模块引脚定义




注意事项

VCC → 3.3V(切勿接5V)
SDO → GND(I²C地址设为0xEC)
SDO → 3.3V(I²C地址设为0xEE)
CSB → 3.3V(禁用SPI模式)
复位时若CSB出现低电平会导致I²C失效,需重新上电。
焊接时避免长时间加热,防止芯片损坏。
三、软件驱动配置(IIC模式)
1. 初始化IIC
I2C_HandleTypeDef hi2c1;

void MX_I2C1_Init(void)
{

  hi2c1.Instance = I2C1;
  hi2c1.Init.ClockSpeed = 100000;
  hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
  hi2c1.Init.OwnAddress1 = 0;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
    Error_Handler();
  }

}


2. 宏定义命令
#if 1 //SDD电压
#define BMP280_ADDR                         (0xEC)
#else
#define BMP280_ADDR                         (0xEE)
#endif

#define BMP280_CHIP_ID                      (0xD0)              /* Chip ID Register */
#define BMP280_RST_REG                      (0xE0)              /* Softreset Register */
#define BMP280_STAT_REG                     (0xF3)              /* Status Register */
#define BMP280_CTRL_MEAS_REG                (0xF4)              /* Ctrl Measure Register */
#define BMP280_CONFIG_REG                   (0xF5)              /* Configuration Register */
#define BMP280_PRESSURE_MSB_REG             (0xF7)              /* Pressure MSB Register */
#define BMP280_PRESSURE_LSB_REG             (0xF8)              /* Pressure LSB Register */
#define BMP280_PRESSURE_XLSB_REG            (0xF9)              /* Pressure XLSB Register */
#define BMP280_TEMPERATURE_MSB_REG          (0xFA)              /* Temperature MSB Reg */
#define BMP280_TEMPERATURE_LSB_REG          (0xFB)              /* Temperature LSB Reg */
#define BMP280_TEMPERATURE_XLSB_REG         (0xFC)              /* Temperature XLSB Reg */

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 */
    s32 t_fine;                                                 /* calibration t_fine data */
} bmp280Calib;



3. 关键寄存器配置表




四、关键操作代码实现(HAL库实现)
读取ID

uint8_t BMP280_ReadID(void)
{
    uint8_t Data[1];
    HAL_I2C_Master_Transmit(&hi2c1, BMP280_ADDR , BMP280_CHIP_ID, 0x01, HAL_MAX_DELAY);
    HAL_I2C_Master_Receive(&hi2c1, BMP280_ADDR , Data, 0x01, HAL_MAX_DELAY);
    return Data[0];
}


复位

void BMP280_Reset(void)
{
    HAL_I2C_Mem_Write(&hi2c1, BMP280_ADDR , BMP280_RST_REG, 0x01, 0xB6, 0x01, HAL_MAX_DELAY);
}


设置测量寄存器

void BMP280_SetCtrlMeas()
{
    HAL_I2C_Mem_Write(&hi2c1, BMP280_ADDR , BMP280_CTRL_MEAS_REG, 0x01, 0xFC, 0x01, HAL_MAX_DELAY);
}


配置滤波寄存器

void BMP280_SetConfig()
{
    HAL_I2C_Mem_Write(&hi2c1, BMP280_ADDR , BMP280_CONFIG_REG, 0x01, 0x00, 0x01, HAL_MAX_DELAY);
}


读取补偿寄存器

bmp280Calib  bmp280Cal;
void BMP280_GetTrimmingParameter()
{
    HAL_I2C_Master_Transmit(&hi2c1, BMP280_ADDR , 0x88, 0x01, HAL_MAX_DELAY);
    HAL_I2C_Master_Receive(&hi2c1, BMP280_ADDR , (uint8_t *)bmp280Cal, 0x14, HAL_MAX_DELAY);
}


读取气压(3字节:0xF7~0xF9)

int32_t BMP280_GetPress(void)
{
    uint8_t Data[3];
    HAL_I2C_Master_Transmit(&hi2c1, BMP280_ADDR , BMP280_PRESSURE_MSB_REG, 0x01, HAL_MAX_DELAY);
    HAL_I2C_Master_Receive(&hi2c1, BMP280_ADDR , Data, 0x03, HAL_MAX_DELAY);
    return (s32)(((uint32_t)data[0]<<12) | ((uint32_t)data[1]<<4) | ((uint32_t)data[2]>>4))
}


读取温度(3字节:0xFA~0xFC)

int32_t BMP280_GetTemp(void)
    {
        uint8_t Data[3];
        HAL_I2C_Master_Transmit(&hi2c1, BMP280_ADDR , BMP280_TEMPERATURE_MSB_REG, 0x01, HAL_MAX_DELAY);
        HAL_I2C_Master_Receive(&hi2c1, BMP280_ADDR , Data, 0x03, HAL_MAX_DELAY);
        return (s32)(((uint32_t)data[0]<<12) | ((uint32_t)data[1]<<4) | ((uint32_t)data[2]>>4))
    }


校准计算

需提前读取校准参数(地址0x88~0xA1),包括dig_T1~T3(温度)和dig_P1~P9(气压)。
五、应用案例
1.温度补偿

static s32 bmp280CompensateT(s32 adcT)
{
    s32 var1,var2,T;

    var1=((((adcT>>3)-((s32)bmp280Cal.dig_T1<<1)))*((s32)bmp280Cal.dig_T2))>>11;
    var2=(((((adcT>>4)-((s32)bmp280Cal.dig_T1))*((adcT>>4)-((s32)bmp280Cal.dig_T1)))>>12)*((s32)bmp280Cal.dig_T3))>>14;
    bmp280Cal.t_fine = var1 + var2;

    T = (bmp280Cal.t_fine*5+128)>>8;

    return T;
}




2.压强补偿

static uint32_t bmp280CompensateP(s32 adcP)
{
    int64_t var1,var2,p;
    var1=((int64_t)bmp280Cal.t_fine)-128000;
    var2=var1*var1*(int64_t)bmp280Cal.dig_P6;
    var2=var2+((var1*(int64_t)bmp280Cal.dig_P5)<<17);
    var2=var2+(((int64_t)bmp280Cal.dig_P4)<<35);
    var1=((var1*var1*(int64_t)bmp280Cal.dig_P3)>>8)+((var1*(int64_t)bmp280Cal.dig_P2)<<12);
    var1=(((((int64_t)1)<<47)+var1))*((int64_t)bmp280Cal.dig_P1)>>33;
    if (var1==0)
        return 0;
    p=1048576-adcP;
    //p=((p<<31)-var2*3125)/var1;
    p=(((p<<31)-var2)*3125)/var1;//???
    var1=(((int64_t)bmp280Cal.dig_P9)*(p>>13)*(p>>13))>>25;
    var2=(((int64_t)bmp280Cal.dig_P8)*p)>>19;
    p=((p+var1+var2)>>8)+(((int64_t)bmp280Cal.dig_P7)<<4);
    return(uint32_t)p;
}



3.主函数

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    IIC_Init();
    USART_Init(); // 串口初始化

    printf("BMP280 ID IS: 0x%X\n",BMP280_ReadID());
    BMP280_GetTrimmingParameter();
    BMP280_SetCtrlMeas();
    BMP280_SetConfig();
    while(1) {
    // 主循环
        float temperature=bmp280CompensateT(BMP280_GetTemp())/1.0;      /*单位度*/
        printf("temperature = %0.2f ℃", temperature);

        static uint32_t p=bmp280CompensateP(BMP280_GetPress());
        float pressure=(float)(p>>8) + ((float)(p&0xFF) / 256.0);       /*单位hPa*/
        printf("pressure= %0.2f hPa", pressure);
    }
}


六、调试与常见问题
无数据输出

检查硬件:确保SDO接地、CSB接3.3V。
复位后需重新上电,避免CSB电平异常。
用逻辑分析仪抓取I²C/SPI波形,确认时序正确。
数据异常

校准参数需按小端序组合(LSB在前)。
温度值错误可能导致气压计算偏差,优先调试温度读取。
海拔换算公式

float altitude = 44330.0 * (1.0 - pow(pressure / 101325.0, 0.1903));
————————————————
版权声明:本文为CSDN博主「谱写秋天」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42222415/article/details/150221256

您需要登录后才可以回帖 登录 | 注册

本版积分规则

121

主题

4363

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部