嵌入式 GUI 开发指南:LVGL、GuiLite 实战
嵌入式 GUI 开发正在从简单的字符界面走向丰富的图形界面。本文介绍 GitHub 上最流行的嵌入式 GUI 框架,帮助你为 MCU 项目添加漂亮的用户界面。
一、主流嵌入式 GUI 框架
1. LVGL(Light and Versatile Graphics Library)
⭐ 22.8k Stars
最流行
C 语言
嵌入式 GUI 的事实标准,支持 MCU 到 Linux 平台,丰富控件和主题:
// LVGL 初始化示例(STM32 + ILI9341 屏幕)
#include "lvgl.h"
static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf1[LV_HOR_RES_MAX * 10];
static lv_color_t buf2[LV_HOR_RES_MAX * 10];
void lvgl_init(void) {
lv_init();
lv_disp_draw_buf_init(&draw_buf, buf1, buf2, LV_HOR_RES_MAX * 10);
lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.draw_buf = &draw_buf;
disp_drv.flush_cb = my_disp_flush;
disp_drv.hor_res = 320;
disp_drv.ver_res = 240;
lv_disp_drv_register(&disp_drv);
}
// 创建一个简单的 UI
void create_ui(void) {
lv_obj_t *scr = lv_scr_act();
// 标题
lv_obj_t *title = lv_label_create(scr);
lv_label_set_text(title, "IoT Monitor");
lv_obj_set_style_text_font(title, &lv_font_montserrat_24, 0);
lv_obj_align(title, LV_ALIGN_TOP_MID, 0, 10);
// 温度显示
lv_obj_t *temp_label = lv_label_create(scr);
lv_label_set_text(temp_label, "25.5°C");
lv_obj_set_style_text_font(temp_label, &lv_font_montserrat_48, 0);
lv_obj_set_style_text_color(temp_label, lv_color_hex(0x00FF00), 0);
lv_obj_align(temp_label, LV_ALIGN_CENTER, 0, 0);
// 图表
lv_obj_t *chart = lv_chart_create(scr);
lv_obj_set_size(chart, 300, 100);
lv_obj_align(chart, LV_ALIGN_BOTTOM_MID, 0, -10);
lv_chart_set_type(chart, LV_CHART_TYPE_LINE);
lv_chart_set_point_count(chart, 20);
}
2. GuiLite
⭐ 7.7k Stars
超轻量
4KB RAM
github.com/aspect-tech/GuiLite
仅 4KB 代码的超轻量 GUI 库,适合资源受限的 MCU:
// GuiLite 最小示例
#include <guilite.h>
// 按钮回调
void on_button_click(void) {
static bool led_state = false;
led_state = !led_state;
led_control(led_state);
}
// 创建界面
void create_ui() {
// 创建按钮
button_t *btn = new button_t(10, 100, 200, 50, "Toggle LED");
btn->set_on_click_handler(on_button_click);
// 创建标签
label_t *lbl = new label_t(10, 10, "Hello GuiLite!");
lbl->set_font_size(24);
lbl->set_text_color(0x00FF00);
}
3. emWin(SEGGER)
商业
工业级
NXP/ST
工业级 GUI 库,NXP 和 ST 的 MCU 可免费使用:
- 支持抗锯齿字体、动画、窗口管理器
- 丰富的控件库(按钮、列表、图表等)
- 支持触摸屏、鼠标、键盘输入
- 配套 GUIBuilder 可视化设计工具
4. TouchGFX(ST)
免费
STM32 专用
高帧率
ST 官方的 GUI 框架,针对 STM32 + Chrom-ART 加速优化:
- 支持 60fps 流畅动画
- TouchGFX Designer 可视化设计
- 自动生成 C++ 代码
- 免费用于 STM32 芯片
二、GUI 开发硬件选型
| MCU | RAM | 适合框架 | 参考价格 |
| STM32F407 | 192KB | LVGL、TouchGFX | $15 |
| STM32F746 | 320KB | TouchGFX、LVGL | $25 |
| ESP32-S3 | 512KB | LVGL、GuiLite | $12 |
| NXP RT1062 | 1MB | emWin、LVGL | $30 |
三、LVGL 实战项目
智能家居仪表盘
// LVGL 智能家居仪表盘
void create_smart_home_ui(void) {
lv_obj_t *scr = lv_scr_act();
// 顶部状态栏
lv_obj_t *status_bar = lv_obj_create(scr);
lv_obj_set_size(status_bar, LV_PCT(100), 40);
lv_obj_align(status_bar, LV_ALIGN_TOP_MID, 0, 0);
lv_obj_t *wifi_icon = lv_label_create(status_bar);
lv_label_set_text(wifi_icon, LV_SYMBOL_WIFI);
lv_obj_align(wifi_icon, LV_ALIGN_LEFT_MID, 10, 0);
lv_obj_t *time_label = lv_label_create(status_bar);
lv_label_set_text(time_label, "14:30");
lv_obj_align(time_label, LV_ALIGN_RIGHT_MID, -10, 0);
// 温度卡片
lv_obj_t *temp_card = lv_obj_create(scr);
lv_obj_set_size(temp_card, 140, 100);
lv_obj_align(temp_card, LV_ALIGN_TOP_LEFT, 10, 50);
lv_obj_t *temp_icon = lv_label_create(temp_card);
lv_label_set_text(temp_icon, LV_SYMBOL_HEAT);
lv_obj_set_style_text_color(temp_icon, lv_color_hex(0xFF6B6B), 0);
lv_obj_align(temp_icon, LV_ALIGN_TOP_LEFT, 5, 5);
lv_obj_t *temp_value = lv_label_create(temp_card);
lv_label_set_text(temp_value, "25.5°C");
lv_obj_set_style_text_font(temp_value, &lv_font_montserrat_24, 0);
lv_obj_align(temp_value, LV_ALIGN_BOTTOM_LEFT, 5, -5);
// 湿度卡片
lv_obj_t *hum_card = lv_obj_create(scr);
lv_obj_set_size(hum_card, 140, 100);
lv_obj_align(hum_card, LV_ALIGN_TOP_RIGHT, -10, 50);
lv_obj_t *hum_icon = lv_label_create(hum_card);
lv_label_set_text(hum_icon, LV_SYMBOL_DROPLET);
lv_obj_set_style_text_color(hum_icon, lv_color_hex(0x4ECDC4), 0);
lv_obj_align(hum_icon, LV_ALIGN_TOP_LEFT, 5, 5);
lv_obj_t *hum_value = lv_label_create(hum_card);
lv_label_set_text(hum_value, "60%");
lv_obj_set_style_text_font(hum_value, &lv_font_montserrat_24, 0);
lv_obj_align(hum_value, LV_ALIGN_BOTTOM_LEFT, 5, -5);
// LED 控制开关
lv_obj_t *led_switch = lv_switch_create(scr);
lv_obj_align(led_switch, LV_ALIGN_BOTTOM_MID, 0, -50);
lv_obj_add_event_cb(led_switch, led_switch_handler, LV_EVENT_VALUE_CHANGED, NULL);
}
四、GUI 开发最佳实践
- 内存管理:MCU RAM 有限,使用对象池避免频繁 malloc
- 刷新策略:只刷新变化的区域,减少 GPU 负载
- 字体选择:使用内置字体,避免加载外部字体占用 Flash
- 输入处理:触摸屏需要校准和去抖动处理
- 多语言支持:使用 Unicode 字符集支持中英文
嵌入式 GUI 开发的关键是在美观和资源消耗之间找到平衡。