[Arduino资料] 零知开源——STM32F4结合BMP581气压传感器实现ST7789中文显示教程

[复制链接]
 楼主| lingzhiLab 发表于 2025-7-8 18:06 | 显示全部楼层 |阅读模式
​✔零知开源是一个真正属于国人自己的开源软硬件平台,在开发效率上超越了Arduino平台并且更加容易上手,大大降低了开发难度。零知开源在软件方面提供了完整的学习教程和丰富示例代码,让不懂程序的工程师也能非常轻而易举的搭建电路来创作产品,测试产品。快来动手试试吧!
✔访问零知开源平台,获取更多实战项目和教程资源吧!
www.lingzhilab.com



(1)项目概述
        本教程将重点讲解如何在STM32F407VET6零知增强板上实现ST7789显示屏的中文显示功能,结合BMP581传感器数据展示。项目使用I2C通信读取传感器数据,通过SPI接口在TFT屏幕上显示中文界面。

(2)项目亮点
        >使用U8g2库实现高质量中文渲染
        >混合使用Adafruit_GFX和U8g2实现高效显示
        >实时显示温度、压力和高度数据
        >针对STM32F4系列优化内存使用


一、硬件系统设计1.1 硬件组成
组件
型号
接口
功能
主控板
STM32F407VET6零知增强板
-
核心控制器
气压传感器
BMP581
I2C
温度/气压数据采集
TFT显示屏
ST7789
SPI
数据可视化显示
接口扩展
零知扩展板
-
提供标准接口

1.2 接线方案
零知增强板(STM32F407VET6)
BMP581(I2C)
ST7789(SPI)
引脚功能说明
3.3V
VCC
VCC
电源
GND
GND
GND
接地
21/SCL
SCL
/
时钟线
20/SDA
SDA
/
数据线
53
/
CS
片选
2
/
DC
数据/
命令选择
51
/
SDA
主出从入
52
/
SCL
时钟
4
/
RES
复位

1.3 连接硬件图
a962f4078e714acbbf53f47ad1d2b312.png

1.4 接线实物图
3a6023f0cdef4e1191b7eb0faad9db65.jpeg




二、软件架构设计2.1 库依赖关系
  • SparkFun_BMP581库:提供传感器初始化接口、封装数据读取函数、处理I2C通信协议
  • Adafruit_ST7789+GFX库:实现屏幕底层驱动、提供图形绘制API、优化显示性能
  • U8g2_for_Adafruit_GFX:添加中文字符支持、扩展文本渲染能力
44f931a0ff5f4292bfb5a9f4a4078243.png



2.2 初始化流程
  1. // sketch_jun30d.ino
  2. #include <Wire.h>
  3. #include "SparkFun_BMP581_Arduino_Library.h"
  4. #include <Adafruit_GFX.h>
  5. #include <Adafruit_ST7789.h>
  6. #include <SPI.h>
  7. #include <U8g2_for_Adafruit_GFX.h>  // 添加U8g2库支持中文字体

  8. // Screen pin configuration
  9. #define TFT_CS 53
  10. #define TFT_RST 4
  11. #define TFT_DC 2
  12. #define TFT_MOSI 51
  13. #define TFT_SCLK 52

  14. // Using hardware SPI
  15. Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
  16. U8G2_FOR_ADAFRUIT_GFX u8g2_for_adafruit_gfx;  // 创建U8g2对象

  17. // Create a new sensor object
  18. BMP581 pressureSensor;

  19. // I2C address selection
  20. uint8_t i2cAddress = BMP581_I2C_ADDRESS_DEFAULT;  // 0x47

  21. // Display configuration
  22. #define SCREEN_WIDTH 240
  23. #define SCREEN_HEIGHT 320
  24. #define ST77xx_PURPLE 0x862F
  25. #define VALUE_SIZE 3
  26. #define LABEL_SIZE 1

  27. // Color definitions
  28. #define BACKGROUND ST77XX_BLACK
  29. #define TEXT_COLOR ST77XX_WHITE
  30. #define TEMP_COLOR ST77xx_PURPLE
  31. #define PRESS_COLOR ST77XX_CYAN
  32. #define ALT_COLOR ST77XX_GREEN
  33. #define BOX_COLOR ST77XX_ORANGE

  34. // 精简版中文字体定义
  35. #define CN_FONT u8g2_font_unifont_t_chinese3  // 使用精简中文字体

  36. void setup() {
  37.   Serial.begin(115200);
  38.   Serial.println("BMP581 Enhanced Text Display Example");

  39.   // Initialize I2C library
  40.   Wire.begin();

  41.   // Initialize screen
  42.   tft.init(SCREEN_WIDTH, SCREEN_HEIGHT);
  43.   tft.setRotation(3);
  44.   tft.fillScreen(BACKGROUND);
  45.   tft.setTextColor(TEXT_COLOR);

  46.   // 初始化U8g2对象,设置中文显示
  47.   u8g2_for_adafruit_gfx.begin(tft);                      // 将U8g2与Adafruit_GFX关联
  48.   u8g2_for_adafruit_gfx.setFontMode(1);                  // 透明模式
  49.   u8g2_for_adafruit_gfx.setFontDirection(0);             // 从左到右
  50.   u8g2_for_adafruit_gfx.setForegroundColor(TEXT_COLOR);  // 设置前景色
  51.   u8g2_for_adafruit_gfx.setFont(CN_FONT);                // 使用精简中文字体

  52.   // Check sensor connection
  53.   while (pressureSensor.beginI2C(i2cAddress) != BMP5_OK) {
  54.     Serial.println("Error: BMP581 not connected, check wiring and I2C address!");

  55.     // 显示错误信息
  56.     u8g2_for_adafruit_gfx.setCursor(10, 30);
  57.     u8g2_for_adafruit_gfx.print("传感器未找到!");
  58.     u8g2_for_adafruit_gfx.setCursor(10, 60);
  59.     u8g2_for_adafruit_gfx.print("请排查接线!");

  60.     delay(1000);
  61.     tft.fillScreen(BACKGROUND);
  62.   }

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


2.3 数据读取机制
  1. void loop() {
  2.   // Get measurements from the sensor
  3.   bmp5_sensor_data data = { 0, 0 };
  4.   int8_t err = pressureSensor.getSensorData(&data);

  5.   if (err == BMP5_OK) {
  6.     // Convert pressure from Pa to hPa (1 hPa = 100 Pa)
  7.     float pressure_hPa = data.pressure / 100.0;

  8.     // Calculate altitude using simplified formula
  9.     float altitude = (1013.25 - pressure_hPa) / 16.5 * 100;

  10.     // Update text display
  11.     updateTextDisplay(data.temperature, pressure_hPa, altitude);

  12.     Serial.print("空气温度 (C): ");
  13.     Serial.print(data.temperature);
  14.     Serial.print("\t大气压强 (hPa): ");
  15.     Serial.print(pressure_hPa);
  16.     Serial.print("\t海拔高度 (m): ");
  17.     Serial.println(altitude);
  18.   } else {
  19.     Serial.print("Error getting data from sensor! Error code: ");
  20.     Serial.println(err);
  21.   }

  22.   delay(1000);  // Update every second
  23. }


2.4 中文文本渲染
  1. void drawStaticElements() {
  2.   tft.fillScreen(BACKGROUND);

  3.   // 使用U8g2绘制中文标题
  4.   u8g2_for_adafruit_gfx.setForegroundColor(ST77XX_YELLOW);
  5.   u8g2_for_adafruit_gfx.setCursor(SCREEN_WIDTH / 2 + 95, 20);  // 居中位置
  6.   u8g2_for_adafruit_gfx.print("BMP581传感器");                 // 中文标题

  7.   // 绘制温度框和标签
  8.   drawDataBox(30, 10, "热量", "(C)", TEMP_COLOR);

  9.   // 绘制压力框和标签
  10.   drawDataBox(30, 90, "大气压强", "(hPa)", PRESS_COLOR);

  11.   // 绘制高度框和标签
  12.   drawDataBox(30, 170, "距离海平面高度", "(m)", ALT_COLOR);
  13. }

  14. void drawDataBox(int x, int y, const char* label, const char* unit, uint16_t color) {
  15.   // Draw box
  16.   tft.drawRoundRect(x, y, SCREEN_WIDTH - 60, 60, 10, BOX_COLOR);

  17.   // 使用U8g2绘制中文标签
  18.   u8g2_for_adafruit_gfx.setForegroundColor(color);
  19.   u8g2_for_adafruit_gfx.setCursor(x + 15, y + 20);  // 调整位置
  20.   u8g2_for_adafruit_gfx.print(label);

  21.   // Draw unit (smaller text)
  22.   tft.setTextSize(LABEL_SIZE - 1);
  23.   tft.setCursor(x + SCREEN_WIDTH - 60 - 40, y + 10);
  24.   tft.print(unit);
  25. }


2.5 动态数据更新
  1. void updateTextDisplay(float temp, float pressure, float altitude) {
  2.   // Update temperature
  3.   updateDataValue(30, 10, temp, 1, TEMP_COLOR);

  4.   // Update pressure
  5.   updateDataValue(30, 90, pressure, 1, PRESS_COLOR);

  6.   // Update altitude
  7.   updateDataValue(30, 170, altitude, 1, ALT_COLOR);
  8. }

  9. void updateDataValue(int x, int y, float value, int decimals, uint16_t color) {
  10.   // Clear previous value
  11.   tft.fillRect(x + 10, y + 30, SCREEN_WIDTH - 80, 25, BACKGROUND);

  12.   // Draw new value
  13.   tft.setTextSize(VALUE_SIZE);
  14.   tft.setTextColor(color);
  15.   tft.setCursor(x + 15, y + 30);
  16.   tft.print(value, decimals);
  17. }


三、功能展示 3.1 显示效果
标题:蓝色中文"BMP581传感器"右对齐显示
数据框:
        蓝色圆角矩形边框、中文标签(灰色/红色/紫色)、单位符号(小字号英文)
数据值:
        大字号显示(字号3)、每秒更新一次、刷新时无闪烁(局部刷新优化)

3.2 系统工作流程
41ece6650ab145b18d39d7b98b391d0d.png


3.3 视频演示效果
https://live.csdn.net/v/484270
将通过传感器获取到的气压值与下面的app海拔仪气压值进行对比
1204517165314be2b21dc36ed749c794.png


3.4 串口监视器数据串口监视器将同时每秒输出一次数据:
8970064510284ecaabf0fa633d3be0d3.png

3.5 性能指标
项目
指标
说明
采样频率
1Hz
每秒更新一次数据
温度精度
±0.5℃
符合BMP581规格
压强精度
±0.5hPa
符合BMP581规格
显示延迟
<100ms
从采集到显示时间
功耗
15mA @3.3V
不含背光功耗

四、海拔计算与精度说明 代码中使用简化的海拔计算公式:
float altitude = (1013.25 - pressure_hPa) / 12 * 100;

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

精度考虑 ,实际测量中可能存在10-50米的误差,主要因素包括:
  • 当地气象条件变化
  • 温度对气压的影响
  • 传感器本身的测量误差
  • 公式本身的近似性

五、常见问题解答Q1:为什么中文显示为方框或乱码?A:原因及解决方案
1.字体未正确设置:
  1. // 确保正确定义中文字体
  2. #define CN_FONT u8g2_font_unifont_t_chinese3
  3. u8g2_for_adafruit_gfx.setFont(CN_FONT);

2.库版本问题:
# 推荐安装的库版本
Adafruit ST7735 and ST7789 Library v1.9.3
U8g2_for_Adafruit_GFX v1.7.0

Q2:编译时出现内存不足错误怎么办?A:优化策略
禁用不必要的库文件
减少全局变量使用
如果仍不足,可更换更小字体:
// 替代字体(约30KB)
#define CN_FONT u8g2_font_wqy12_t_gb2312

Q3:如何添加更多中文内容?A:扩展方法
1.在drawStaticElements()中添加新元素
2.确保使用的字符在字体库中存在:
  1. // 添加新标签
  2. drawDataBox(30, 250, "湿度", "%", HUMIDITY_COLOR);
3.如需生僻字,需自定义字体子集(本教程未包含)
注意:u8g2_font_unifont_t_chinese3包含GB2312一级字库(3755个常用汉字),满足大多数应用需求。

Q4:传感器初始化失败怎么办?A:排查步骤
1.检查I2C接线:SDA/SCL是否反接
2.确认I2C地址:使用I2C扫描工具检测
  1. void scanI2C() {
  2.   for(uint8_t addr=1; addr<127; addr++) {
  3.     Wire.beginTransmission(addr);
  4.     if(Wire.endTransmission() == 0) {
  5.       Serial.print("Found device at 0x");
  6.       Serial.println(addr, HEX);
  7.     }
  8.   }
  9. }
3.检查电源:确保3.3V供电稳定


六、结论
本教程详细讲解了在STM32F407VET6零知增强板上实现ST7789显示屏中文显示的技术方案。通过使用U8g2_for_Adafruit_GFX库,我们能够:
  • 高效渲染中文字符
           
  • 保持与Adafruit_GFX的兼容性
           
  • 实现中英文混合显示
           
  • 在有限的硬件资源下优化性能


项目资源
完整代码链接: https://pan.baidu.com/s/1EPrOlbQ2wHjGa691qyf71Q?pwd=2kj7
大气压强传感器:BMP581数据手册
主控芯片:STM32F4参考手册

通过本教程,开发者可以快速构建稳定可靠的环境监测系统,点击了解更多零知开发教程:
https://www.lingzhilab.com/freesources.html

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

本版积分规则

22

主题

33

帖子

0

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