?零知開源是一個真正屬于國人自己的開源軟硬件平臺,在開發效率上超越了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 #include "SparkFun_BMP581_Arduino_Library.h" #include #include #include #include // 添加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; addr127; 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
審核編輯 黃宇
-
SPI
+關注
關注
17文章
1799瀏覽量
95699 -
I2C
+關注
關注
28文章
1541瀏覽量
127632 -
STM32F4
+關注
關注
3文章
203瀏覽量
28999 -
氣壓傳感器
+關注
關注
4文章
141瀏覽量
21561 -
LVGL
+關注
關注
1文章
105瀏覽量
3659
發布評論請先 登錄
零知開源——STM32F1驅動BMP581壓強傳感器使用SPI實現ST7789顯示的環境監測系統
開源分享 - BMP180大氣壓傳感器模塊的使用
博世發布氣壓傳感器BMP581提供超高精度的高度追蹤功能

Bosch Sensortec推新一代氣壓傳感器BMP581
Bosch Sensortec推出首款電容式氣壓傳感器BMP581
Bosch Sensortec推出新一代氣壓傳感器BMP581
使用Visuino程序將SSD1331 OLED和ST7789顯示器連接到Arduino

評論