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

我从stm32一路学到esp32,发现这款芯片挺好玩的,主要是还是stm32太贵了,stm32主要是很多坑有人遇到了,并给出了解决方法,esp32这方面就少点,有时候找不到的,只能靠自己了。

本文使用vscode加esp32 idf环境,主要是解决esp32 idf使用esp32自带的falsh,存字库,显示中文,之前使用文件系统来显示,使用上比较卡顿,我这里使用esp32自带的函数显示,解决卡顿问题。我这里是使用的我也是借鉴许多大佬的经验。本文主要目的也是一则分享经验,给大家一个思路,二则是记录一下。

第一步是制作字体,字体制作使用“lvlgFontTool V0.4”这软件,大家网上自行下载即可,先选择字体,字体可以自行去网上下载字体即可,我这里使用的是阿里巴巴的字体,字体高度,可以根据自己要求改,然后确定就行。

第二步根据自己flash的大小,看情况选择常用汉字还是全部汉字,然后选择版本6.0版本以上,类型选择XBF字体,外部bin文件,然后开始转换,选择好路径保存即可。打开保存的文件夹,可以看到一个c文件和一个bin文件,之后我们需要用到。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
第三步:制作分区表,因为我们需要把字库存到esp32自带的falsh里面,我们需要制作分区表,打开自己工程的目录下有个partitions.csv文件,没有自己建一个,然后根据下面图的内容进行填写即可。我这里不讲原理,有兴趣的可以去查esp32分区表。只要关注最后一行是我们的存字库的地方,其中最后一列是填写这个分区多大,我这里bin文件1.5m多,我直接填了2M,大家可以根据自己的生成的字库大小填写。
在这里插入图片描述
注意自己的esp32自带的falsh多大,我的是4m的,esp32默认设置是2m,大家可以esp32在vscode,点击那个小齿轮,然后找到flash size的选择,改成自己实际的大小,然后再找到那个csv选择,改成下图所示,然后编译一下上传,然后看看重启后看看串口打印消息的,其中lenth是不是自己设置的,我这里是00200000。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
然后现在我们需要将我们制作的bin文件烧写到esp32中,我们打开刚才的文件夹,然后我们这边需要使用到一个下载工具“esptool.py”,这个文件可以自行到你们的esp32的安装目录里面搜索,把他复制到现在的文件夹即可。
然后打开命令提示符,我们首先需要看看自己的python是否正常运行,输入python,看他会不会打印版本消息,如果是提示报错的话,自行百度安装pyhon即可,然后我们输入cd加bin文件的目录,然后转到该目录下然后输入以下代码。
其中[port] 是当前esp32连接的串口,根据自己的实际填写,[baud]是波特率,一般是115200,0x1b9000是先前分区表第四行第四列的值,代表该文件存放的起始位,myFont.bin是我们生成的bin文件名,然后回车,然后等待进度走完,如果没报错,我们就成功的一大半了。

python esptool.py --chip esp32 --port [port] --baud [baud] write_flash -z 0x1b9000 myFont.bin

在这里插入图片描述
第四步,我们应该是把那个c文件拷贝到自己工程的components\lvgl\src\font目录下,因为我一直没明白CMakeLists,所以我这边一直出现找不到“"esp_partition.h"这个头文件,如果有知道的大神可以在评论区回复下哈
我这边因为这个原因,我就放在我自己工程下的components\uart0\src目录下,这是我自己创建的组件,然后记得在CMakeLists.txt文件中添加PRIV_REQUIRES lvgl和REQUIRES spi_flash,不然找不到头文件,然后把那个myFont.c里面的,添加#include “esp_partition.h”,然后改写static uint8_t *__user_font_getdata(int offset, int size)这个函数,具体看下面的内容

//CMakeLists.txt文件,这个文件根据实际需要的组件填写,我这里引入了许多的组件,
//来支撑其他文件,我的工程和你的可能不一样,不要全部复制,你需要是添加添加PRIV_REQUIRES lvgl和REQUIRES spi_flash
set(uart0_srcs "src/myFont.c"
               )
idf_component_register(SRCS "${uart0_srcs}"
                       INCLUDE_DIRS "include"
                       PRIV_REQUIRES nvs_flash
                       PRIV_REQUIRES lvgl
                       PRIV_REQUIRES lvgl_esp32_drivers
                       REQUIRES esp_http_client
                       REQUIRES json
                       REQUIRES mqtt 
                       REQUIRES fatfs
                       REQUIRES spiffs
                       REQUIRES spi_flash
                       )
/*
*---------------------------------------------------------------
*                        Lvgl Font Tool                         
*                                                               
* 注:使用unicode编码                                              
* 注:本字体文件由Lvgl Font Tool V0.4 生成                          
* 作者:阿里(qq:617622104)                                         
*---------------------------------------------------------------
*/
//这是myFont.c文件

#include "lvgl.h"
#include "esp_partition.h"

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 = 0x9fa5,
    .bpp = 2,
};


static uint8_t __g_font_buf[300];//如bin文件存在SPI FLASH可使用此buff

esp_partition_t* partition_res=NULL;
static uint8_t *__user_font_getdata(int offset, int size)
{
    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)
        {
            printf("Failed to open file for reading\n");
            return;
        }
        else
        {
             printf("Successfully open file for reading\n");
        }
    }
    esp_err_t res=esp_partition_read(partition_res,offset,__g_font_buf,size);//读取数据
    if(res!=ESP_OK)
    {
        printf("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;
}


//Alibaba PuHuiTi,,-1
//字模高度:22
//XBF字体,外部bin文件
lv_font_t myFont = {
    .get_glyph_bitmap = __user_font_get_bitmap,
    .get_glyph_dsc = __user_font_get_glyph_dsc,
    .line_height = 22,
    .base_line = 0,
};

第五步,然后我们可以测试一下,首先引入字库,然后测试一下

LV_FONT_DECLARE(myFont);//引入字库
static lv_label_t* other_btn_label;//创建对象
other_btn_label = lv_label_create(lv_scr_act());//获取默认屏幕
lv_obj_set_style_text_font(other_btn_label,&myFont,0);// 设置风格的字体
lv_label_set_text(other_btn_label,"你好世界");//显示文字

在这里插入图片描述

至此,完成中文显示。我也是刚玩esp32没多久,这是我第一次发文,所以内容上有错误大家可以提出,出现问题也可以在评论区提出了,我看能不能解决,可能有些问题我也无法回答,请大家善用搜索,我也是借鉴了许多大神的经验而来的。如果文章觉得可以的,可以点个赞呦!

  • 12
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值