:除濕機(jī)LT165A 2.8寸屏驅(qū)動(dòng)與界面刷新實(shí)踐)
LT165A 2.8寸 320X240彩屏顯示方案適用于除濕機(jī)產(chǎn)品的人機(jī)交互面板。這個(gè)方案的核心并不是簡(jiǎn)單地把數(shù)碼管換成一塊彩色屏幕而是要讓用戶在“當(dāng)前濕度、目標(biāo)濕度、運(yùn)行模式、水箱狀態(tài)、故障提示”這些信息之間快速準(zhǔn)確地獲取狀態(tài)。2.8 英寸的尺寸適合放在除濕機(jī)前面板320×240 分辨率雖然屬于典型的 QVGA 規(guī)格但在家電屏幕上已經(jīng)能清楚展示漢字、圖標(biāo)、數(shù)字和簡(jiǎn)單曲線。要真正落地需要把顯示模組、驅(qū)動(dòng) IC、主控 MCU、界面刷新邏輯和整機(jī)控制邏輯放在一起考慮否則容易出現(xiàn)白屏、花屏、數(shù)據(jù)閃爍、界面卡頓等問題。本文面向正在做家電顯示方案的嵌入式工程師以及需要把 LT165A 模組接入到自有控制板上的開發(fā)者。文章會(huì)先拆解除濕機(jī)顯示需求再講如何準(zhǔn)備硬件和軟件環(huán)境然后給出最小驅(qū)動(dòng)工程、界面更新策略最后整理驗(yàn)證方法和常見問題排查鏈路。1. 先理解除濕機(jī)彩屏顯示的需求邊界1.1 除濕機(jī)面板到底要顯示什么除濕機(jī)不是一個(gè)高頻率操作的設(shè)備但它的人機(jī)交互狀態(tài)很多。用戶在機(jī)器前停留的時(shí)間通常只有幾秒所以顯示內(nèi)容必須一眼能看明白。常見的顯示項(xiàng)包括當(dāng)前環(huán)境濕度。當(dāng)前環(huán)境溫度。設(shè)定目標(biāo)濕度。當(dāng)前運(yùn)行模式例如自動(dòng)除濕、連續(xù)除濕、干衣模式。風(fēng)速檔位和擺風(fēng)狀態(tài)。水箱滿水提醒。濾網(wǎng)清潔或更換提醒。傳感器故障、壓縮機(jī)保護(hù)等故障碼。童鎖、定時(shí)開關(guān)機(jī)、Wi-Fi 連接狀態(tài)等附加功能。從內(nèi)容量上看如果只用 LED 數(shù)碼管顯示濕度數(shù)值還可以但要展示“濾網(wǎng)提醒”“故障代碼”和“模式導(dǎo)航”就會(huì)很吃力。LCD 彩屏的價(jià)值在于可以用分區(qū)和圖形來(lái)組織這些信息用戶不需要對(duì)著說(shuō)明書記憶圖標(biāo)含義。1.2 彩屏方案與段碼屏的差異除濕機(jī)行業(yè)里大量低端產(chǎn)品使用 LED 數(shù)碼管或段碼 LCD這類方案成本低、開發(fā)快、可靠性好但顯示內(nèi)容固定。彩屏方案的優(yōu)勢(shì)是靈活劣勢(shì)是開發(fā)復(fù)雜度、成本和故障面都會(huì)增加。對(duì)比項(xiàng)數(shù)碼管/段碼屏2.8 寸彩屏方案信息密度低只能顯示固定數(shù)字和少量符號(hào)高可顯示中文、圖形和動(dòng)態(tài)狀態(tài)交互層級(jí)簡(jiǎn)單按鍵切換比較獨(dú)立支持菜單、設(shè)置頁(yè)、故障頁(yè)開發(fā)工作量邏輯簡(jiǎn)單需要驅(qū)動(dòng)初始化、字庫(kù)、UI 刷新硬件成本低高含 TFT 模組、驅(qū)動(dòng)電路、主控資源故障排查容易需要區(qū)分軟件、驅(qū)動(dòng)、接口和電源問題對(duì) MCU 資源要求很低Flash 和 RAM 要求明顯升高在選型時(shí)不能只看屏幕單價(jià)。如果原有主控只是 8 位 MCU、幾 KB RAM加載 320×240 彩屏顯示幾乎不可行。常見做法是增加一顆帶硬件 SPI 的 32 位 MCU或者直接用帶 GUI 引擎的方案來(lái)承擔(dān)界面任務(wù)。1.3 LT165A 方案中屏幕、驅(qū)動(dòng) IC 和主控是三個(gè)概念方案名稱中的“LT165A”通??梢宰鳛槟=M編號(hào)或方案代號(hào)來(lái)理解但它本身并不等于一塊可以直接驅(qū)動(dòng)的標(biāo)準(zhǔn)屏。實(shí)際開發(fā)前要確認(rèn)三件事2.8 寸 320×240 是指屏幕玻璃和分辨率。屏幕模組上的 LCD 驅(qū)動(dòng) IC 型號(hào)是什么例如常見驅(qū)動(dòng) IC 會(huì)有各自的初始化寄存器序列。主控 MCU 和顯示模組之間使用哪種接口可能是 SPI、8080 并口也可能是 RGB 接口。很多工程師拿到“LT165A 2.8寸 320X240”后直接復(fù)用網(wǎng)上其他 2.8 寸屏的初始化代碼結(jié)果花屏原因就是驅(qū)動(dòng) IC 不一致。320×240 只說(shuō)明像素總數(shù)不代表代碼通用。起步階段最重要的動(dòng)作是向屏廠索要該模組對(duì)應(yīng)驅(qū)動(dòng) IC 的 datasheet 和推薦初始化序列并把模組接口定義逐腳確認(rèn)清楚。2. 硬件平臺(tái)和軟件依賴要先對(duì)齊2.1 搭建彩屏方案需要準(zhǔn)備哪些物料除濕機(jī)彩屏顯示并不是一個(gè)純軟件項(xiàng)目。開發(fā)階段至少需要準(zhǔn)備以下部分主控開發(fā)板或樣機(jī)控制板。LT165A 2.8 寸彩屏模組。邏輯分析儀或示波器用于檢查 SPI 時(shí)序。溫濕度傳感器用來(lái)模擬除濕機(jī)實(shí)際數(shù)據(jù)源??煽?3.3V 電源避免用開發(fā)板 USB 供電帶動(dòng)大背光。按鍵、繼電器、蜂鳴器等外圍控制器件如果要做整機(jī)聯(lián)調(diào)。主控 MCU 的選擇很關(guān)鍵。對(duì) 320×240 彩屏而言建議優(yōu)先選擇帶硬件 SPI、主頻不低于幾十 MHz、Flash 至少 128KB 的 MCU。如果要在屏幕上做多級(jí)菜單、中文漢字庫(kù)和較多圖標(biāo)資源Flash 需求很容易達(dá)到 256KB 以上。若使用 LVGL 等圖形庫(kù)還要關(guān)注 RAM 大小因?yàn)榭丶?duì)象、顯示緩存和事件處理都會(huì)占用 RAM。2.2 屏幕接口與引腳規(guī)劃要逐腳確認(rèn)2.8 寸彩屏模組常用 4 線 SPI 或 8080 并口。SPI 方案占用 IO 少適合中低端家電控制板8080 并口傳輸快但占用 IO 多。選擇接口前要確認(rèn)主控硬件是否支持對(duì)應(yīng)的物理接口。下面是一份常見 SPI 接線參考具體引腳順序以實(shí)際模組規(guī)格書為準(zhǔn)。模組引腳功能說(shuō)明建議連接VCC模組電源3.3V 穩(wěn)壓輸出GND地公共地SCLSPI 時(shí)鐘MCU SPI SCKSDASPI 數(shù)據(jù)MCU SPI MOSICS片選MCU GPIO 或 SPI CSD/C 或 RS命令/數(shù)據(jù)選擇MCU GPIORESET硬件復(fù)位MCU GPIOBLK背光控制MCU GPIO 或 PWM 引腳如果是 8080 并口模組則還需要 WR、RD、CS、D/C 以及 DB0 到 DB15 等數(shù)據(jù)線。連接時(shí)不要憑顏色接線因?yàn)椴煌翉S對(duì)排線顏色定義可能不同。上電前可以用萬(wàn)用表測(cè)量 VCC 和 GND確認(rèn)沒有反接。2.3 顯示方案選擇底層繪圖、串口屏還是 LVGL“LT165A 2.8寸 320X240顯示方案”在不同開發(fā)團(tuán)隊(duì)里落地方式完全不同。常見有三類方案一主控 MCU 直接驅(qū)動(dòng) LCD 模組。根據(jù)界面復(fù)雜度使用底層繪圖函數(shù)或輕量 UI 框架。代碼可控性強(qiáng)但開發(fā)周期較長(zhǎng)。方案二使用可編程串口屏。屏幕模塊自帶主控和矢量字庫(kù)整機(jī) MCU 只需通過(guò)串口發(fā)送指令更新數(shù)據(jù)。開發(fā)快但成本相對(duì)高。方案三在主控上跑 LVGL 或類似圖形庫(kù)。需要 MCU 有足夠 Flash/RAM適合做復(fù)雜菜單、動(dòng)畫和觸摸交互。如果產(chǎn)品以顯示數(shù)值和簡(jiǎn)單狀態(tài)為主不推薦一開始就引入大型 GUI 框架。先把手寫字體、畫矩形、畫字符串、局部刷新做通能減少不少資源問題。后續(xù)界面復(fù)雜了再把這些底層接口封裝給 LVGL 使用。3. 從點(diǎn)屏到顯示數(shù)據(jù)搭建最小驅(qū)動(dòng)工程3.1 用 SPI 方式完成屏幕初始化和顏色填充下面的代碼以 SPI 型 TFT 模組為例演示最基礎(chǔ)的驅(qū)動(dòng)結(jié)構(gòu)。實(shí)際 LT165A 模組如果使用 8080 并口只需要把寫命令和寫數(shù)據(jù)的函數(shù)改成并口時(shí)序其余窗口和繪圖邏輯可以復(fù)用。先定義基本的寫命令和寫數(shù)據(jù)函數(shù)#define LCD_CS_LOW() HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_RESET) #define LCD_CS_HIGH() HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_SET) #define LCD_DC_LOW() HAL_GPIO_WritePin(LCD_DC_GPIO_Port, LCD_DC_Pin, GPIO_PIN_RESET) #define LCD_DC_HIGH() HAL_GPIO_WritePin(LCD_DC_GPIO_Port, LCD_DC_Pin, GPIO_PIN_SET) #define LCD_RST_LOW() HAL_GPIO_WritePin(LCD_RST_GPIO_Port, LCD_RST_Pin, GPIO_PIN_RESET) #define LCD_RST_HIGH() HAL_GPIO_WritePin(LCD_RST_GPIO_Port, LCD_RST_Pin, GPIO_PIN_SET) static void lcd_write_cmd(uint8_t cmd) { LCD_DC_LOW(); LCD_CS_LOW(); spi_transmit_byte(cmd); LCD_CS_HIGH(); } static void lcd_write_data_byte(uint8_t data) { LCD_DC_HIGH(); LCD_CS_LOW(); spi_transmit_byte(data); LCD_CS_HIGH(); }這里spi_transmit_byte是底層發(fā)送單字節(jié)的函數(shù)內(nèi)部可以調(diào)用 MCU 的硬件 SPI 接口。每次寫命令前要把 D/C 拉低寫數(shù)據(jù)前要把 D/C 拉高。CS 的作用是片選避免總線上其他設(shè)備干擾。初始化函數(shù)需要完成復(fù)位、退出休眠、設(shè)置像素格式、設(shè)置掃描方向和開啟顯示等操作void lcd_init(void) { LCD_RST_HIGH(); delay_ms(20); LCD_RST_LOW(); delay_ms(20); LCD_RST_HIGH(); delay_ms(120); lcd_write_cmd(0x11); // Sleep Out delay_ms(120); lcd_write_cmd(0x36); // Memory Access Control lcd_write_data_byte(0x08); // 根據(jù)安裝方向調(diào)整掃描方向 lcd_write_cmd(0x3A); // Interface Pixel Format lcd_write_data_byte(0x55); // RGB565, 16bpp lcd_write_cmd(0x29); // Display ON delay_ms(20); }這段初始化命令只是常見模組的基礎(chǔ)序列。LT165A 模組上的驅(qū)動(dòng) IC 不同可能還需要設(shè)置電源、伽馬、視角等寄存器。不要把所有屏的初始化代碼混用必須以屏廠提供的數(shù)據(jù)手冊(cè)為準(zhǔn)。3.2 設(shè)置顯示窗口和填充矩形320×240 分辨率下屏幕左上角坐標(biāo)是 (0,0)右下角坐標(biāo)是 (319,239)。要刷新某個(gè)區(qū)域先通過(guò)命令設(shè)置列地址和行地址再連續(xù)發(fā)送像素?cái)?shù)據(jù)。void lcd_set_window(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) { lcd_write_cmd(0x2A); // Column Address Set lcd_write_data_byte(x0 8); lcd_write_data_byte(x0 0xFF); lcd_write_data_byte(x1 8); lcd_write_data_byte(x1 0xFF); lcd_write_cmd(0x2B); // Row Address Set lcd_write_data_byte(y0 8); lcd_write_data_byte(y0 0xFF); lcd_write_data_byte(y1 8); lcd_write_data_byte(y1 0xFF); lcd_write_cmd(0x2C); // Memory Write }設(shè)置窗口后后續(xù)發(fā)送的數(shù)據(jù)會(huì)按“從左到右、從上到下”的順序?qū)懭肫聊豢刂破鞯娘@存。填充整個(gè)屏幕不需要單獨(dú)設(shè)置每個(gè)點(diǎn)只需要設(shè)置一次窗口然后連續(xù)發(fā) 320×240 個(gè)像素。RGB565 模式下一個(gè)像素占 2 字節(jié)。整屏像素?cái)?shù)量是320 * 240 76800 76800 * 2 153600 字節(jié)因此最小填充函數(shù)可以寫成void lcd_fill_rect(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color) { uint32_t pixel_count; uint16_t x; uint16_t y; uint8_t color_hi color 8; uint8_t color_lo color 0xFF; lcd_set_window(x0, y0, x1, y1); pixel_count (uint32_t)(x1 - x0 1) * (y1 - y0 1); for (uint32_t i 0; i pixel_count; i) { lcd_write_data_byte(color_hi); lcd_write_data_byte(color_lo); } }在調(diào)試階段可以先調(diào)用lcd_fill_rect(0, 0, 319, 239, 0xF800)確認(rèn)屏幕能顯示純紅色再分別嘗試0x07E0綠色和0x001F藍(lán)色。如果紅綠藍(lán)顯示錯(cuò)位往往和 RGB 顏色順序配置有關(guān)需要在初始化數(shù)組里調(diào)整。3.3 不要在主控里保存整幅 RGB565 幀緩存很多第一次接觸彩屏的人會(huì)下意識(shí)設(shè)計(jì)一個(gè) 320×240×2 字節(jié)的全局?jǐn)?shù)組當(dāng)作 framebuffer。這個(gè)數(shù)組需要 150KB RAM普通低成本 MCU 根本放不下。正確思路是讓 LCD 模組內(nèi)部的顯示 RAM 充當(dāng)“屏幕緩存”MCU 只在需要更新某個(gè)區(qū)域時(shí)把變化區(qū)域的數(shù)據(jù)送給屏幕。如果界面確實(shí)需要復(fù)雜圖層疊加、窗口裁剪和動(dòng)畫才考慮在外部 SDRAM 或大容量 MCU 中開辟局部緩存。對(duì)于除濕機(jī)這類狀態(tài)變化頻率較低的設(shè)備直接局部刷新即可。4. 除濕機(jī)控制邏輯與顯示刷新如何配合4.1 把采集、控制和顯示拆成不同職責(zé)驅(qū)動(dòng)層面跑通之后最容易犯的錯(cuò)誤是把顯示刷新代碼直接寫進(jìn)濕度采集或按鍵中斷里。除濕機(jī)的主控還要管壓縮機(jī)、風(fēng)機(jī)、水箱檢測(cè)和傳感器讀取顯示功能只是其中一部分。推薦結(jié)構(gòu)是把數(shù)據(jù)放在一個(gè)公共結(jié)構(gòu)體中控制邏輯負(fù)責(zé)更新結(jié)構(gòu)體顯示邏輯只讀取結(jié)構(gòu)體并渲染。typedef enum { MODE_AUTO 0, MODE_CONTINUOUS, MODE_DRY, MODE_MAX } DehumMode; typedef struct { uint16_t current_humidity; // 當(dāng)前濕度單位 0.1%RH int16_t current_temperature; // 當(dāng)前溫度單位 0.1°C uint16_t target_humidity; DehumMode mode; uint8_t wind_level; uint8_t water_tank_full; uint8_t filter_warning; } DehumDisplayData; DehumDisplayData g_display_data;主循環(huán)定時(shí)讀取溫濕度傳感器然后更新g_display_data。顯示模塊在刷新周期到來(lái)時(shí)只讀取這個(gè)結(jié)構(gòu)體再?zèng)Q定哪些區(qū)域需要重繪。4.2 界面分層和刷新節(jié)奏除濕機(jī)界面一般可以分成三層靜態(tài)層背景色、標(biāo)題欄、狀態(tài)圖標(biāo)框。這類內(nèi)容只在切換頁(yè)面或初始化時(shí)刷新。數(shù)值層當(dāng)前濕度、設(shè)定濕度、溫度。數(shù)值變化時(shí)才刷新不需要整屏重繪。告警層水箱滿、濾網(wǎng)提醒、故障碼。這類內(nèi)容需要第一時(shí)間彈出或閃爍提示。刷新頻率也應(yīng)根據(jù)內(nèi)容區(qū)分。環(huán)境濕度變化緩慢1 秒刷新一次已經(jīng)足夠按鍵操作導(dǎo)致的模式切換應(yīng)當(dāng)立即刷新水箱滿和傳感器故障屬于告警應(yīng)當(dāng)使用事件觸發(fā)而不是在循環(huán)里反復(fù)畫同一張圖。顯示區(qū)域建議刷新策略原因當(dāng)前濕度數(shù)值每 500ms 到 1s濕度本身變化慢太快會(huì)顯得數(shù)值跳動(dòng)目標(biāo)濕度用戶設(shè)置變化時(shí)設(shè)置動(dòng)作需要即時(shí)反饋模式/風(fēng)速圖標(biāo)狀態(tài)切換時(shí)按鍵即時(shí)性要求高水箱滿/故障碼事件觸發(fā)異常告警需要第一時(shí)間看到背景和邊框頁(yè)面初始化或切換時(shí)靜態(tài)內(nèi)容無(wú)需反復(fù)發(fā)送4.3 除濕機(jī)特有的異常狀態(tài)需要有獨(dú)立頁(yè)面或彈窗除濕機(jī)工作環(huán)境通常比較潮濕某些異常狀態(tài)比其他家電更頻繁。例如水箱滿水、排水管堵塞、蒸發(fā)器需要化霜、濕度傳感器失效、壓縮機(jī)啟動(dòng)保護(hù)等。屏幕顯示這些狀態(tài)時(shí)不能只在某個(gè)角落顯示一個(gè)小圖標(biāo)最好同時(shí)顯示用戶可執(zhí)行動(dòng)作。例如水箱滿時(shí)界面可以先彈出全屏或半屏提示水箱已滿 請(qǐng)清空水箱后放回這樣可以避免用戶只在面板上看到一個(gè)不認(rèn)識(shí)的水滴圖標(biāo)。故障碼顯示也要和用戶文案組合起來(lái)例如底層顯示“E1”旁邊再顯示“濕度傳感器異?!狈奖闶酆蠛陀脩襞袛唷?.4 數(shù)據(jù)變化要做去抖和上下限處理濕度傳感器在風(fēng)機(jī)啟動(dòng)、壓縮機(jī)啟停瞬間會(huì)出現(xiàn)短暫跳變。如果直接把原始值送往屏幕用戶會(huì)看到濕度數(shù)值在小范圍內(nèi)頻繁閃跳。軟件上需要做兩層處理連續(xù)采樣或者滑動(dòng)平均。顯示值和上次刷新值之間的差值小于閾值時(shí)不更新。簡(jiǎn)單實(shí)現(xiàn)示例void display_update_humidity(uint16_t new_humidity) { static uint16_t last_humidity 0; const uint16_t display_diff_threshold 15; // 1.5%RH if (new_humidity last_humidity display_diff_threshold || new_humidity last_humidity - display_diff_threshold) { draw_humidity_value(new_humidity); last_humidity new_humidity; } }這里閾值要結(jié)合實(shí)際產(chǎn)品體驗(yàn)調(diào)整。閾值過(guò)大用戶會(huì)抱怨?jié)穸葦?shù)值不更新閾值過(guò)小顯示會(huì)一直跳動(dòng)。通常先用 1% 到 2% 的相對(duì)濕度作為起步值再根據(jù)整機(jī)風(fēng)道和傳感器位置修正。5. 點(diǎn)屏成功不等于整機(jī)正常運(yùn)行驗(yàn)證和問題排查5.1 從黑屏到顯示數(shù)據(jù)的驗(yàn)證順序拿到新模組后不要直接寫完整 UI先按最小步驟驗(yàn)證硬件和驅(qū)動(dòng)確認(rèn) 3.3V 電源穩(wěn)定背光是否點(diǎn)亮。用邏輯分析儀或示波器檢查 RESET、CS、DC、SCL 信號(hào)是否出現(xiàn)。先用lcd_fill_rect填充純色確認(rèn) RGB 順序正確。再顯示橫線和豎線確認(rèn)坐標(biāo)方向和掃描方向。最后顯示數(shù)字和中文確認(rèn)字庫(kù)和字符繪制函數(shù)正確。接入真實(shí)傳感器觀察數(shù)值連續(xù)變化是否平滑。每一步都有明確結(jié)果遇到問題就能縮小范圍。5.2 白屏、花屏、閃爍等常見異常分析實(shí)際項(xiàng)目中最常見的顯示問題可以歸納為下面幾類問題現(xiàn)象可能原因檢查方式處理建議背光亮但無(wú)內(nèi)容白屏或黑屏LCD 驅(qū)動(dòng) IC 未初始化成功檢查復(fù)位時(shí)序、初始化數(shù)組、SPI 數(shù)據(jù)確認(rèn)驅(qū)動(dòng) IC 型號(hào)按規(guī)格書初始化花屏或顏色錯(cuò)亂RGB 順序配置錯(cuò)誤或掃描方向不對(duì)填充純色對(duì)比紅綠藍(lán)輸出修改像素格式和 MADCTL 參數(shù)橫向豎線、條紋或水波紋SPI 速率過(guò)高或電源紋波大降低 SPI 時(shí)鐘用示波器看波形分頻降低時(shí)鐘加濾波電容畫面上下左右顛倒寫入掃描方向參數(shù)不對(duì)檢查屏幕安裝方向修改內(nèi)存訪問控制寄存器顯示內(nèi)容殘缺地址窗口或幀緩存越界檢查坐標(biāo)最大值和像素循環(huán)長(zhǎng)度限制窗口不超過(guò) 319×239數(shù)值閃跳傳感器值未濾波或刷新頻率過(guò)高打印原始值和濾波值加入滑動(dòng)濾波和變化閾值如果屏幕之前點(diǎn)亮過(guò)代碼改動(dòng)后突然花屏優(yōu)先檢查是否改動(dòng)了初始化寄存器、坐標(biāo)窗口或者 SPI 時(shí)鐘配置不需要馬上懷疑硬件損壞。5.3 除濕機(jī)環(huán)境里要額外關(guān)注電源和干擾除濕機(jī)內(nèi)部有壓縮機(jī)、風(fēng)機(jī)、繼電器和水滿傳感器這些都是常見的干擾源。彩屏顯示模組對(duì)電源噪聲相對(duì)敏感尤其是 SPI 通信發(fā)生在壓縮機(jī)啟動(dòng)或繼電器吸合瞬間時(shí)可能造成畫面數(shù)據(jù)錯(cuò)亂。生產(chǎn)項(xiàng)目中需要注意以下幾點(diǎn)顯示模組電源和功率負(fù)載電源盡量分開走線避免繼電器動(dòng)作時(shí)拉低 3.3V。信號(hào)線使用短走線或雙絞線SPI 時(shí)鐘頻率不要盲目調(diào)到最高。MCU 和屏幕之間加 100nF 去耦電容電源入口根據(jù)電流選擇合適容量的電解電容。軟件刷新盡量避開繼電器動(dòng)作時(shí)間或者把大區(qū)域刷新放到繼電器動(dòng)作完成后的穩(wěn)定時(shí)間窗口。5.4 排錯(cuò)時(shí)應(yīng)從現(xiàn)象倒推原因遇到顯示異常時(shí)不要先改代碼。先確認(rèn)輸入和前提條件是否正確模組供電電壓是否符合要求、初始化是否成功、SPI 是否實(shí)際發(fā)出數(shù)據(jù)、坐標(biāo)是否在 320×240 范圍內(nèi)、驅(qū)動(dòng)芯片和初始化數(shù)組是否匹配。排查順序一般是先查硬件連接和電源。再查 SPI 波形和時(shí)序。然后確認(rèn)初始化命令是否執(zhí)行完。接著用純色填充代替完整 UI定位是繪圖問題還是 UI 邏輯問題。最后檢查數(shù)據(jù)源是否有異常值。只有按這個(gè)順序排查才能避免在錯(cuò)誤方向反復(fù)調(diào)參。6. 從樣品到量產(chǎn)資源規(guī)劃與工程維護(hù)建議6.1 顯示代碼按分層方式組織不要全部堆在 main.c當(dāng)項(xiàng)目進(jìn)入量產(chǎn)階段顯示邏輯通常不再只有一兩個(gè)函數(shù)。建議按功能拆文件project ├── bsp_lcd │ ├── lcd_drv.c │ └── lcd_drv.h ├── gui │ ├── ui_main_page.c │ ├── ui_fault_page.c │ ├── ui_common.c │ └── ui_common.h ├── fonts │ ├── font_ascii.c │ └── font_chinese.c ├── hal │ ├── spi_conf.c │ ├── gpio_conf.c │ └── delay.c └── app ├── app_main.c └── display_data.cbsp_lcd只負(fù)責(zé)屏幕初始化和點(diǎn)線面、字符輸出等基礎(chǔ)接口。gui層負(fù)責(zé)具體頁(yè)面排版。app層采集濕度、溫度、按鍵和水箱狀態(tài)并把數(shù)據(jù)交給顯示頁(yè)面。這樣后續(xù)更換屏幕型號(hào)時(shí)只需要替換bsp_lcd層。6.2 圖片和字庫(kù)資源要評(píng)估 Flash 占用320×240 全屏背景圖如果直接按 RGB565 轉(zhuǎn)成 C 數(shù)組大小會(huì)很大。例如一張全屏背景位圖占 150KB放幾張頁(yè)面就能把 MCU Flash 耗盡。實(shí)際項(xiàng)目中背景盡量使用程序繪制漸變、色塊和矩形框而不是從美工導(dǎo)出整幅圖片。真正無(wú)法用代碼繪制的圖片再用 RLE 壓縮或轉(zhuǎn)換成適合 MCU 的格式。資源大小估算建議全屏 RGB565 背景圖320×240×2 150KB盡量程序繪制不直接存全屏圖常用 16×16 中文字庫(kù)每個(gè)字約 32 字節(jié)幾千字約 64KB按產(chǎn)品需求裁剪字符ASCII 字庫(kù)很小可直接使用全 ASCII圖標(biāo)按鈕取決于數(shù)量使用透明通道或按 UI 風(fēng)格統(tǒng)一如果使用 LVGL字庫(kù)還要考慮抗鋸齒和緩存占用。不要在最終產(chǎn)品里保留所有測(cè)試字體和測(cè)試圖片發(fā)布前需要做一次資源裁剪。6.3 鍵盤操作和界面狀態(tài)要做狀態(tài)機(jī)除濕機(jī)通常按鍵較少顯示界面卻可能有設(shè)置目標(biāo)濕度、模式選擇、定時(shí)設(shè)置和故障彈窗。直接用多個(gè)全局標(biāo)志位控制界面頁(yè)面一多就會(huì)失控。推薦用頁(yè)面狀態(tài)機(jī)typedef enum { PAGE_MAIN 0, PAGE_SET_HUMIDITY, PAGE_TIMER, PAGE_FAULT, PAGE_MAX } UiPageId; static UiPageId s_current_page PAGE_MAIN; void ui_switch_page(UiPageId new_page) { if (new_page PAGE_MAX || new_page s_current_page) { return; } ui_page_on_exit(s_current_page); s_current_page new_page; ui_page_on_enter(s_current_page); }每個(gè)頁(yè)面定義進(jìn)入和退出處理頁(yè)面之間切換時(shí)先清理舊頁(yè)面再繪制新頁(yè)面。這樣可以防止上一頁(yè)的內(nèi)容殘留到下一頁(yè)。6.4 量產(chǎn)前需要做的顯示相關(guān)測(cè)試清單24 小時(shí)長(zhǎng)時(shí)間運(yùn)行觀察是否出現(xiàn)隨機(jī)花屏。溫度從低溫到高溫變化環(huán)境下的顯示刷新是否異常。繼電器反復(fù)啟停時(shí)畫面是否出現(xiàn)干擾條紋??彀窗存I和慢按按鍵時(shí)頁(yè)面切換是否正常。斷電再上電屏幕是否能恢復(fù)顯示是否會(huì)短暫白屏。水箱滿、傳感器斷開、壓縮機(jī)保護(hù)等故障場(chǎng)景顯示是否準(zhǔn)確。不同溫濕度傳感器樣本下數(shù)值偏差是否在可接受范圍。SPI 時(shí)鐘在不同速率、不同批次板卡上的裕量是否足夠。彩屏顯示方案在除濕機(jī)上的難點(diǎn)往往不在“點(diǎn)亮屏幕”而在于控制邏輯、顯示資源和整機(jī)可靠性之間的平衡。LT165A 2.8 寸 320×240 屏是否能穩(wěn)定落地關(guān)鍵看驅(qū)動(dòng) IC 是否匹配、界面刷新策略是否合理、顯示代碼是否和功率控制部分做好隔離。先把底層驅(qū)動(dòng)和頁(yè)面框架做扎實(shí)再根據(jù)真實(shí)傳感器數(shù)據(jù)調(diào)整刷新邏輯方案才能真正進(jìn)入量產(chǎn)。