ESP32-S3 驱动 ILI9488 显示屏(基于LVGL 9.2.2的ESP32-S3 ILI9488显示屏中文显示实现)

一、背景分析

 1、说明:        

当前Esp32s3驱动ILI9488显示中文汉字方案研究了两种,一种TTF转C数组方案,另一种是TTF动态加载方案,这俩种方案各有利弊。

2、开发环境

        1. ubuntu下ESP-IDF开发环境(ubuntu仅编译调试,在source insight中编写代码)

        2. LVGL版本9.2.2

        3.ESP32芯片型号ESP32S3 N16R8(flash 16M PSRAM 8M)

二、TTF转C数组方案(高效但固定)

2.1、实现原理

提前转化:使用工具将TTF文件转化成LVGL专用的.c字体文件。

特性限制:固定字号,且仅包含指定Unicode范围内的字符。

2.2、实现步骤

2.2.1 下载TTF字符库文件

         TTF字符库可以百度搜索下载,也可以找电脑上的字符库,我用的是电脑上的TTF字符库。

1. 打开本电脑C:\Windows\Fonts,可以看到很多字体,选择一款自己喜欢的字体

 2.复制字体到一个新的文件夹,作为转化文件夹,我选用的是黑体常规字体

2.2.2 使用转化工具转化C数组

打开LVGL官方文字转换网址Font Converter — LVGL,配置如下

name: 输出文件名(自定义文件名,比如simhei.ttf转化后我定义为my_font_simhei_24_4bpp.c)。

size:字体大小(如常用的小字号16,中字号24,大字号32)。

Bpp:字体质量 (我一般用4bpp)。

Browse: 选择我们前面下载的TTF字体库(如:simhei.ttf)。

Range: 中文字符的Unicode编码范围,填写0x0000-0xFFFF,基本包含了常用汉字以及中文标点符号。

Symbols: 可以不填

Submit:点击后等待生my_font_simhei_24_4bpp.c文件,下载到文件夹中(网页翻译大概8s,耐心等待)

2.2.3 修改生成的C文件

 修改代码第10行为      "../../lvgl.h"    (未修改前为:"lvgl/lvgl"),修改后的文件拷贝到LVGL9组件库下(lvgl-9.2.2/src/font/)。

2.2.4 修改后的C文件拷贝到LVGL9组件库的src/font/路径下

2.2.5 修改lvgl-9.2.2\scripts\built_in_font\generate_all.py文件

print("\nGenerating 16 px my_font_simhei_CJK")
os.system(u"./built_in_font_gen.py --size 16 -o my_font_simhei_16_4bpp.c --bpp 4")

print("\nGenerating 24 px my_CJK")
os.system(u"./built_in_font_gen.py --size 24 -o my_font_simhei_24_4bpp.c --bpp 4")

2.2.6 修改lvgl-9.2.2\src\font\lv_font.h文件

新增如下两行

LV_FONT_DECLARE(my_font_simhei_24_4bpp)
LV_FONT_DECLARE(my_font_simhei_16_4bpp)

2.2.7 修改lvgl-9.2.2\src\lv_conf_kconfig.h文件

新增如下两行代码

#define CONFIG_LV_FONT_DEFAULT &my_font_simhei_16_4bpp
#define CONFIG_LV_FONT_DEFAULT &my_font_simhei_24_4bpp

2.3、使用案例

void send_question_cb(lv_event_t * e) {
    lv_obj_t * textarea = (lv_obj_t *)lv_event_get_user_data(e);
    const char * question = lv_textarea_get_text(textarea);
    
    // 模拟回答(实际可对接ChatGPT或本地逻辑)
    char answer[256];
    snprintf(answer, sizeof(answer), "回答:已收到问题——%s", question);
    
    // 更新回答区域
    lv_textarea_set_text(lv_obj_get_child(lv_obj_get_parent(textarea), 1), answer);
    lv_textarea_set_text(textarea, ""); // 清空输入框
}

void create_chat_ui() {
    // 创建父容器(全屏)
    lv_obj_t * parent = lv_obj_create(lv_scr_act());
    lv_obj_set_size(parent, LV_PCT(100), LV_PCT(100));
    lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN);
    lv_obj_set_style_text_font(parent, &my_font_simhei_24_4bpp, 0);

    // 1. 问题区域
    lv_obj_t * label_question = lv_label_create(parent);
    lv_label_set_text(label_question, "问题:如何点亮LED?");
    lv_obj_set_width(label_question, LV_PCT(100));

    // 2. 回答区域(可滚动)
    lv_obj_t * textarea_answer = lv_textarea_create(parent);
    lv_textarea_set_text(textarea_answer, "回答:使用gpio_set_level(LED_PIN, 1);");
    lv_obj_set_width(textarea_answer, LV_PCT(100));
    lv_obj_set_flex_grow(textarea_answer, 1); // 占据剩余空间
    lv_textarea_set_placeholder_text(textarea_answer, "等待回答...");

    // 3. 底部输入框和按钮
    lv_obj_t * panel_footer = lv_obj_create(parent);
    lv_obj_set_width(panel_footer, LV_PCT(100));
    lv_obj_set_flex_flow(panel_footer, LV_FLEX_FLOW_ROW);

    lv_obj_t * textarea_input = lv_textarea_create(panel_footer);
    lv_obj_set_flex_grow(textarea_input, 1);
    lv_textarea_set_placeholder_text(textarea_input, "输入问题...");

    lv_obj_t * btn_send = lv_btn_create(panel_footer);
    lv_obj_t * label_btn = lv_label_create(btn_send);
    lv_label_set_text(label_btn, "发送");
    lv_obj_add_event_cb(btn_send, send_question_cb, LV_EVENT_CLICKED, textarea_input);
}

void setup()
{
    Serial.begin( 115200 );
    
    lv_init();
    lv_display_t * disp;
#if LV_USE_TFT_ESPI
    /*TFT_eSPI can be enabled lv_conf.h to initialize the display in a simple way*/
    disp = lv_tft_espi_create(TFT_HOR_RES, TFT_VER_RES, draw_buf, sizeof(draw_buf));
    lv_display_set_rotation(disp, TFT_ROTATION);//设置图片旋转角度
    //lv_display_set_flush_cb(disp, my_disp_flush);

#else
    /*Else create a display yourself*/
    disp = lv_display_create(TFT_HOR_RES, TFT_VER_RES);
    lv_display_set_flush_cb(disp, my_disp_flush);
    lv_display_set_buffers(disp, draw_buf, NULL, sizeof(draw_buf), LV_DISPLAY_RENDER_MODE_PARTIAL);
#endif

    create_chat_ui();
}

void loop()
{
    lv_timer_handler(); /* let the GUI do its work */
    delay(5); /* let this time pass */
}

2.4、效果展示

三:TTF动态加载方案(灵活但缓慢)

基本流程已经跑通,待整理文档

四、后语

整体流程已经基本调通,效果展示已拍照记录。

测试代码已完整提供。

从无到有实现目前的效果,有参考其他大佬的帖子,也有自己摸索实现的部分,知识劳动成果,实属不易。

如果需要技术支持,欢迎骚扰(+v:Sw-striving)!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值