零知开源——STM32F4结合BMP581气压传感器实现ST7789中文显示教程
✔零知开源是一个真正属于国人自己的开源软硬件平台,在开发效率上超越了Arduino平台并且更加容易上手,大大降低了开发难度。零知开源在软件方面提供了完整的学习教程和丰富示例代码,让不懂程序的工程师也能非常轻而易举的搭建电路来创作产品,测试产品。快来动手试试吧!
✔访问零知开源平台,获取更多实战项目和教程资源吧!
www.lingzhilab.com
目录
一、硬件系统设计
1.1 硬件组成
1.2 接线方案
1.3 连接硬件图
1.4 接线实物图
二、软件架构设计
2.1 库依赖关系
2.2 初始化流程
2.3 数据读取机制
2.4 中文文本渲染
2.5 动态数据更新
三、功能展示
3.1 显示效果
3.2 系统工作流程
3.3 视频演示效果
3.4 串口监视器数据
3.5 性能指标
四、海拔计算与精度说明
五、常见问题解答
Q1:为什么中文显示为方框或乱码?
Q2:编译时出现内存不足错误怎么办?
Q3:如何添加更多中文内容?
Q4:传感器初始化失败怎么办?
六、结论
(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 连接硬件图
1.4 接线实物图
二、软件架构设计
2.1 库依赖关系
- SparkFun_BMP581库:提供传感器初始化接口、封装数据读取函数、处理I2C通信协议
- Adafruit_ST7789+GFX库:实现屏幕底层驱动、提供图形绘制API、优化显示性能
- U8g2_for_Adafruit_GFX:添加中文字符支持、扩展文本渲染能力
2.2 初始化流程
// sketch_jun30d.ino
#include <Wire.h>
#include "SparkFun_BMP581_Arduino_Library.h"
#include <Adafruit_GFX.h>
#include <Adafruit_ST7789.h>
#include <SPI.h>
#include <U8g2_for_Adafruit_GFX.h> // 添加U8g2库支持中文字体// Screen pin configuration
#define TFT_CS 53
#define TFT_RST 4
#define TFT_DC 2
#define TFT_MOSI 51
#define TFT_SCLK 52// Using hardware SPI
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
U8G2_FOR_ADAFRUIT_GFX u8g2_for_adafruit_gfx; // 创建U8g2对象// Create a new sensor object
BMP581 pressureSensor;// I2C address selection
uint8_t i2cAddress = BMP581_I2C_ADDRESS_DEFAULT; // 0x47// Display configuration
#define SCREEN_WIDTH 240
#define SCREEN_HEIGHT 320
#define ST77xx_PURPLE 0x862F
#define VALUE_SIZE 3
#define LABEL_SIZE 1// Color definitions
#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// 精简版中文字体定义
#define CN_FONT u8g2_font_unifont_t_chinese3 // 使用精简中文字体void setup() {Serial.begin(115200);Serial.println("BMP581 Enhanced Text Display Example");// Initialize I2C libraryWire.begin();// Initialize screentft.init(SCREEN_WIDTH, SCREEN_HEIGHT);tft.setRotation(3);tft.fillScreen(BACKGROUND);tft.setTextColor(TEXT_COLOR);// 初始化U8g2对象,设置中文显示u8g2_for_adafruit_gfx.begin(tft); // 将U8g2与Adafruit_GFX关联u8g2_for_adafruit_gfx.setFontMode(1); // 透明模式u8g2_for_adafruit_gfx.setFontDirection(0); // 从左到右u8g2_for_adafruit_gfx.setForegroundColor(TEXT_COLOR); // 设置前景色u8g2_for_adafruit_gfx.setFont(CN_FONT); // 使用精简中文字体// Check sensor connectionwhile (pressureSensor.beginI2C(i2cAddress) != BMP5_OK) {Serial.println("Error: BMP581 not connected, check wiring and I2C address!");// 显示错误信息u8g2_for_adafruit_gfx.setCursor(10, 30);u8g2_for_adafruit_gfx.print("传感器未找到!");u8g2_for_adafruit_gfx.setCursor(10, 60);u8g2_for_adafruit_gfx.print("请排查接线!");delay(1000);tft.fillScreen(BACKGROUND);}Serial.println("BMP581 connected!");drawStaticElements();
}
2.3 数据读取机制
void loop() {// Get measurements from the sensorbmp5_sensor_data data = { 0, 0 };int8_t err = pressureSensor.getSensorData(&data);if (err == BMP5_OK) {// Convert pressure from Pa to hPa (1 hPa = 100 Pa)float pressure_hPa = data.pressure / 100.0;// Calculate altitude using simplified formulafloat altitude = (1013.25 - pressure_hPa) / 16.5 * 100;// Update text displayupdateTextDisplay(data.temperature, pressure_hPa, altitude);Serial.print("空气温度 (C): ");Serial.print(data.temperature);Serial.print("\t大气压强 (hPa): ");Serial.print(pressure_hPa);Serial.print("\t海拔高度 (m): ");Serial.println(altitude);} else {Serial.print("Error getting data from sensor! Error code: ");Serial.println(err);}delay(1000); // Update every second
}
2.4 中文文本渲染
void drawStaticElements() {tft.fillScreen(BACKGROUND);// 使用U8g2绘制中文标题u8g2_for_adafruit_gfx.setForegroundColor(ST77XX_YELLOW);u8g2_for_adafruit_gfx.setCursor(SCREEN_WIDTH / 2 + 95, 20); // 居中位置u8g2_for_adafruit_gfx.print("BMP581传感器"); // 中文标题// 绘制温度框和标签drawDataBox(30, 10, "热量", "(C)", TEMP_COLOR);// 绘制压力框和标签drawDataBox(30, 90, "大气压强", "(hPa)", PRESS_COLOR);// 绘制高度框和标签drawDataBox(30, 170, "距离海平面高度", "(m)", ALT_COLOR);
}void drawDataBox(int x, int y, const char* label, const char* unit, uint16_t color) {// Draw boxtft.drawRoundRect(x, y, SCREEN_WIDTH - 60, 60, 10, BOX_COLOR);// 使用U8g2绘制中文标签u8g2_for_adafruit_gfx.setForegroundColor(color);u8g2_for_adafruit_gfx.setCursor(x + 15, y + 20); // 调整位置u8g2_for_adafruit_gfx.print(label);// Draw unit (smaller text)tft.setTextSize(LABEL_SIZE - 1);tft.setCursor(x + SCREEN_WIDTH - 60 - 40, y + 10);tft.print(unit);
}
2.5 动态数据更新
void updateTextDisplay(float temp, float pressure, float altitude) {// Update temperatureupdateDataValue(30, 10, temp, 1, TEMP_COLOR);// Update pressureupdateDataValue(30, 90, pressure, 1, PRESS_COLOR);// Update altitudeupdateDataValue(30, 170, altitude, 1, ALT_COLOR);
}void updateDataValue(int x, int y, float value, int decimals, uint16_t color) {// Clear previous valuetft.fillRect(x + 10, y + 30, SCREEN_WIDTH - 80, 25, BACKGROUND);// Draw new valuetft.setTextSize(VALUE_SIZE);tft.setTextColor(color);tft.setCursor(x + 15, y + 30);tft.print(value, decimals);
}
三、功能展示
3.1 显示效果
标题:蓝色中文"BMP581传感器"右对齐显示
数据框:
蓝色圆角矩形边框、中文标签(灰色/红色/紫色)、单位符号(小字号英文)数据值:
大字号显示(字号3)、每秒更新一次、刷新时无闪烁(局部刷新优化)
3.2 系统工作流程
3.3 视频演示效果
STM32F4结合BMP581气压传感器实现ST7789显示
将通过传感器获取到的气压值与下面的app海拔仪气压值进行对比
3.4 串口监视器数据
串口监视器将同时每秒输出一次数据:
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.字体未正确设置:
// 确保正确定义中文字体
#define CN_FONT u8g2_font_unifont_t_chinese3
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.确保使用的字符在字体库中存在:
// 添加新标签
drawDataBox(30, 250, "湿度", "%", HUMIDITY_COLOR);
3.如需生僻字,需自定义字体子集(本教程未包含)
注意:
u8g2_font_unifont_t_chinese3
包含GB2312一级字库(3755个常用汉字),满足大多数应用需求。
Q4:传感器初始化失败怎么办?
A:排查步骤
1.检查I2C接线:SDA/SCL是否反接
2.确认I2C地址:使用I2C扫描工具检测
void scanI2C() {for(uint8_t addr=1; addr<127; addr++) {Wire.beginTransmission(addr);if(Wire.endTransmission() == 0) {Serial.print("Found device at 0x");Serial.println(addr, HEX);}}
}
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