目录
[✅ 1. 硬件清单(精准罗列,新手无采购误区)](#✅ 1. 硬件清单(精准罗列,新手无采购误区))
[✅ 2. BMP280 传感器核心特点与工作原理](#✅ 2. BMP280 传感器核心特点与工作原理)
[(1)BMP280 核心特性](#(1)BMP280 核心特性)
[✅ 3. OLED 显示原理](#✅ 3. OLED 显示原理)
[✅ 1. 引脚定义说明](#✅ 1. 引脚定义说明)
[(1)BMP280 模块核心引脚(I2C 模式)](#(1)BMP280 模块核心引脚(I2C 模式))
[(2)OLED 模块核心引脚](#(2)OLED 模块核心引脚)
[✅ 2. 完整接线表(STM32F103C8T6,通用无错)](#✅ 2. 完整接线表(STM32F103C8T6,通用无错))
[✅ 接线注意事项(新手必看,避坑指南)](#✅ 接线注意事项(新手必看,避坑指南))
[✅ 1. 开发环境](#✅ 1. 开发环境)
[✅ 2. STM32CubeMX 配置步骤(图文式步骤,零基础能看懂)](#✅ 2. STM32CubeMX 配置步骤(图文式步骤,零基础能看懂))
[步骤 1:新建工程,选择芯片](#步骤 1:新建工程,选择芯片)
[步骤 2:基础配置(必做)](#步骤 2:基础配置(必做))
[步骤 3:配置硬件 I2C1](#步骤 3:配置硬件 I2C1)
[步骤 4:配置系统时钟树](#步骤 4:配置系统时钟树)
[步骤 5:生成工程代码](#步骤 5:生成工程代码)
[✅ 步骤 1:导入 0.96 寸 OLED 驱动代码](#✅ 步骤 1:导入 0.96 寸 OLED 驱动代码)
[✅ 步骤 2:编写 BMP280 传感器驱动代码(核心)](#✅ 步骤 2:编写 BMP280 传感器驱动代码(核心))
[✅ 代码编译注意事项(新手必看,解决编译报错)](#✅ 代码编译注意事项(新手必看,解决编译报错))
[✅ 1. 编译下载程序](#✅ 1. 编译下载程序)
[✅ 2. 测试效果](#✅ 2. 测试效果)
[❌ 问题 1:OLED 屏幕无任何显示](#❌ 问题 1:OLED 屏幕无任何显示)
[❌ 问题 2:BMP280 初始化失败(程序卡死在 while (1))](#❌ 问题 2:BMP280 初始化失败(程序卡死在 while (1)))
[❌ 问题 3:气压数据显示异常(如气压 0hPa)](#❌ 问题 3:气压数据显示异常(如气压 0hPa))
[❌ 问题 4:数据显示乱码、跳动严重](#❌ 问题 4:数据显示乱码、跳动严重)
本文将详细讲解如何使用STM32F103C8T6 单片机,通过I2C 通信方式驱动 BMP280 高精度气压,大气压强数据,并通过算法精准计算海拔高度,最终将所有数据实时显示在 0.96 寸 I2C OLED 屏幕上。教程基于 STM32 HAL 库开发,代码完整可直接复用、步骤清晰易懂、注释详尽,适合零基础入门学习,也可直接用于气象站、高度计、无人机定高、环境监测等嵌入式项目开发。

一、硬件准备与核心原理说明
✅ 1. 硬件清单(精准罗列,新手无采购误区)
| 器件名称 | 数量 | 重要备注 |
|---|---|---|
| STM32F103C8T6 最小系统板 | 1 | 核心主控,本文所有代码基于此型号开发 |
| BMP280 传感器模块 | 1 | 数字型传感器,I2C/SPI 双模,本文用 I2C 模式 |
| 0.96 寸 I2C OLED 显示屏 | 1 | 分辨率 128*64,SSD1306 驱动芯片,4 针款 |
| 杜邦线 | 若干 | 公对母 / 公对公均可,建议备 10 根以上 |
| 5V/3.3V 供电电源 | 1 | USB 数据线供电即可,给 STM32 最小系统板供电 |
小提示:BMP280 是 BMP180 的升级款,精度更高、功耗更低,两款传感器驱动逻辑类似,本教程代码稍作修改即可兼容 BMP180。
✅ 2. BMP280 传感器核心特点与工作原理
(1)BMP280 核心特性
- 通信方式:硬件 I2C / SPI 双接口,本教程选用 I2C(两线通信,接线简单,可与 OLED 共用 I2C 引脚);
- 检测参数:精准温度 + 大气压强(部分商家标注的湿度为模块集成,BMP280 本体只测压);
- 测量精度:气压 ±1hPa,海拔高度 ±1 米,满足日常 / 项目开发所有需求;
- 量程范围:气压 300hPa~1100hPa(对应海拔 - 500 米~9000 米);
- 供电电压:3.3V(推荐),部分模块兼容 5V,建议用 3.3V 和 STM32 电平匹配,避免烧毁传感器;
- I2C 默认地址:
0x76(传感器 SDO 引脚接 GND 时),若 SDO 接 VCC 则地址为0x77。
(2)核心计算公式
BMP280 采集的是原始数据,需通过公式换算成实际物理值,所有公式已封装在代码中,无需手动计算:
- 气压:基于校准后的温度,补偿计算出实际大气压强(hPa,1hPa=1 百帕 = 100Pa);
- 海拔高度:通过当前气压和海平面标准气压(1013.25hPa) 换算,公式如下:海拔当前气压海平面气压
✅ 3. OLED 显示原理
0.96 寸 OLED 屏采用 SSD1306 驱动芯片,同样为 I2C 通信接口,OLED 的默认 I2C 地址为 0x78(部分为 0x7A)。
关键优势:BMP280 和 OLED 的 I2C 地址不同,因此可以共用 STM32 的同一个 I2C 外设,仅需 2 根线即可同时驱动两个设备,极大简化硬件接线!
二、硬件接线(重中之重,精准无错版)
✅ 1. 引脚定义说明
(1)BMP280 模块核心引脚(I2C 模式)
VCC:供电引脚,接 3.3V(优先推荐);GND:接地引脚,必须和 STM32、OLED 共地;SCL:I2C 时钟线;SDA:I2C 数据线;SDO:I2C 地址配置脚,接 GND 即可,对应地址 0x76;CSB:SPI/I2C 模式选择脚,接 VCC 为 I2C 模式(接 GND 为 SPI 模式,本文不用);SCK/SDI:SPI 引脚,I2C 模式下悬空即可。
(2)OLED 模块核心引脚
VCC:3.3V 供电;GND:共地;SCL:I2C 时钟线;SDA:I2C 数据线。
✅ 2. 完整接线表(STM32F103C8T6,通用无错)
本文选用 STM32 的硬件 I2C1 ,引脚为 PB6 = SCL 、PB7 = SDA,两个设备完全共用这组引脚,接线如下,建议对照接线,避免接错:
| 外设引脚 | STM32 引脚 | 接线说明 |
|---|---|---|
| BMP280-VCC | 3.3V | 传感器供电,严禁接 5V 长期使用 |
| BMP280-GND | GND | 与 STM32、OLED 共地(必须!) |
| BMP280-SCL | PB0 | I2C时钟线 |
| BMP280-SDA | PB1 | I2C数据线 |
| BMP280-SDO | GND | 配置地址 0x76 |
| BMP280-CSB | VCC | 启用 I2C 模式 |
| OLED-VCC | 3.3V | 屏幕供电 |
| OLED-GND | GND | 共地 |
| OLED-SCL | PB6 | I2C时钟线 |
| OLED-SDA | PB7 | I2C数据线 |
✅ 接线注意事项(新手必看,避坑指南)
- 所有设备必须共地,否则 I2C 通信会出现乱码、设备失联等问题;
- BMP280 优先接 3.3V,部分 5V 供电的模块内置稳压,但若直接接 5V 可能导致传感器发热、精度下降;
- 严禁将 SCL 和 SDA 引脚接反,接反后设备无法通信,OLED 无显示、传感器初始化失败;
- 杜邦线尽量短,避免过长导致信号干扰,影响数据稳定性。
三、软件准备(开发环境配置)
✅ 1. 开发环境
- 图形化配置工具:STM32CubeMX 6.x 版本
- 编译下载工具:Keil MDK-ARM 5.x 版本
- 程序下载器:ST-Link(或 USB 转串口,推荐 ST-Link,下载稳定)
✅ 2. STM32CubeMX 配置步骤(图文式步骤,零基础能看懂)
步骤 1:新建工程,选择芯片
打开 STM32CubeMX → 点击Access to MCU Selector → 搜索STM32F103C8T6 → 选中芯片后点击Start Project。
步骤 2:基础配置(必做)
- 配置 RCC 时钟:点击左侧
RCC→ 高速外部时钟HSE选择Crystal/Ceramic Resonator(8MHz 晶振); - 配置调试接口:点击左侧
SYS→ 调试模式选择Serial Wire(SWD),方便后续下载和调试程序。
步骤 3:配置硬件 I2C1
- 仅需配置OLED的SDA和SCL、BMP280的SDA和SCL。
步骤 4:配置系统时钟树
将 STM32 系统时钟配置为72MHz(F103 的最大主频,性能最佳):
- HSE 选择 8MHz → PLL 倍频系数设为 9 → 系统时钟 = 8*9=72MHz;
- AHB 分频系数 1,APB1 分频系数 2,APB2 分频系数 1;
- 点击
Refresh,确认时钟配置无误,无红色报错。
步骤 5:生成工程代码
- 点击顶部
Project Manager→ 设置工程名称(如BMP280_OLED)、保存路径(路径不能有中文和空格); - 工具链选择
MDK-ARM,勾选Generate peripheral initialization as a pair of .c/.h files per peripheral; - 点击
GENERATE CODE生成代码,生成完成后点击Open Project直接打开 Keil 工程。
四、完整代码编写(可直接复制,注释详尽)
本次代码采用模块化开发,结构清晰,分为三部分:① 导入 OLED 驱动代码 ② 编写 BMP280 驱动代码 ③ 编写主函数实现数据采集与显示,所有代码无冗余,新手可直接复制使用。
✅ 步骤 1:导入 0.96 寸 OLED 驱动代码
0.96 寸 I2C OLED 的驱动基于 SSD1306 芯片,为通用驱动,无需修改,直接在工程中添加两个文件即可:
- 在 Keil 工程的
Src目录下新建oled.c,Inc目录下新建oled.h; - 将 SSD1306 的 I2C 驱动代码复制到这两个文件中(网上可下载通用版,核心功能:初始化、清屏、显示字符、显示字符串)。
关键提示:OLED 的默认 I2C 地址为
0x78,若屏幕无显示,可在 oled.h 中修改为0x7A重试。
✅ 步骤 2:编写 BMP280 传感器驱动代码(核心)
在工程中新建两个文件:bmp280.c(放入 Src 目录)和bmp280.h(放入 Inc 目录),这两个文件是 BMP280 的核心驱动,包含初始化、校准参数读取、温压数据读取、海拔计算等所有功能。
BMP280.c
cs
void BMP280GetData(float* pressure,float* temperature,float* asl)
{
static float t;
static float p;
bmp280GetPressure();
t=bmp280CompensateT(bmp280RawTemperature)/100.0;
p=bmp280CompensateP(bmp280RawPressure)/25600.0;
presssureFilter(&p,pressure);
*temperature=(float)t; /*单位度*/
*pressure=(float)p ; /*单位hPa*/
*asl=bmp280PressureToAltitude(pressure); /*转换成海拔*/
}
#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.
// TLDR: Adjusting for temp changes does more harm than good.
/*
* Converts pressure to altitude above sea level (ASL) in meters
*/
static float bmp280PressureToAltitude(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;
}
}
BMP280.h
cs
/**
****************************************************************************************************
* @file bmp280.h
* @author 送外卖的工程师
* @version V1.0
* @date 2025-12-27
* @brief BMP280驱动代码
****************************************************************************************************
* @attention
*
* 实验平台:STM32F103C8T6
* CSDN:送外卖的工程师
* 技术指导VX:wmz14026
* 淘宝店铺:小马科技
* 闲鱼店铺:送外卖的工程师
*
* 修改说明
* V1.0.0.251227
* 第一次发布
* 注:长期接各种项目设计,提供仿真、实物、原理图、PCB、代码工程、后期指导、操作视频、
说明文档、各种报告、后期指导等。
****************************************************************************************************
*/
#ifndef __BMP280_H
#define __BMP280_H
#include "main.h"
#include "stdbool.h"
//==============================================BMP280硬件接口==================================================
#define BMP280_IIC_RCC_EN_CLK __HAL_RCC_GPIOB_CLK_ENABLE();
#define BMP280_IIC_PORT GPIOB
#define BMP280_IIC_SCL_PIN GPIO_PIN_0
#define BMP280_IIC_SDA_PIN GPIO_PIN_1
#define BMP280_IIC_SCL(x) HAL_GPIO_WritePin(BMP280_IIC_PORT, BMP280_IIC_SCL_PIN,(GPIO_PinState)(x))
#define BMP280_IIC_SDA(x) HAL_GPIO_WritePin(BMP280_IIC_PORT, BMP280_IIC_SDA_PIN,(GPIO_PinState)(x))
#define BMP280_READ_SDA HAL_GPIO_ReadPin(BMP280_IIC_PORT, BMP280_IIC_SDA_PIN)//输入SDA
//=============================================================================================================
#define BMP280_ADDR (0xEC)
#define BMP280_DEFAULT_CHIP_ID (0x58)
#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 */
#define BMP280_SLEEP_MODE (0x00)
#define BMP280_FORCED_MODE (0x01)
#define BMP280_NORMAL_MODE (0x03)
#define BMP280_TEMPERATURE_CALIB_DIG_T1_LSB_REG (0x88)
#define BMP280_PRESSURE_TEMPERATURE_CALIB_DATA_LENGTH (24)
#define BMP280_DATA_FRAME_SIZE (6)
#define BMP280_OVERSAMP_SKIPPED (0x00)
#define BMP280_OVERSAMP_1X (0x01)
#define BMP280_OVERSAMP_2X (0x02)
#define BMP280_OVERSAMP_4X (0x03)
#define BMP280_OVERSAMP_8X (0x04)
#define BMP280_OVERSAMP_16X (0x05)
//IIC所有操作函数
void BMP_IIC_Init(void); //初始化IIC的IO口
void BMP_IIC_Start(void); //发送IIC开始信号
void BMP_IIC_Stop(void); //发送IIC停止信号
void BMP_IIC_Send_Byte(uint8_t txd); //IIC发送一个字节
uint8_t BMP_IIC_Read_Byte(unsigned char ack); //IIC读取一个字节
uint8_t BMP_IIC_Wait_Ack(void); //IIC等待ACK信号
void BMP_IIC_Ack(void); //IIC发送ACK信号
void BMP_IIC_NAck(void); //IIC不发送ACK信号
void IIC_Write_One_Byte(uint8_t daddr,uint8_t addr,uint8_t data);
uint8_t IIC_Read_One_Byte(uint8_t daddr,uint8_t addr);
uint8_t iicDevReadByte(uint8_t devaddr,uint8_t addr); /*读一字节*/
void iicDevWriteByte(uint8_t devaddr,uint8_t addr,uint8_t data); /*写一字节*/
void iicDevRead(uint8_t devaddr,uint8_t addr,uint8_t len,uint8_t *rbuf); /*连续读取多个字节*/
void iicDevWrite(uint8_t devaddr,uint8_t addr,uint8_t len,uint8_t *wbuf); /*连续写入多个字节*/
bool BMP280Init(void);
void BMP280GetData(float* pressure, float* temperature, float* asl);
#endif
✅ 代码编译注意事项(新手必看,解决编译报错)
编译代码时,新手大概率会遇到 2 个报错,以下是解决方案,必须配置,否则编译失败:
- 开启微库(Use MicroLIB) :Keil 中点击
Options for Target→Target→ 勾选Use MicroLIB,解决sprintf格式化浮点数报错; - 链接数学库 :点击
Options for Target→Editor→Misc Controls,输入--cpu Cortex-M3 -lm,解决pow(幂函数)、sqrt等数学函数未定义的报错; - 若提示
OLED_xxx函数未定义,检查 OLED 驱动文件是否正确添加到工程中,头文件是否包含。
五、程序下载与测试效果
✅ 1. 编译下载程序
- 在 Keil 中点击
Build编译代码,无报错后点击Download下载程序到 STM32; - 下载完成后,给 STM32 供电,此时 OLED 屏幕会点亮。
✅ 2. 测试效果
- OLED 屏幕会显示标题、实时大气压强,显示稳定;
- 抬起传感器,海拔高度会增加,放下则减少,数据变化符合实际物理规律;
- 正常环境下,气压值在 1000~1020hPa 之间,海拔根据当地实际高度显示。

六、常见问题解决(新手避坑,最全解决方案)
这部分是重中之重,新手在调试时大概率会遇到以下问题,所有问题均为实测中出现的高频问题,解决方案精准有效:
❌ 问题 1:OLED 屏幕无任何显示
- 检查 OLED 的 VCC 和 GND 是否接对,确保 3.3V 供电正常;
- 确认 OLED 的 I2C 地址是
0x78还是0x7A,在 oled.h 中修改地址重试; - 检查 SCL 和 SDA 引脚是否接反,PB6=SCL,PB7=SDA,接反后无显示;
- 所有设备必须共地,无共地则 I2C 通信失败。
❌ 问题 2:BMP280 初始化失败(程序卡死在 while (1))
- 传感器供电问题:BMP280 必须接 3.3V,接 5V 可能导致传感器烧毁,无法通信;
- I2C 地址错误:SDO 接 GND 地址是 0x76(写地址 0xEE),接 VCC 是 0x77(写地址 0xF0),在 bmp280.h 中修改地址;
- SCL/SDA 引脚接反,或传感器未共地;
- 传感器硬件损坏:更换 BMP280 模块重试。
❌ 问题 3:气压数据显示异常(如气压 0hPa)
- 未读取校准参数:BMP280 必须读取校准参数才能计算出正确数据,检查代码;
- 传感器未进入工作模式:检查
BMP280_CTRL_MEAS寄存器的配置值是否为 0x77; - 数据读取顺序错误:BMP280 的温压数据是 6 个字节,必须按顺序读取,不能拆分。
❌ 问题 4:数据显示乱码、跳动严重
- 杜邦线过长,导致信号干扰,更换短的杜邦线;
- 电源纹波过大,给传感器的 VCC 引脚并联一个 0.1μF 的滤波电容;
- 延时时间过短,增大
HAL_Delay(200)的数值,降低刷新频率。
七、功能扩展(进阶开发,可选)
本教程实现了基础的气压采集与显示,可根据需求轻松扩展以下功能,适合项目升级:
- 串口打印数据:添加 USART 串口配置,将气压数据通过串口打印到电脑串口助手,便于数据记录;
- 气压预警功能:当气压低于 980hPa 时,通过 GPIO 控制 LED 闪烁,实现低气压预警;
- 多传感器联合采集:搭配 DHT11/DHT22 温湿度传感器,同时显示温度、湿度、气压、海拔,打造完整气象站。