第二章 开发环境搭建:硬件平台选择与第一个LVGL工程
好,咱们正式开始动手了。这一章我带你走一遍开发环境的搭建流程。说实话,很多初学者卡在这一步就放弃了——工具链装不上、源码编译报错、下载器不识别……我当年也踩过不少坑。今天我把经验都摊开讲,你跟着走就行。
2.1 硬件平台怎么选?STM32还是ESP32?
这个问题我几乎每次线下课都会被问到。我的回答是:看你最终产品要什么。
先看一张对比表,心里有个底:
| 对比项 | STM32(以F4/H7为例) | ESP32(以ESP32-S3为例) |
|---|---|---|
| 主频 | 168~480 MHz | 240 MHz |
| RAM | 192KB~1MB(片内) | 512KB(片内)+ 8MB PSRAM |
| Flash | 1~2MB(片内) | 16MB(外挂) |
| LVGL流畅度 | 中等(需优化显存) | 流畅(PSRAM加持) |
| WiFi/蓝牙 | 需外挂模块 | 内置 |
| 开发成本 | 中等(板子+调试器) | 低(USB下载即可) |
| 适合场景 | 工业控制、医疗设备 | 智能家居、物联网屏显 |
我个人习惯是:学LVGL入门用ESP32。为什么?因为ESP32有PSRAM,你不用担心内存不够用。我刚开始用STM32F103跑LVGL时,一个简单的仪表盘界面就把内存撑爆了,折腾了两天才搞定显存分配。ESP32就没这烦恼,8MB PSRAM随便用。
但如果你做的是工业产品,对稳定性要求极高,那还是STM32更靠谱。ESP32的WiFi射频有时候会干扰屏显刷新,我在一个智能家居项目里遇到过这个问题,后来加了屏蔽罩才解决。
2.2 软件工具链安装
工具链这东西,说白了就是「编译器+调试器+烧录工具」的组合。不同平台用的工具不一样,我分开讲。
2.2.1 ESP32开发环境
我推荐用ESP-IDF,别用Arduino。虽然Arduino上手快,但LVGL在ESP-IDF下性能更好,而且内存管理更灵活。
安装步骤:
- 安装Python 3.8+ —— 记得勾选「Add Python to PATH」
- 安装Git —— 后面拉取LVGL源码要用
- 安装ESP-IDF —— 打开终端,运行:
git clone --recursive https://github.com/espressif/esp-idf.git
cd esp-idf
./install.sh # Windows用 install.bat
. ./export.sh # Windows用 export.bat
嗯,这里要注意:install.sh会下载编译工具链,大概1~2GB,网速慢的话可能要等半小时。我建议你找个有梯子的网络环境,或者用国内镜像。
--recursive 参数,结果子模块没拉全,编译时疯狂报错。后来我学乖了,每次都用 git clone --recursive。
2.2.2 STM32开发环境
STM32这边,我习惯用STM32CubeIDE。它集成了GCC编译器、调试器和CubeMX配置工具,一套搞定。
安装流程:
- 去ST官网下载STM32CubeIDE(需要注册账号)
- 安装时选择「Full Installation」,大概1.5GB
- 安装完成后,打开CubeMX,配置一个工程试试
如果你喜欢用Keil或者IAR,也行。但我个人觉得CubeIDE免费又好用,没必要花几万块买Keil授权。
2.3 LVGL源码获取与移植
LVGL的源码托管在GitHub上。获取方式很简单:
git clone https://github.com/lvgl/lvgl.git
cd lvgl
git checkout v8.3.0 # 建议用稳定版
为什么我推荐v8.3.0?因为v9.0改动太大,很多API都变了,网上教程大多基于v8。等v9稳定了再升级也不迟。
移植LVGL到你的工程,核心就三步:
- 复制源码 —— 把
lvgl文件夹放到你的工程目录下 - 配置lv_conf.h —— 这是LVGL的配置文件,里面可以开关功能、调整内存大小
- 实现三个接口 —— 显示驱动、触摸驱动、系统时钟
我重点说一下 lv_conf.h 的配置。你打开这个文件,找到这几项:
#define LV_COLOR_DEPTH 16 // 颜色深度,16位够用
#define LV_MEM_SIZE (64U * 1024U) // LVGL动态内存,64KB起步
#define LV_HOR_RES_MAX 320 // 屏幕宽度
#define LV_VER_RES_MAX 240 // 屏幕高度
#define LV_USE_DEMO_WIDGETS 1 // 打开示例,方便测试
关键点: LV_MEM_SIZE 不要设太小。我见过有人设成8KB,结果界面稍微复杂一点就卡死。ESP32有PSRAM,可以设到256KB甚至更大。STM32如果片内RAM紧张,设64KB也够用。
2.4 第一个LVGL工程
好了,环境搭好了,源码也放进去了。咱们来跑第一个程序。
以ESP32为例,在 main.c 里写:
#include "lvgl.h"
#include "lv_examples.h"
void app_main(void)
{
// 1. 初始化LVGL
lv_init();
// 2. 初始化显示驱动(这里用你的屏幕驱动函数)
lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.flush_cb = my_disp_flush; // 你的刷屏函数
disp_drv.hor_res = 320;
disp_drv.ver_res = 240;
lv_disp_drv_register(&disp_drv);
// 3. 初始化触摸驱动(如果有触摸屏)
lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = my_touchpad_read; // 你的触摸读取函数
lv_indev_drv_register(&indev_drv);
// 4. 创建一个按钮
lv_obj_t *btn = lv_btn_create(lv_scr_act());
lv_obj_set_pos(btn, 100, 80);
lv_obj_set_size(btn, 120, 50);
lv_obj_t *label = lv_label_create(btn);
lv_label_set_text(label, "Hello LVGL!");
// 5. 主循环
while(1) {
lv_timer_handler(); // 处理LVGL任务
vTaskDelay(5 / portTICK_PERIOD_MS); // 延时5ms
}
}
这段代码干了什么?说白了就是:初始化LVGL → 告诉它你的屏幕怎么刷 → 创建一个按钮 → 循环处理界面事件。
你编译烧录后,屏幕上应该会出现一个带「Hello LVGL!」文字的按钮。如果没显示,别慌,先检查这几个地方:
- 屏幕的SPI/I2C引脚有没有接对?
my_disp_flush函数里有没有调用lv_disp_flush_ready()?lv_timer_handler()有没有在主循环里被调用?
一个小技巧: 如果屏幕没显示,先别急着查硬件。在 my_disp_flush 里直接填充全屏红色,看看屏幕能不能亮。能亮说明硬件没问题,问题出在LVGL配置上。
我记得第一次跑通LVGL时,看到屏幕上那个按钮,心里还挺激动的。虽然只是个简单的按钮,但意味着你的嵌入式设备有了「图形界面」的能力。后面咱们会一步步把它做成完整的仪表盘、智能家居面板……
好,这一章就到这儿。环境搭好了,第一个工程也跑起来了。下一章咱们开始深入LVGL的组件系统,看看那些按钮、标签、滑块到底怎么用。
公众号:蓝海资料掘金营,微信deep3321