0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

零知开源——STM32F1驱动BMP581压强传感器使用SPI实现ST7789显示的环境监测系统

零知实验室 来源:PCB56242069 作者:PCB56242069 2025-07-03 16:39 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

✔零知开源是一个真正属于国人自己的开源软硬件平台,在开发效率上超越了Arduino平台并且更加容易上手,大大降低了开发难度。零知开源在软件方面提供了完整的学习教程和丰富示例代码,让不懂程序的工程师也能非常轻而易举的搭建电路来创作产品,测试产品。快来动手试试吧!

✔访问零知开源平台,获取更多实战项目和教程资源吧!

(1)项目概述

本文将详细介绍如何在零知标准板上实现BMP581气压传感器与ST7789显示屏的协同工作,重点解决SPI总线冲突问题,并展示环境数据的实时监测显示。实现以下系统功能:

>实时采集温度和气压数据
>计算并显示海拔高度
>在240x320彩色显示屏上直观展示数据

>通过串口输出监测数据

(2)项目难点

当两个SPI设备共享总线时,会产生总线竞争导致通信失败。本文将重点介绍两种解决方案。

(3)解决思路

方案一:将显示屏改为软件SPI驱动,与传感器的硬件SPI物理隔离。

方案二:通过精确控制CS引脚状态,确保同一时间只有一个设备使用SPI总线。

一、硬件准备与连接

1.1硬件清单

组件 型号 数量
主控板 零知标准板 1
气压传感器 BMP581 1
显示屏 ST7789 (240x320) 1
杜邦线 公对公 若干

1.2 接线方案

零知标准板(STM32F103RBT6) BMP581(硬件SPI) ST7789(软件SPI)
3.3V VCC VCC
GND GND GND
10 CS /
11(MOSI) SDA /
12(MISO) SDO /
13(SCK) SCL /
6 / CS
2 / DC
8 / SDA
7 / SCL
4 / RES

1.3 硬件连线图

wKgZPGhmQQWAC7FBAAcVlFGRYe0838.png

1.4 接线实物图

wKgZO2hmQO-AAghfACkyJPmxvhk374.png

二、完整代码实现

采取软件SPI替换ST7789的通信方式解决总线冲突的方案,确保零知IDE包含以下库文件:

SparkFun_BMP581_Arduino_Library.h

Adafruit_GFX.h

Adafruit_ST7789.h

SPI.h

2.1 初始化定义

定义显示屏和BMP581气压传感器驱动的相关参数

// BMP581 SPI通信参数
uint8_t bmp581_cs = 10;  // BMP581 片选引脚
uint32_t clockFrequency = 100000;  // 设置SPI时钟频率

// ST7789 显示屏引脚定义
#define TFT_CS   6  // 设置软件SPI的片选引脚
#define TFT_RST  4   // 显示屏复位引脚
#define TFT_DC   2  // 显示屏数据/控制命令引脚
#define TFT_MOSI 8  // 软件SPI的MOSI引脚
#define TFT_SCLK 7  // 软件SPI的SCK引脚

// 传感器和显示屏的对象创建与初始化
BMP581 pressureSensor;
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);

// 定义显示屏参数
#define SCREEN_WIDTH  240
#define SCREEN_HEIGHT 320
#define ST77xx_PURPLE 0x862F
#define VALUE_SIZE    3
#define LABEL_SIZE    1

// 颜色定义
#define BACKGROUND  ST77XX_BLACK
#define TEXT_COLOR  ST77XX_WHITE
#define TEMP_COLOR  ST77xx_PURPLE
#define PRESS_COLOR ST77XX_CYAN
#define ALT_COLOR   ST77XX_GREEN
#define BOX_COLOR   ST77XX_ORANGE
poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

2.2 初始化配置

配置串口通信波特率为115200,ST7789显示屏大小、方向和交互内容显示,开启BMP581的SPI通信连接,绘制显示屏标题和数据内容标签

void setup() {
    // 开启串口监视器并设置波特率为115200
    Serial.begin(115200);
    Serial.println("BMP581 with ST7789 Display Example");

    // 初始化SPI
    SPI.begin();

    // 初始化显示屏
    tft.init(SCREEN_WIDTH, SCREEN_HEIGHT);
    tft.setRotation(3);
    tft.fillScreen(BACKGROUND);
    tft.setTextColor(TEXT_COLOR);

    // 初始化BMP581传感器
    while (pressureSensor.beginSPI(bmp581_cs, clockFrequency) != BMP5_OK) {
        Serial.println("Error: BMP581 not connected, check wiring and CS pin!");
        tft.setCursor(10, 10);
        tft.setTextSize(2);
        tft.print("Sensor not found!");
        delay(1000);
        tft.fillScreen(BACKGROUND);
    }

    Serial.println("BMP581 connected!");
    drawStaticElements();
}

2.3 读取传感器数据

loop函数循环获取实时的大气压强和温度数据,并通过经验公式转换为海拔高度数据,将获得的数据实时更新到TFT显示屏界面上

void loop() {
    // 从寄存器获取到数值
    bmp5_sensor_data data = {0, 0};
    int8_t err = pressureSensor.getSensorData(&data);

    if (err == BMP5_OK) {
        // 将气压数据转换以百帕为单位 (1 hPa = 100 Pa)
        float pressure_hPa = data.pressure / 100.0;

        // 使用经验公式计算海拔高度数据
        float altitude = (1013.25 - pressure_hPa) / 12 * 100;

        // 更新屏幕
        updateTextDisplay(data.temperature, pressure_hPa, altitude);

        // 打印串口监视数据
        Serial.print("Temperature (C): ");
        Serial.print(data.temperature);
        Serial.print("tPressure (hPa): ");
        Serial.print(pressure_hPa);
        Serial.print("tAltitude (m): ");
        Serial.println(altitude);
    } else {
        Serial.print("Error getting data from sensor! Error code: ");
        Serial.println(err);
    }

    delay(1000);  // 每秒更新一次数据
}

2.4 UI界面更新

void drawStaticElements() {
  tft.fillScreen(BACKGROUND);
  
  // 绘制标题
  tft.setTextSize(1);
  tft.setTextColor(ST77XX_YELLOW);
  tft.setCursor(SCREEN_WIDTH/2 + 120, 10);
  tft.print("BMP581 SENSOR");
  
  // 绘制温度数据容器
  drawDataBox(30, 10, "TEMPERATURE", "(C)", TEMP_COLOR);
  
  // 绘制气压数据容器
  drawDataBox(30, 90, "PRESSURE", "(hPa)", PRESS_COLOR);
  
  // 绘制海拔数据容器
  drawDataBox(30, 170, "ALTITUDE", "(m)", ALT_COLOR);
}

void drawDataBox(int x, int y, const char* label, const char* unit, uint16_t color) {
    // 绘制数据容器
    tft.drawRoundRect(x, y, SCREEN_WIDTH - 60, 60, 10, BOX_COLOR);

    // 绘制数据标题
    tft.setTextSize(LABEL_SIZE);
    tft.setTextColor(color);
    tft.setCursor(x + 15, y + 10);
    tft.print(label);

    // 绘制数据单位
    tft.setTextSize(LABEL_SIZE - 1);
    tft.setCursor(x + SCREEN_WIDTH - 60 - 40, y + 10);
    tft.print(unit);
}

void updateTextDisplay(float temp, float pressure, float altitude) {
  updateDataValue(30, 10, temp, 1, TEMP_COLOR);  // 更新温度数据
  updateDataValue(30, 90, pressure, 1, PRESS_COLOR);  // 更新气压数据
  updateDataValue(30, 170, altitude, 1, ALT_COLOR);  // 更新海拔数据
}

void updateDataValue(int x, int y, float value, int decimals, uint16_t color) {
    // 清除旧数据
    tft.fillRect(x + 10, y + 30, SCREEN_WIDTH - 80, 25, BACKGROUND);

    // 写入新数据
    tft.setTextSize(VALUE_SIZE);
    tft.setTextColor(color);
    tft.setCursor(x + 15, y + 30);
    tft.print(value, decimals);
}

2.5 项目完整代码获取

通过网盘分享的文链接:
https://pan.baidu.com/s/125lFvyjRd98dkqMkYh0TSA?pwd=d4m4

三、实际效果展示

3.1 显示屏信息解读

成功运行后,显示屏将分为三个区域显示:

温度区:灰色标签,显示摄氏度

气压区:红色标签,显示百帕

海拔区:紫色标签,显示米

3.2 视频演示效果

https://www.bilibili.com/video/BV1MR3tzzEXm/?spm_id_from=333.1387.homepage.video_card.click&vd_source=a31e3d8d8ce008260eee442534c2f63d

将通过传感器获取到的气压值与app海拔仪气压值进行对比

3.3 串口监视器数据

同时,串口监视器将每秒输出一次数据:

wKgZPGhmQJaANRfrAACYRHkVkXY741.png

四、SPI冲突解决方案详解

4.1 问题现象

当BMP581和ST7789共享硬件SPI总线时:显示屏无法正常显示,传感器数据读取不稳定,系统可能完全无法工作

4.2 根本原因

SPI总线需要独占访问

两个设备共享MOSI、MISO、SCK信号线

片选(CS)信号控制不足

总线竞争导致数据冲突

4.3 方案一

软件SPI驱动显示屏:将显示屏改为软件SPI驱动,与传感器的硬件SPI物理隔离。

// ST7789使用软件SPI
#define TFT_CS   6  // 显示屏片选
#define TFT_RST  4  // 复位引脚
#define TFT_DC   2  // 数据/命令选择
#define TFT_MOSI 8  // 软件SPI数据引脚
#define TFT_SCLK 7  // 软件SPI时钟引脚

// 创建显示屏对象(使用软件SPI)
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);

优势:

完全避免硬件SPI冲突

简化编程逻辑

更稳定的通信表现

灵活的引脚分配

4.4 方案二

共享SPI总线+显式CS控制:通过精确控制CS引脚状态,确保同一时间只有一个设备使用SPI总线。

// BMP581 SPI参数
uint8_t bmp581_cs = 10;  // BMP581芯片选择引脚
uint32_t clockFrequency = 100000;  // BMP581的SPI时钟频率

// ST7789显示屏引脚配置
#define TFT_CS   6  // 显示屏芯片选择引脚(与BMP581不同)

Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);   //使用硬件SPI驱动方式

void setup() {
    // ...其他初始化...
    
    // 初始化CS引脚
    pinMode(TFT_CS, OUTPUT);
    digitalWrite(TFT_CS, HIGH);  // 初始取消选择显示屏
    pinMode(bmp581_cs, OUTPUT);
    digitalWrite(bmp581_cs, HIGH);  // 初始取消选择传感器
}

void loop() {
    // 读取传感器数据
    digitalWrite(TFT_CS, HIGH);  // 取消选择显示屏
    err = pressureSensor.getSensorData(&data);
    digitalWrite(bmp581_cs, HIGH);  // 取消选择传感器
    
    // 更新显示
    digitalWrite(bmp581_cs, HIGH);  // 确保传感器已取消选择
    updateTextDisplay(...);
}

关键点:

通信前确保另一个设备被取消选择

通信后立即取消选择当前设备

初始化时所有CS引脚设为HIGH

软件SPI的MOSI和SCK引脚共用,片选(CS)引脚需要单独设置

五、海拔计算与精度说明

代码中使用简化的海拔计算公式:

float altitude = (1013.25 - pressure_hPa) / 12 * 100;

计算原理

1013.25 hPa:标准海平面气压
气压梯度:每下降12 hPa,海拔升高约100米

精度考虑 ,实际测量中可能存在10-50米的误差,主要因素包括:

当地气象条件变化

温度对气压的影响

传感器本身的测量误差

公式本身的近似性

六、常见问题解决

1.显示屏白屏或花屏

检查RES引脚连接
确认软件SPI引脚配置正确

尝试降低软件SPI速度

在tft.init()后添加tft.setSPISpeed(10000000)

2.传感器读取失败

检查硬件SPI连接
确保CS引脚配置正确
测量传感器供电电压(应为3.3V)

3.数据显示异常

检查引脚定义是否正确
确认显示屏旋转方向设置合适
验证传感器数据在串口的输出是否正常

七、方案对比与选择建议

特性 方案一(软件SPI) 方案二(硬件SPI+CS控制)
实现难度 简单 ★☆☆ 中等 ★★☆
稳定性 高 ★★★ 中 ★★☆
性能 中 ★★☆ 高 ★★★
资源占用 较高(需要额外引脚) 低(共享SPI引脚)
推荐场景 初学者/快速实现 高性能应用/引脚受限

推荐选择:

对于大多数应用,方案一(软件SPI驱动显示屏) 是更简单可靠的选择

只有在需要高速刷新或引脚资源紧张时才考虑方案二

八、总结

本文详细介绍了在零知增强板上实现BMP581传感器与ST7789显示屏协同工作的完整过程,重点解决了SPI总线冲突问题。关键点包括:

硬件连接:正确连接SPI设备,特别是CS引脚

SPI冲突解决:

推荐方案:使用软件SPI驱动显示屏
备选方案:共享硬件SPI+精确CS控制

数据采集与显示:实时获取环境数据并直观展示

海拔计算:使用简化公式计算海拔高度

通过本教程,开发者可以快速构建稳定可靠的环境监测系统,更多零知开发教程:

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 传感器
    +关注

    关注

    2573

    文章

    54363

    浏览量

    785790
  • SPI
    SPI
    +关注

    关注

    17

    文章

    1866

    浏览量

    99732
  • stm32f1
    +关注

    关注

    1

    文章

    60

    浏览量

    12801
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    STM32项目分享:矿井环境监测系统

    01—项目简介1.功能详解STM32矿井环境监测系统功能如下:STM32F103C8T6单片机作为主控制器DS18B20测量
    的头像 发表于 08-16 10:03 699次阅读
    <b class='flag-5'>STM32</b>项目分享:矿井<b class='flag-5'>环境监测</b><b class='flag-5'>系统</b>

    开源——STM32F407VET6驱动SHT41温湿度传感器完整教程

    目基于STM32F407VET6增强板,实现SHT41高精度温湿度传感器驱动和数据采集。S
    发表于 07-10 12:01

    开源——STM32F407VET6驱动SHT41温湿度传感器完整教程

    摘要:本项目基于STM32F407VET6增强板驱动SHT41高精度温湿度传感器实现±0.
    的头像 发表于 07-09 18:53 890次阅读
    <b class='flag-5'>零</b><b class='flag-5'>知</b><b class='flag-5'>开源</b>——<b class='flag-5'>STM32F</b>407VET6<b class='flag-5'>驱动</b>SHT41温湿度<b class='flag-5'>传感器</b>完整教程

    开源——STM32F4结合BMP581气压传感器实现ST7789中文显示教程

    开源平台是一个专为国开发者设计的软硬件开源平台,提供比Arduino更易上手的开发体验。本教程展示了如何在STM32F407VET6增强
    的头像 发表于 07-09 09:21 1236次阅读
    <b class='flag-5'>零</b><b class='flag-5'>知</b><b class='flag-5'>开源</b>——<b class='flag-5'>STM32F</b>4结合<b class='flag-5'>BMP581</b>气压<b class='flag-5'>传感器</b><b class='flag-5'>实现</b><b class='flag-5'>ST7789</b>中文<b class='flag-5'>显示</b>教程

    开源——STM32F4结合BMP581气压传感器实现ST7789中文显示教程

    STM32F407VET6增强板上实现ST7789显示屏的中文
    发表于 07-08 18:55

    开源——STM32F1驱动BMP581压强传感器使SPI实现ST7789显示环境监测系统

    实现BMP581气压传感器ST7789显示屏的协同工作,重点解决SPI总线冲突问题,并展示
    发表于 07-03 17:26

    STM32F1驱动BMP581压强传感器使SPI实现ST7789显示环境监测系统

    监测系统
    PCB56242069
    发布于 :2025年07月03日 16:30:04

    开源——基于STM32F407VET6增强板的四路独立计时器

    TFT_RST 4 蜂鸣器&LED 3 按钮 1 14 按钮 215 按钮 3 16 按钮 4 17 1.3 连接硬件图 主控增强板和ST7789
    发表于 07-01 10:31

    开源——基于STM32F407VET6增强板的四路独立计时器

    本教程介绍基于STM32F407VET6增强板的四路独立计时器实现方案。项目采用TFT显示屏、蜂鸣器和按钮构建交互
    的头像 发表于 07-01 10:13 862次阅读
    <b class='flag-5'>零</b><b class='flag-5'>知</b><b class='flag-5'>开源</b>——基于<b class='flag-5'>STM32F</b>407VET6<b class='flag-5'>零</b><b class='flag-5'>知</b>增强板的四路独立计时器

    开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程

    STM32F1本教程使用标准板(STM32F103RBT6)通过I2C驱动ICM20948九轴传感器
    发表于 06-09 14:53

    开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程

    本教程使用标准板(STM32F103RBT6)通过I2C驱动ICM20948九轴传感器实现
    的头像 发表于 06-09 14:01 1188次阅读
    <b class='flag-5'>零</b><b class='flag-5'>知</b><b class='flag-5'>开源</b>——<b class='flag-5'>STM32F</b>103RBT6<b class='flag-5'>驱动</b> ICM20948 九轴<b class='flag-5'>传感器</b>及 vofa + 上位机可视化教程

    开源——STM32F4驱动MAX31865实现PT100高精度测温

    材料增强板(STM32F407VET6) MAX31865模块(支持三线制PT100) 三线制PT100传感器 0.96寸I2C OLED显示
    发表于 05-26 18:52

    开源——STM32F1驱动MAX31865读取三线PT100温度传感器

    使用Callendar-Van Dusen方程计算。 4.演示视频STM32F1驱动MAX31865读取三线PT100温度传感器 五、常见问题1.OLED无
    发表于 05-23 18:27

    ESP32驱动ST7789触摸屏开发指南:LVGL主题设置与示波器面板

    处理器 屏幕ST7789 2.4寸240×320分辨率 触摸芯片XPT2046电阻式触摸控制器 接线SPI使用硬件SPI接口接线图 三、环境搭建1
    发表于 04-29 10:20

    st7789软件包不能添加是怎么回事?

    1、在UI界面上可以看到st7789,但在packages中没有。 2、没有看到对应的下载信息。 3、在对应github中可以正常下载。 4、RTT版本为5.1.0. 5、类似的ili9341的添加是正常的。
    发表于 03-20 07:51