- // 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 library
- Wire.begin();
- // Initialize screen
- tft.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 connection
- while (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 sensor
- bmp5_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 formula
- float altitude = (1013.25 - pressure_hPa) / 16.5 * 100;
- // Update text display
- updateTextDisplay(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 box
- tft.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 temperature
- updateDataValue(30, 10, temp, 1, TEMP_COLOR);
- // Update pressure
- updateDataValue(30, 90, pressure, 1, PRESS_COLOR);
- // Update altitude
- updateDataValue(30, 170, altitude, 1, ALT_COLOR);
- }
- void updateDataValue(int x, int y, float value, int decimals, uint16_t color) {
- // Clear previous value
- tft.fillRect(x + 10, y + 30, SCREEN_WIDTH - 80, 25, BACKGROUND);
- // Draw new value
- tft.setTextSize(VALUE_SIZE);
- tft.setTextColor(color);
- tft.setCursor(x + 15, y + 30);
- tft.print(value, decimals);
- }
三、功能展示 3.1 显示效果标题:蓝色中文"BMP581传感器"右对齐显示
数据框:
蓝色圆角矩形边框、中文标签(灰色/红色/紫色)、单位符号(小字号英文)
数据值:
大字号显示(字号3)、每秒更新一次、刷新时无闪烁(局部刷新优化)
3.2 系统工作流程
3.3 视频演示效果
https://live.csdn.net/v/484270
将通过传感器获取到的气压值与下面的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