ESP32基础应用之lvgl显示中文

news2024/9/28 23:30:06

文章目录

  • 1 工程简介
  • 2 工程实现
    • 2.1 制作字库
    • 2.2 为字库自作分区表
    • 2.3 将字库移植到lvgl工程中
    • 2.4 将字库myFont.bin烧录到分区表中
    • 2.5 编写程序测试
  • 3 存在问题

1 工程简介

该工程在《ESP32基础应用之LVGL基础》之上实现中文的显示。
参考文章

  1. 《ESP32 IDF LVGL8.0 flash 外部字库显示 中文显示》

2 工程实现

2.1 制作字库

使用软件LvglFontToolV0.4自作二进制字库文件。

  1. 在电脑(C:\Windows\Fonts)找到合适的字体,并复制到桌面
    在这里插入图片描述
  2. 打开 LvglFontToolV0.4 软件
    在这里插入图片描述在这里插入图片描述在这里插入图片描述
  3. 最后获得两个文件,并查看myFont.bin大小,好后续为字库分配分区表大小。
    在这里插入图片描述

2.2 为字库自作分区表

分区表知识可参考乐鑫官网《API 指南 — 分区表》

  1. 在官方例程中复制一份自定义分区表到lvgl工程中
    在这里插入图片描述在这里插入图片描述
    修改分区表中的内容后如下

    # Name,   Type, SubType, Offset,  Size, Flags
    # Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
    nvs,        data, nvs,      0x9000,  0x6000,
    phy_init,   data, phy,      0xf000,  0x1000,
    factory,    app,  factory,  0x10000, 1M,
    font,    data, 0x40,             , 2M,  //type选择data;SubType自定义(大于0x3F);Size根据字库大小合理定义
    
  2. 在ESP32配置菜单中选择自定义分区表

    在这里插入图片描述

2.3 将字库移植到lvgl工程中

  1. 将字库myFont.bin放置到lvgl工程目录下

    在这里插入图片描述
    2. 将 myFont.c 放到合适的位置(注意需要将myFont.c添加到CMakeLists.txt)
    s://img-blog.csdnimg.cn/c9ebfe3f1ea74f2ca3415a605b7e0e53.png)

2.4 将字库myFont.bin烧录到分区表中

  1. 命令esptool.py --chip esp32 --port COM4 --baud 115200 write_flash -z 0x110000 myFont.bin
    在这里插入图片描述注意:烧录位置0x110000 可以通过自定义分区表计算,也可以在串口打印数据中查看
    在这里插入图片描述

2.5 编写程序测试

  1. 修改myFont.c以适配工程,

    /*
    *---------------------------------------------------------------
    *                        Lvgl Font Tool                         
    *                                                               
    * 注:使用unicode编码                                              
    * 注:本字体文件由Lvgl Font Tool V0.4 生成                          
    * 作者:阿里(qq:617622104)                                         
    *---------------------------------------------------------------
    */
    #include "main.h"
    #include "esp_partition.h"
    #include "lvgl/lvgl.h"![在这里插入图片描述](https://img-blog.csdnimg.cn/9882e48826b24e988d12e61d7ad04e21.png)
    
    #include "lvgl_helpers.h"
    
    #define TAG "myFont.c"
    
    typedef struct{
        uint16_t min;
        uint16_t max;
        uint8_t  bpp;
        uint8_t  reserved[3];
    }x_header_t;
    typedef struct{
        uint32_t pos;
    }x_table_t;
    typedef struct{
        uint8_t adv_w;
        uint8_t box_w;
        uint8_t box_h;
        int8_t  ofs_x;
        int8_t  ofs_y;
        uint8_t r;
    }glyph_dsc_t;
    
    
    static x_header_t __g_xbf_hd = {
        .min = 0x0020,
        .max = 0x9fa0,
        .bpp = 2,
    };![在这里插入图片描述](https://img-blog.csdnimg.cn/83af052dcf9a43bf942052986a0a4715.png)
    
    static uint8_t __g_font_buf[144];//如bin文件存在SPI FLASH可使用此buff
    
    esp_partition_t* partition_res=NULL;
    
    static uint8_t *__user_font_getdata(int offset, int size){
        //如字模保存在SPI FLASH, SPIFLASH_Read(__g_font_buf,offset,size);
        //如字模已加载到SDRAM,直接返回偏移地址即可如:return (uint8_t*)(sdram_fontddr+offset);
        static uint8_t first_in = 1;  
        if(first_in==1)
        {      
            partition_res=esp_partition_find_first(0x01,0x40,NULL);//这个函数第一个参数是我们分区表的第四行的,第二列的参数,第二个是第三列的值
            first_in=0;
            if (partition_res == NULL)
            {
                ESP_LOGI(TAG,"Failed to open file for reading\n");
                return NULL;
            }else{
                 ESP_LOGI(TAG,"Successfully open file for reading\n");
            }
        }
        esp_err_t res=esp_partition_read(partition_res,offset,__g_font_buf,size);//读取数据
        if(res!=ESP_OK)
        {
            ESP_LOGI(TAG,"Failed to reading\n");
        }    
        return __g_font_buf;
    }
    static const uint8_t * __user_font_get_bitmap(const lv_font_t * font, uint32_t unicode_letter) {
        if( unicode_letter>__g_xbf_hd.max || unicode_letter<__g_xbf_hd.min ) {
            return NULL;
        }
        uint32_t unicode_offset = sizeof(x_header_t)+(unicode_letter-__g_xbf_hd.min)*4;
        uint32_t *p_pos = (uint32_t *)__user_font_getdata(unicode_offset, 4);
        if( p_pos[0] != 0 ) {
            uint32_t pos = p_pos[0];
            glyph_dsc_t * gdsc = (glyph_dsc_t*)__user_font_getdata(pos, sizeof(glyph_dsc_t));
            return __user_font_getdata(pos+sizeof(glyph_dsc_t), gdsc->box_w*gdsc->box_h*__g_xbf_hd.bpp/8);
        }
        return NULL;
    }
    static bool __user_font_get_glyph_dsc(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter, uint32_t unicode_letter_next) {
        if( unicode_letter>__g_xbf_hd.max || unicode_letter<__g_xbf_hd.min ) {
            return NULL;
        }
        uint32_t unicode_offset = sizeof(x_header_t)+(unicode_letter-__g_xbf_hd.min)*4;
        uint32_t *p_pos = (uint32_t *)__user_font_getdata(unicode_offset, 4);
        if( p_pos[0] != 0 ) {
            glyph_dsc_t * gdsc = (glyph_dsc_t*)__user_font_getdata(p_pos[0], sizeof(glyph_dsc_t));
            dsc_out->adv_w = gdsc->adv_w;
            dsc_out->box_h = gdsc->box_h;
            dsc_out->box_w = gdsc->box_w;
            dsc_out->ofs_x = gdsc->ofs_x;
            dsc_out->ofs_y = gdsc->ofs_y;
            dsc_out->bpp   = __g_xbf_hd.bpp;
            return true;
        }
        return false;
    }
    //FangSong_GB2312,,-1
    //字模高度:18
    //XBF字体,外部bin文件
    lv_font_t myFont = {
        .get_glyph_bitmap = __user_font_get_bitmap,
        .get_glyph_dsc = __user_font_get_glyph_dsc,
        .line_height = 18,
        .base_line = 0,
    };
    
  2. 在屏幕中显示中文

    #include "lvgl/lvgl.h"
    #include "lvgl_helpers.h"
    #include "esp_partition.h"
    LV_FONT_DECLARE(myFont);//引入字库
    static lv_obj_t * tv;
    static lv_style_t style_title;
    
    void fun(void)
    {
        tv = lv_tabview_create(lv_scr_act(), NULL);   //以屏幕为父控件创建选项卡
        lv_obj_t * label = lv_label_create(tv, NULL);
        lv_style_init(&style_title);
        lv_style_set_text_font(&style_title, LV_STATE_DEFAULT, &myFont);
        lv_obj_add_style(label, LV_LABEL_PART_MAIN, &style_title);
        lv_obj_set_pos(label, 100,100);
        lv_label_set_text(label ,"你好世界2022-12-17");
    }
    

    在这里插入图片描述

    3 存在问题

    1. 文件之间的依赖行,即找不到所需的文件,这里要研究CMakeLists.txt文件
    2. 显示中文会很慢。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/96819.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CSC7720

CSC7720是一款用于5V2.1A开关电源的高效率同步整流控制IC。其具备较高的集成度&#xff0c;在有效的提升开关电源的转换效率的同时&#xff0c;减少了外围元器件的应用。CSC7720可用于DCM/QR开关电源系统。CSC7720内置45V的功率管&#xff0c;在系统中替代次级肖特基管,并提高整…

启动单文件组件项目及项目文件解释

启动项目文件&#xff1a;“package.json”&#xff1a; “package.json”&#xff1a;这个文件能记录当前项目中安装的所有模块&#xff0c;里面也有脚本&#xff0c;这个脚本可以快速启动我们的项目。 打开文件&#xff0c;可以看到“serve”&#xff0c;serve就是启动文件…

李沐精读论文:transformer 《Attention Is All You Need》 by Google

论文&#xff1a;Attention Is All You Need 视频&#xff1a;Transformer论文逐段精读【论文精读】_哔哩哔哩_bilibili 课程&#xff08;推荐先看这个&#xff09;&#xff1a;李宏毅机器学习&#xff1a;self-attention&#xff08;自注意力机制&#xff09;和transformer及其…

SpringBoot整合Shiro环境搭建

SpringBoot整合Shiro环境搭建导入 SpringBoot 和 Shiro 整合包的依赖&#xff1a; <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-spring --> <dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring<…

XXL-Job分布式任务调度框架-- 定时任务注册案例2

一 案例操作 1.1 新建工程 简单建一个springboot的工程&#xff0c;如下图结构 1.2 工程的配置 1.pom中依赖配置 2&#xff09;代码 <!-- xxl-job --><dependency><groupId>com.xuxueli</groupId><artifactId>xxl-job-core</artifactI…

ANTLR4入门(一):Windows安装antlr4命令行环境

最近开始学习ANTLR4&#xff0c;《ANTLR 4权威指南》这本书是看完了&#xff0c;现在开始实践&#xff0c;本系列文记录实践过程中的遇到的问题解决过程及心得体会 下载 从antlr官方网站下载最新的antr4版本(jar)&#xff1a;https://www.antlr.org/download.html 目前最新的…

牛客java刷题知识点总结(七)

instanceof运算符作用 instance是java的二元运算符&#xff0c;用来判断他左边的对象是否为右面类&#xff08;接口&#xff0c;抽象类&#xff0c;父类&#xff09;的实例。 我们考虑的时候&#xff0c;左边的对象如果是父类的引用指向子类的对象&#xff0c;我们用子类对象的…

C++【并查集】

文章目录一、并查集是什么并查集的简单表示并查集的合并并查集的代码实现并查集小练习1并查集小练习2并查集的压缩问题一、并查集是什么 并查集是一个森林 在一些应用问题中&#xff0c;需要将n个不同的元素划分成一些不相交的集合。开始时&#xff0c;每个元素自成一个单元素…

CS61A Lab 4

更好的阅读体验 Lab 4: Recursion, Tree Recursion lab04.zip What Would Python Do? Q1: Squared Virahanka Fibonacci Use Ok to test your knowledge with the following “What Would Python Display?” questions: python3 ok -q squared-virfib-wwpd -u✂️Hint: If…

CountDownLatch类的使用

&#x1f388;专栏链接:多线程相关知识详解 目录 一.CountDownLatch的介绍 二.CountDownLatch类里面的方法 三.CountDownLatch的两种应用场景 ①一等多情况 ②多等一情况 一.CountDownLatch的介绍 CountDownLatch是一种用来控制多线程的工具类,它被称为门阀、计数器或者…

LeetCode HOT 100 —— 301.删除无效的括号

题目 给你一个由若干括号和字母组成的字符串 s &#xff0c;删除最小数量的无效括号&#xff0c;使得输入的字符串有效。 返回所有可能的结果。答案可以按 任意顺序 返回。 思路 DFS 回溯算法&#xff1a; 首先最终合法的方案&#xff0c;必然有左括号的数量 右括号的数量 …

钉钉获取免登用户信息

大家好&#xff0c;这里是一口八宝周&#x1f44f; 欢迎来到我的博客❤️一起交流学习 文章中有需要改进的地方请大佬们多多指点 谢谢&#x1f64f; 最近好像搞了个什么钉钉小程序&#xff0c;具体做什么咱也不知道&#xff0c;就让我搞一个钉钉获取免登录用户信息的接口出来&…

计网理论模拟

一. 单选题&#xff08;共10 题&#xff0c;20.0分&#xff09; 1. (单选题,2.0分)网络协议主要由 3 个基本要素组成&#xff0c;即&#xff08; &#xff09; A. 层次、语义和同步B. 语法、原语和同步C. 语法、语义和同步D. 语法、语义和功能 正确答案: C 2. (单选题,2.0分…

计算机毕业设计ssm+vue基本微信小程序的智能图书管理系统

项目介绍 本设计旨在研究一种社区图书管理系统设计与实现系统,以各种浏览器web页面加上云服务器后端服务系统,通过这一设计过程,进一步熟悉web前端开发技术和云服务器后端开发技术和方法,培养理论联系实际及知识的综合运用能力。 图书管理系统可以有效实现图书管理的规范化、系…

SAP Gateway 后台模型的缓存设置

/iwbep/cl_mgw_med_provider 类里的成员 mv_cache_active: 这个 cache 默认是开启状态。 调用 OData 服务的 MPC_EXT 类的 get_last_modified 方法获取最后一次修改的时间戳。这个时间戳(timestamp)也会影响到 cache 的行为&#xff0c;我们后续也会详细讨论。 第12 行 super 方…

PySpark--spark local 的环境部署

Spark环境搭建-Local 环境搭建 基本原理 本质&#xff1a;启动一个JVM Process进程(一个进程里面有多个线程)&#xff0c;执行任务Task Local模式可以限制模拟Spark集群环境的线程数量, 即Local[N] 或 Local[*]其中N代表可以使用N个线程&#xff0c;每个线程拥有一个cpu core。…

【使用Netty实现群发消息】

使用Netty实现群发消息netty简单介绍实现群发流程图代码实现NettyServer 类MyChannelInitializer 类MyServerHandler 类ChannelHandler 类Netty 依赖效果展示netAssist 工具启动Netty server打开netAssist 工具netty简单介绍 Netty是由JBOSS提供的一个java开源框架&#xff0c…

第三十一章 linux-模块的加载过程

第三十一章 linux-模块的加载过程 文章目录第三十一章 linux-模块的加载过程sys_init_modulestruct moduleload_module在用户空间&#xff0c;用insmod这样的命令来向内核空间安装一个内核模块&#xff0c;本节将详细讨论模块加载时的内核行为。当调用“insmod demodev.ko”来安…

通讯录的思路与实现(C语言)

目录 前言 程序的分装 程序的结构 函数实现 通讯录的初始化 通讯录的扩容 将数据保存到本地 增加联系人 显示通讯录所有联系人 目标联系人的检索(根据名称) 目标联系人的检索(根据号码) 检索发展来的函数 删除联系人 查询目标联系人 联系人信息的更改 按名称对通…

Python写个“点球大战”小游戏

大家好&#xff0c;欢迎来到 Crossin的编程教室 &#xff01; 看过我Python入门教程的朋友应该会看到其中有提到一个点球小游戏的作业。 在世界杯决赛即将到来之际&#xff0c;我们再来回顾一下这个小游戏。对于刚刚学习编程不久的同学&#xff0c;这是个不错的练手习题&…