?零知開源是一個(gè)真正屬于國人自己的開源軟硬件平臺,在開發(fā)效率上超越了Arduino平臺并且更加容易上手,大大降低了開發(fā)難度。零知開源在軟件方面提供了完整的學(xué)習(xí)教程和豐富示例代碼,讓不懂程序的工程師也能非常輕而易舉的搭建電路來創(chuàng)作產(chǎn)品,測試產(chǎn)品??靵韯?dòng)手試試吧!
?訪問零知開源平臺,獲取更多實(shí)戰(zhàn)項(xiàng)目和教程資源吧!
www.lingzhilab.com
目錄
一、硬件系統(tǒng)設(shè)計(jì)
1.1 硬件組成
1.2 接線方案
1.3 連接硬件圖
1.4 接線實(shí)物圖
二、軟件架構(gòu)設(shè)計(jì)
2.1 庫依賴關(guān)系
2.2 初始化流程
2.3 數(shù)據(jù)讀取機(jī)制
2.4 中文文本渲染
2.5 動(dòng)態(tài)數(shù)據(jù)更新
三、功能展示
3.1顯示效果
3.2 系統(tǒng)工作流程
3.3視頻演示效果
3.4串口監(jiān)視器數(shù)據(jù)
3.5 性能指標(biāo)
四、海拔計(jì)算與精度說明
五、常見問題解答
Q1:為什么中文顯示為方框或亂碼?
Q2:編譯時(shí)出現(xiàn)內(nèi)存不足錯(cuò)誤怎么辦?
Q3:如何添加更多中文內(nèi)容?
Q4:傳感器初始化失敗怎么辦?
六、結(jié)論
(1)項(xiàng)目概述
本教程將重點(diǎn)講解如何在STM32F407VET6零知增強(qiáng)板上實(shí)現(xiàn)ST7789顯示屏的中文顯示功能,結(jié)合BMP581傳感器數(shù)據(jù)展示。項(xiàng)目使用I2C通信讀取傳感器數(shù)據(jù),通過SPI接口在TFT屏幕上顯示中文界面。
(2)項(xiàng)目亮點(diǎn)
>使用U8g2庫實(shí)現(xiàn)高質(zhì)量中文渲染
>混合使用Adafruit_GFX和U8g2實(shí)現(xiàn)高效顯示
>實(shí)時(shí)顯示溫度、壓力和高度數(shù)據(jù)
>針對STM32F4系列優(yōu)化內(nèi)存使用
一、硬件系統(tǒng)設(shè)計(jì)
1.1 硬件組成
組件 | 型號 | 接口 | 功能 |
---|---|---|---|
主控板 | STM32F407VET6零知增強(qiáng)板 | - | 核心控制器 |
氣壓傳感器 | BMP581 | I2C | 溫度/氣壓數(shù)據(jù)采集 |
TFT顯示屏 | ST7789 | SPI | 數(shù)據(jù)可視化顯示 |
接口擴(kuò)展 | 零知擴(kuò)展板 | - | 提供標(biāo)準(zhǔn)接口 |
1.2 接線方案
零知增強(qiáng)板(STM32F407VET6) | BMP581(I2C) | ST7789(SPI) | 引腳功能說明 |
---|---|---|---|
3.3V | VCC | VCC | 電源 |
GND | GND | GND | 接地 |
21/SCL | SCL | / | 時(shí)鐘線 |
20/SDA | SDA | / | 數(shù)據(jù)線 |
53 | / | CS | 片選 |
2 | / | DC | 數(shù)據(jù)/命令選擇 |
51 | / | SDA | 主出從入 |
52 | / | SCL | 時(shí)鐘 |
4 | / | RES | 復(fù)位 |
1.3 連接硬件圖
1.4 接線實(shí)物圖
二、軟件架構(gòu)設(shè)計(jì)
2.1 庫依賴關(guān)系
SparkFun_BMP581庫:提供傳感器初始化接口、封裝數(shù)據(jù)讀取函數(shù)、處理I2C通信協(xié)議
Adafruit_ST7789+GFX庫:實(shí)現(xiàn)屏幕底層驅(qū)動(dòng)、提供圖形繪制API、優(yōu)化顯示性能
U8g2_for_Adafruit_GFX:添加中文字符支持、擴(kuò)展文本渲染能力
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; // 創(chuàng)建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對象,設(shè)置中文顯示 u8g2_for_adafruit_gfx.begin(tft); // 將U8g2與Adafruit_GFX關(guān)聯(lián) u8g2_for_adafruit_gfx.setFontMode(1); // 透明模式 u8g2_for_adafruit_gfx.setFontDirection(0); // 從左到右 u8g2_for_adafruit_gfx.setForegroundColor(TEXT_COLOR); // 設(shè)置前景色 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!"); // 顯示錯(cuò)誤信息 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 數(shù)據(jù)讀取機(jī)制
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大氣壓強(qiáng) (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繪制中文標(biāo)題 u8g2_for_adafruit_gfx.setForegroundColor(ST77XX_YELLOW); u8g2_for_adafruit_gfx.setCursor(SCREEN_WIDTH / 2 + 95, 20); // 居中位置 u8g2_for_adafruit_gfx.print("BMP581傳感器"); // 中文標(biāo)題 // 繪制溫度框和標(biāo)簽 drawDataBox(30, 10, "熱量", "(C)", TEMP_COLOR); // 繪制壓力框和標(biāo)簽 drawDataBox(30, 90, "大氣壓強(qiáng)", "(hPa)", PRESS_COLOR); // 繪制高度框和標(biāo)簽 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繪制中文標(biāo)簽 u8g2_for_adafruit_gfx.setForegroundColor(color); u8g2_for_adafruit_gfx.setCursor(x + 15, y + 20); // 調(diào)整位置 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 動(dòng)態(tài)數(shù)據(jù)更新
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顯示效果
標(biāo)題:藍(lán)色中文"BMP581傳感器"右對齊顯示
數(shù)據(jù)框:
藍(lán)色圓角矩形邊框、中文標(biāo)簽(灰色/紅色/紫色)、單位符號(小字號英文)
數(shù)據(jù)值:
大字號顯示(字號3)、每秒更新一次、刷新時(shí)無閃爍(局部刷新優(yōu)化)
3.2 系統(tǒng)工作流程
3.3視頻演示效果
https://live.csdn.net/v/484270
將通過傳感器獲取到的氣壓值與下面的app海拔儀氣壓值進(jìn)行對比
3.4串口監(jiān)視器數(shù)據(jù)
串口監(jiān)視器將同時(shí)每秒輸出一次數(shù)據(jù):
3.5 性能指標(biāo)
項(xiàng)目 | 指標(biāo) | 說明 |
---|---|---|
采樣頻率 | 1Hz | 每秒更新一次數(shù)據(jù) |
溫度精度 | ±0.5℃ | 符合BMP581規(guī)格 |
壓強(qiáng)精度 | ±0.5hPa | 符合BMP581規(guī)格 |
顯示延遲 | <100ms | 從采集到顯示時(shí)間 |
功耗 | 15mA @3.3V | 不含背光功耗 |
四、海拔計(jì)算與精度說明
代碼中使用簡化的海拔計(jì)算公式:
float altitude = (1013.25 - pressure_hPa) / 12 * 100;
計(jì)算原理
1013.25 hPa:標(biāo)準(zhǔn)海平面氣壓
氣壓梯度:每下降12 hPa,海拔升高約100米
精度考慮 ,實(shí)際測量中可能存在10-50米的誤差,主要因素包括:
當(dāng)?shù)貧庀髼l件變化
溫度對氣壓的影響
傳感器本身的測量誤差
公式本身的近似性
五、常見問題解答
Q1:為什么中文顯示為方框或亂碼?
A:原因及解決方案
1.字體未正確設(shè)置:
// 確保正確定義中文字體 #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:編譯時(shí)出現(xiàn)內(nèi)存不足錯(cuò)誤怎么辦?
A:優(yōu)化策略
禁用不必要的庫文件
減少全局變量使用
如果仍不足,可更換更小字體:
// 替代字體(約30KB)
#define CN_FONT u8g2_font_wqy12_t_gb2312
Q3:如何添加更多中文內(nèi)容?
A:擴(kuò)展方法
1.在drawStaticElements()中添加新元素
2.確保使用的字符在字體庫中存在:
// 添加新標(biāo)簽 drawDataBox(30, 250, "濕度", "%", HUMIDITY_COLOR);
3.如需生僻字,需自定義字體子集(本教程未包含)
注意:u8g2_font_unifont_t_chinese3包含GB2312一級字庫(3755個(gè)常用漢字),滿足大多數(shù)應(yīng)用需求。
Q4:傳感器初始化失敗怎么辦?
A:排查步驟
1.檢查I2C接線:SDA/SCL是否反接
2.確認(rèn)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供電穩(wěn)定
六、結(jié)論
本教程詳細(xì)講解了在STM32F407VET6零知增強(qiáng)板上實(shí)現(xiàn)ST7789顯示屏中文顯示的技術(shù)方案。通過使用U8g2_for_Adafruit_GFX庫,我們能夠:
高效渲染中文字符
保持與Adafruit_GFX的兼容性
實(shí)現(xiàn)中英文混合顯示
在有限的硬件資源下優(yōu)化性能
項(xiàng)目資源:
完整代碼鏈接: https://pan.baidu.com/s/1EPrOlbQ2wHjGa691qyf71Q?pwd=2kj7
大氣壓強(qiáng)傳感器:BMP581數(shù)據(jù)手冊
主控芯片:STM32F4參考手冊
通過本教程,開發(fā)者可以快速構(gòu)建穩(wěn)定可靠的環(huán)境監(jiān)測系統(tǒng),點(diǎn)擊了解更多零知開發(fā)教程:
https://www.lingzhilab.com/freesources.html
審核編輯 黃宇
-
SPI
+關(guān)注
關(guān)注
17文章
1804瀏覽量
96011 -
I2C
+關(guān)注
關(guān)注
28文章
1541瀏覽量
127878 -
STM32F4
+關(guān)注
關(guān)注
3文章
203瀏覽量
29054 -
氣壓傳感器
+關(guān)注
關(guān)注
4文章
141瀏覽量
21599 -
LVGL
+關(guān)注
關(guān)注
1文章
107瀏覽量
3711
發(fā)布評論請先 登錄
零知開源——STM32F1驅(qū)動(dòng)BMP581壓強(qiáng)傳感器使用SPI實(shí)現(xiàn)ST7789顯示的環(huán)境監(jiān)測系統(tǒng)
零知開源——STM32F4結(jié)合BMP581氣壓傳感器實(shí)現(xiàn)ST7789中文顯示教程
開源分享 - BMP180大氣壓傳感器模塊的使用
博世發(fā)布氣壓傳感器BMP581提供超高精度的高度追蹤功能

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

《博世氣壓傳感器BMP581產(chǎn)品分析》
讓我們?yōu)锳rduino和ST7789顯示器設(shè)計(jì)一個(gè)盾牌

評論