LT165A 2.8寸 320X240彩屏显示方案,适用于除湿机产品的人机交互面板。这个方案的核心并不是简单地把数码管换成一块彩色屏幕,而是要让用户在“当前湿度、目标湿度、运行模式、水箱状态、故障提示”这些信息之间快速准确地获取状态。2.8 英寸的尺寸适合放在除湿机前面板,320×240 分辨率虽然属于典型的 QVGA 规格,但在家电屏幕上已经能清楚展示汉字、图标、数字和简单曲线。要真正落地,需要把显示模组、驱动 IC、主控 MCU、界面刷新逻辑和整机控制逻辑放在一起考虑,否则容易出现白屏、花屏、数据闪烁、界面卡顿等问题。
本文面向正在做家电显示方案的嵌入式工程师,以及需要把 LT165A 模组接入到自有控制板上的开发者。文章会先拆解除湿机显示需求,再讲如何准备硬件和软件环境,然后给出最小驱动工程、界面更新策略,最后整理验证方法和常见问题排查链路。
1. 先理解除湿机彩屏显示的需求边界
1.1 除湿机面板到底要显示什么
除湿机不是一个高频率操作的设备,但它的人机交互状态很多。用户在机器前停留的时间通常只有几秒,所以显示内容必须一眼能看明白。常见的显示项包括:
- 当前环境湿度。
- 当前环境温度。
- 设定目标湿度。
- 当前运行模式,例如自动除湿、连续除湿、干衣模式。
- 风速档位和摆风状态。
- 水箱满水提醒。
- 滤网清洁或更换提醒。
- 传感器故障、压缩机保护等故障码。
- 童锁、定时开关机、Wi-Fi 连接状态等附加功能。
从内容量上看,如果只用 LED 数码管,显示湿度数值还可以,但要展示“滤网提醒”“故障代码”和“模式导航”就会很吃力。LCD 彩屏的价值在于可以用分区和图形来组织这些信息,用户不需要对着说明书记忆图标含义。
1.2 彩屏方案与段码屏的差异
除湿机行业里大量低端产品使用 LED 数码管或段码 LCD,这类方案成本低、开发快、可靠性好,但显示内容固定。彩屏方案的优势是灵活,劣势是开发复杂度、成本和故障面都会增加。
| 对比项 | 数码管/段码屏 | 2.8 寸彩屏方案 |
|---|---|---|
| 信息密度 | 低,只能显示固定数字和少量符号 | 高,可显示中文、图形和动态状态 |
| 交互层级 | 简单,按键切换比较独立 | 支持菜单、设置页、故障页 |
| 开发工作量 | 逻辑简单 | 需要驱动初始化、字库、UI 刷新 |
| 硬件成本 | 低 | 高,含 TFT 模组、驱动电路、主控资源 |
| 故障排查 | 容易 | 需要区分软件、驱动、接口和电源问题 |
| 对 MCU 资源要求 | 很低 | Flash 和 RAM 要求明显升高 |
在选型时不能只看屏幕单价。如果原有主控只是 8 位 MCU、几 KB RAM,加载 320×240 彩屏显示几乎不可行。常见做法是增加一颗带硬件 SPI 的 32 位 MCU,或者直接用带 GUI 引擎的方案来承担界面任务。
1.3 LT165A 方案中屏幕、驱动 IC 和主控是三个概念
方案名称中的“LT165A”通常可以作为模组编号或方案代号来理解,但它本身并不等于一块可以直接驱动的标准屏。实际开发前要确认三件事:
- 2.8 寸 320×240 是指屏幕玻璃和分辨率。
- 屏幕模组上的 LCD 驱动 IC 型号是什么,例如常见驱动 IC 会有各自的初始化寄存器序列。
- 主控 MCU 和显示模组之间使用哪种接口,可能是 SPI、8080 并口,也可能是 RGB 接口。
很多工程师拿到“LT165A 2.8寸 320X240”后,直接复用网上其他 2.8 寸屏的初始化代码,结果花屏,原因就是驱动 IC 不一致。320×240 只说明像素总数,不代表代码通用。起步阶段最重要的动作是向屏厂索要该模组对应驱动 IC 的 datasheet 和推荐初始化序列,并把模组接口定义逐脚确认清楚。
2. 硬件平台和软件依赖要先对齐
2.1 搭建彩屏方案需要准备哪些物料
除湿机彩屏显示并不是一个纯软件项目。开发阶段至少需要准备以下部分:
- 主控开发板或样机控制板。
- LT165A 2.8 寸彩屏模组。
- 逻辑分析仪或示波器,用于检查 SPI 时序。
- 温湿度传感器,用来模拟除湿机实际数据源。
- 可靠 3.3V 电源,避免用开发板 USB 供电带动大背光。
- 按键、继电器、蜂鸣器等外围控制器件,如果要做整机联调。
主控 MCU 的选择很关键。对 320×240 彩屏而言,建议优先选择带硬件 SPI、主频不低于几十 MHz、Flash 至少 128KB 的 MCU。如果要在屏幕上做多级菜单、中文汉字库和较多图标资源,Flash 需求很容易达到 256KB 以上。若使用 LVGL 等图形库,还要关注 RAM 大小,因为控件对象、显示缓存和事件处理都会占用 RAM。
2.2 屏幕接口与引脚规划要逐脚确认
2.8 寸彩屏模组常用 4 线 SPI 或 8080 并口。SPI 方案占用 IO 少,适合中低端家电控制板;8080 并口传输快,但占用 IO 多。选择接口前要确认主控硬件是否支持对应的物理接口。下面是一份常见 SPI 接线参考,具体引脚顺序以实际模组规格书为准。
| 模组引脚 | 功能说明 | 建议连接 |
|---|---|---|
| VCC | 模组电源 | 3.3V 稳压输出 |
| GND | 地 | 公共地 |
| SCL | SPI 时钟 | MCU SPI SCK |
| SDA | SPI 数据 | MCU SPI MOSI |
| CS | 片选 | MCU GPIO 或 SPI CS |
| D/C 或 RS | 命令/数据选择 | MCU GPIO |
| RESET | 硬件复位 | MCU GPIO |
| BLK | 背光控制 | MCU GPIO 或 PWM 引脚 |
如果是 8080 并口模组,则还需要 WR、RD、CS、D/C 以及 DB0 到 DB15 等数据线。连接时不要凭颜色接线,因为不同屏厂对排线颜色定义可能不同。上电前可以用万用表测量 VCC 和 GND,确认没有反接。
2.3 显示方案选择:底层绘图、串口屏还是 LVGL
“LT165A 2.8寸 320X240显示方案”在不同开发团队里落地方式完全不同。常见有三类:
- 方案一:主控 MCU 直接驱动 LCD 模组。根据界面复杂度,使用底层绘图函数或轻量 UI 框架。代码可控性强,但开发周期较长。
- 方案二:使用可编程串口屏。屏幕模块自带主控和矢量字库,整机 MCU 只需通过串口发送指令更新数据。开发快,但成本相对高。
- 方案三:在主控上跑 LVGL 或类似图形库。需要 MCU 有足够 Flash/RAM,适合做复杂菜单、动画和触摸交互。
如果产品以显示数值和简单状态为主,不推荐一开始就引入大型 GUI 框架。先把手写字体、画矩形、画字符串、局部刷新做通,能减少不少资源问题。后续界面复杂了,再把这些底层接口封装给 LVGL 使用。
3. 从点屏到显示数据:搭建最小驱动工程
3.1 用 SPI 方式完成屏幕初始化和颜色填充
下面的代码以 SPI 型 TFT 模组为例,演示最基础的驱动结构。实际 LT165A 模组如果使用 8080 并口,只需要把写命令和写数据的函数改成并口时序,其余窗口和绘图逻辑可以复用。
先定义基本的写命令和写数据函数:
#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是底层发送单字节的函数,内部可以调用 MCU 的硬件 SPI 接口。每次写命令前要把 D/C 拉低,写数据前要把 D/C 拉高。CS 的作用是片选,避免总线上其他设备干扰。
初始化函数需要完成复位、退出休眠、设置像素格式、设置扫描方向和开启显示等操作:
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); // 根据安装方向调整扫描方向 lcd_write_cmd(0x3A); // Interface Pixel Format lcd_write_data_byte(0x55); // RGB565, 16bpp lcd_write_cmd(0x29); // Display ON delay_ms(20); }这段初始化命令只是常见模组的基础序列。LT165A 模组上的驱动 IC 不同,可能还需要设置电源、伽马、视角等寄存器。不要把所有屏的初始化代码混用,必须以屏厂提供的数据手册为准。
3.2 设置显示窗口和填充矩形
320×240 分辨率下,屏幕左上角坐标是 (0,0),右下角坐标是 (319,239)。要刷新某个区域,先通过命令设置列地址和行地址,再连续发送像素数据。
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 }设置窗口后,后续发送的数据会按“从左到右、从上到下”的顺序写入屏幕控制器的显存。填充整个屏幕不需要单独设置每个点,只需要设置一次窗口,然后连续发 320×240 个像素。
RGB565 模式下,一个像素占 2 字节。整屏像素数量是:
320 * 240 = 76800 76800 * 2 = 153600 字节因此最小填充函数可以写成:
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); } }在调试阶段,可以先调用lcd_fill_rect(0, 0, 319, 239, 0xF800),确认屏幕能显示纯红色;再分别尝试0x07E0绿色和0x001F蓝色。如果红绿蓝显示错位,往往和 RGB 颜色顺序配置有关,需要在初始化数组里调整。
3.3 不要在主控里保存整幅 RGB565 帧缓存
很多第一次接触彩屏的人会下意识设计一个 320×240×2 字节的全局数组当作 framebuffer。这个数组需要 150KB RAM,普通低成本 MCU 根本放不下。正确思路是让 LCD 模组内部的显示 RAM 充当“屏幕缓存”,MCU 只在需要更新某个区域时,把变化区域的数据送给屏幕。
如果界面确实需要复杂图层叠加、窗口裁剪和动画,才考虑在外部 SDRAM 或大容量 MCU 中开辟局部缓存。对于除湿机这类状态变化频率较低的设备,直接局部刷新即可。
4. 除湿机控制逻辑与显示刷新如何配合
4.1 把采集、控制和显示拆成不同职责
驱动层面跑通之后,最容易犯的错误是把显示刷新代码直接写进湿度采集或按键中断里。除湿机的主控还要管压缩机、风机、水箱检测和传感器读取,显示功能只是其中一部分。
推荐结构是把数据放在一个公共结构体中,控制逻辑负责更新结构体,显示逻辑只读取结构体并渲染。
typedef enum { MODE_AUTO = 0, MODE_CONTINUOUS, MODE_DRY, MODE_MAX } DehumMode; typedef struct { uint16_t current_humidity; // 当前湿度,单位 0.1%RH int16_t current_temperature; // 当前温度,单位 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;主循环定时读取温湿度传感器,然后更新g_display_data。显示模块在刷新周期到来时,只读取这个结构体,再决定哪些区域需要重绘。
4.2 界面分层和刷新节奏
除湿机界面一般可以分成三层:
- 静态层:背景色、标题栏、状态图标框。这类内容只在切换页面或初始化时刷新。
- 数值层:当前湿度、设定湿度、温度。数值变化时才刷新,不需要整屏重绘。
- 告警层:水箱满、滤网提醒、故障码。这类内容需要第一时间弹出或闪烁提示。
刷新频率也应根据内容区分。环境湿度变化缓慢,1 秒刷新一次已经足够;按键操作导致的模式切换,应当立即刷新;水箱满和传感器故障属于告警,应当使用事件触发,而不是在循环里反复画同一张图。
| 显示区域 | 建议刷新策略 | 原因 |
|---|---|---|
| 当前湿度数值 | 每 500ms 到 1s | 湿度本身变化慢,太快会显得数值跳动 |
| 目标湿度 | 用户设置变化时 | 设置动作需要即时反馈 |
| 模式/风速图标 | 状态切换时 | 按键即时性要求高 |
| 水箱满/故障码 | 事件触发 | 异常告警需要第一时间看到 |
| 背景和边框 | 页面初始化或切换时 | 静态内容无需反复发送 |
4.3 除湿机特有的异常状态需要有独立页面或弹窗
除湿机工作环境通常比较潮湿,某些异常状态比其他家电更频繁。例如水箱满水、排水管堵塞、蒸发器需要化霜、湿度传感器失效、压缩机启动保护等。屏幕显示这些状态时,不能只在某个角落显示一个小图标,最好同时显示用户可执行动作。
例如水箱满时,界面可以先弹出全屏或半屏提示:
水箱已满 请清空水箱后放回这样可以避免用户只在面板上看到一个不认识的水滴图标。故障码显示也要和用户文案组合起来,例如底层显示“E1”,旁边再显示“湿度传感器异常”,方便售后和用户判断。
4.4 数据变化要做去抖和上下限处理
湿度传感器在风机启动、压缩机启停瞬间会出现短暂跳变。如果直接把原始值送往屏幕,用户会看到湿度数值在小范围内频繁闪跳。软件上需要做两层处理:
- 连续采样或者滑动平均。
- 显示值和上次刷新值之间的差值小于阈值时不更新。
简单实现示例:
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; } }这里阈值要结合实际产品体验调整。阈值过大,用户会抱怨湿度数值不更新;阈值过小,显示会一直跳动。通常先用 1% 到 2% 的相对湿度作为起步值,再根据整机风道和传感器位置修正。
5. 点屏成功不等于整机正常:运行验证和问题排查
5.1 从黑屏到显示数据的验证顺序
拿到新模组后,不要直接写完整 UI,先按最小步骤验证硬件和驱动:
- 确认 3.3V 电源稳定,背光是否点亮。
- 用逻辑分析仪或示波器检查 RESET、CS、DC、SCL 信号是否出现。
- 先用
lcd_fill_rect填充纯色,确认 RGB 顺序正确。 - 再显示横线和竖线,确认坐标方向和扫描方向。
- 最后显示数字和中文,确认字库和字符绘制函数正确。
- 接入真实传感器,观察数值连续变化是否平滑。
每一步都有明确结果,遇到问题就能缩小范围。
5.2 白屏、花屏、闪烁等常见异常分析
实际项目中最常见的显示问题可以归纳为下面几类:
| 问题现象 | 可能原因 | 检查方式 | 处理建议 |
|---|---|---|---|
| 背光亮但无内容,白屏或黑屏 | LCD 驱动 IC 未初始化成功 | 检查复位时序、初始化数组、SPI 数据 | 确认驱动 IC 型号,按规格书初始化 |
| 花屏或颜色错乱 | RGB 顺序配置错误,或扫描方向不对 | 填充纯色,对比红绿蓝输出 | 修改像素格式和 MADCTL 参数 |
| 横向竖线、条纹或水波纹 | SPI 速率过高或电源纹波大 | 降低 SPI 时钟,用示波器看波形 | 分频降低时钟,加滤波电容 |
| 画面上下左右颠倒 | 写入扫描方向参数不对 | 检查屏幕安装方向 | 修改内存访问控制寄存器 |
| 显示内容残缺 | 地址窗口或帧缓存越界 | 检查坐标最大值和像素循环长度 | 限制窗口不超过 319×239 |
| 数值闪跳 | 传感器值未滤波,或刷新频率过高 | 打印原始值和滤波值 | 加入滑动滤波和变化阈值 |
如果屏幕之前点亮过,代码改动后突然花屏,优先检查是否改动了初始化寄存器、坐标窗口或者 SPI 时钟配置,不需要马上怀疑硬件损坏。
5.3 除湿机环境里要额外关注电源和干扰
除湿机内部有压缩机、风机、继电器和水满传感器,这些都是常见的干扰源。彩屏显示模组对电源噪声相对敏感,尤其是 SPI 通信发生在压缩机启动或继电器吸合瞬间时,可能造成画面数据错乱。
生产项目中需要注意以下几点:
- 显示模组电源和功率负载电源尽量分开走线,避免继电器动作时拉低 3.3V。
- 信号线使用短走线或双绞线,SPI 时钟频率不要盲目调到最高。
- MCU 和屏幕之间加 100nF 去耦电容,电源入口根据电流选择合适容量的电解电容。
- 软件刷新尽量避开继电器动作时间,或者把大区域刷新放到继电器动作完成后的稳定时间窗口。
5.4 排错时应从现象倒推原因
遇到显示异常时,不要先改代码。先确认输入和前提条件是否正确:模组供电电压是否符合要求、初始化是否成功、SPI 是否实际发出数据、坐标是否在 320×240 范围内、驱动芯片和初始化数组是否匹配。排查顺序一般是:
- 先查硬件连接和电源。
- 再查 SPI 波形和时序。
- 然后确认初始化命令是否执行完。
- 接着用纯色填充代替完整 UI,定位是绘图问题还是 UI 逻辑问题。
- 最后检查数据源是否有异常值。
只有按这个顺序排查,才能避免在错误方向反复调参。
6. 从样品到量产:资源规划与工程维护建议
6.1 显示代码按分层方式组织,不要全部堆在 main.c
当项目进入量产阶段,显示逻辑通常不再只有一两个函数。建议按功能拆文件:
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只负责屏幕初始化和点线面、字符输出等基础接口。gui层负责具体页面排版。app层采集湿度、温度、按键和水箱状态,并把数据交给显示页面。这样后续更换屏幕型号时,只需要替换bsp_lcd层。
6.2 图片和字库资源要评估 Flash 占用
320×240 全屏背景图如果直接按 RGB565 转成 C 数组,大小会很大。例如一张全屏背景位图占 150KB,放几张页面就能把 MCU Flash 耗尽。实际项目中,背景尽量使用程序绘制渐变、色块和矩形框,而不是从美工导出整幅图片。真正无法用代码绘制的图片,再用 RLE 压缩或转换成适合 MCU 的格式。
| 资源 | 大小估算 | 建议 |
|---|---|---|
| 全屏 RGB565 背景图 | 320×240×2 = 150KB | 尽量程序绘制,不直接存全屏图 |
| 常用 16×16 中文字库 | 每个字约 32 字节,几千字约 64KB | 按产品需求裁剪字符 |
| ASCII 字库 | 很小 | 可直接使用全 ASCII |
| 图标按钮 | 取决于数量 | 使用透明通道或按 UI 风格统一 |
如果使用 LVGL,字库还要考虑抗锯齿和缓存占用。不要在最终产品里保留所有测试字体和测试图片,发布前需要做一次资源裁剪。
6.3 键盘操作和界面状态要做状态机
除湿机通常按键较少,显示界面却可能有设置目标湿度、模式选择、定时设置和故障弹窗。直接用多个全局标志位控制界面,页面一多就会失控。推荐用页面状态机:
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); }每个页面定义进入和退出处理,页面之间切换时先清理旧页面,再绘制新页面。这样可以防止上一页的内容残留到下一页。
6.4 量产前需要做的显示相关测试清单
- 24 小时长时间运行,观察是否出现随机花屏。
- 温度从低温到高温变化环境下的显示刷新是否异常。
- 继电器反复启停时,画面是否出现干扰条纹。
- 快按按键和慢按按键时,页面切换是否正常。
- 断电再上电,屏幕是否能恢复显示,是否会短暂白屏。
- 水箱满、传感器断开、压缩机保护等故障场景显示是否准确。
- 不同温湿度传感器样本下,数值偏差是否在可接受范围。
- SPI 时钟在不同速率、不同批次板卡上的裕量是否足够。
彩屏显示方案在除湿机上的难点往往不在“点亮屏幕”,而在于控制逻辑、显示资源和整机可靠性之间的平衡。LT165A 2.8 寸 320×240 屏是否能稳定落地,关键看驱动 IC 是否匹配、界面刷新策略是否合理、显示代码是否和功率控制部分做好隔离。先把底层驱动和页面框架做扎实,再根据真实传感器数据调整刷新逻辑,方案才能真正进入量产。