解决LVGL与FATFS编码格式冲突及外挂字库方案

news/2025/11/28 21:58:01/文章来源:https://www.cnblogs.com/lsdm/p/19284253

问题描述

在使用LVGL和FATFS文件系统时,遇到了编码格式不一致的问题:

  • LVGL 默认使用 UTF-8 编码
  • CubeMX生成的FATFS 使用 GBK 编码
  • 从SD卡读取的字符文字为GBK格式,导致在LVGL中显示时出现乱码

stm-loc1.png

参考解决方案:http://www.openedv.com/forum.php?mod=viewthread&tid=348136&highlight=lvgl%2B%D6%D0%CE%C4

编码转换方案

转换逻辑

  • LVGL中文存入SD卡:UTF-8 → GBK
  • LVGL显示SD卡文字:GBK → UTF-8

实现步骤

  1. 下载转换文件
    GBK转UTF-8修改好的文件

  2. 导入工程
    将文件导入Keil工程

  3. 代码示例

#include "gbk2utf8.h"char name[] = "你好你好你好";
char utf8_text[64];
str_gbk2utf8(name, utf8_text);
lv_label_set_text_fmt(guider_ui.screen_text_name, "%s", utf8_text);

LVGL外挂字库方案

准备工作

使用 LvglFontTool 工具生成字库文件

操作步骤

1. 选择字体和大小

stm-loc2.png

2. 添加字符集

  • 点击"加入常用汉字"
  • 添加可能用到的生僻字和中文符号,避免显示为方框
    stm-loc3.png

3. 可选:添加Awesome图标

stm-loc4.png

4. 设置输出参数

  • 设置字体名称和尺寸
  • 类型选择"外部bin文件"
    stm-loc5.png

5. 生成文件

  • 点击"开始转换"

  • 生成两个文件:

    • .bin文件 → 拷贝到SD卡

      stm-loc6.png

    • .c文件 → 加入Keil工程
      stm-loc7.png

代码修改

修改 YaHeiFont12.c 文件:

/*
*---------------------------------------------------------------
*                        Lvgl Font Tool                         
*                                                               
* 注:使用unicode编码                                              
* 注:本字体文件由Lvgl Font Tool V0.4 生成                          
* 作者:阿里(qq:617622104)                                         
*---------------------------------------------------------------
*/#include "lvgl.h"
#include "fatfs.h"
#include "ff.h"
#include <stdio.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 = 0xf244,.bpp = 1,
};static uint8_t __g_font_buf[63];  // 字体读取缓冲区static uint8_t *__user_font_getdata(int offset, int size){uint32_t br;// 注意修改SD卡中字库文件路径if( f_open(&SDFile, (const TCHAR*)"0:/Font/YaHeiFont12.bin", FA_READ) != FR_OK ) {printf("font.bin open failed\r\n");} else {if( f_lseek(&SDFile, (FSIZE_t)offset) != FR_OK ) {printf("font lseek failed\r\n");}if( f_read(&SDFile, __g_font_buf, (UINT)size, (UINT*)&br) != FR_OK ) {printf("font read failed\r\n");}f_close(&SDFile);}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;
}// YaHei Consolas Hybrid,YaHei Consolas Hybrid Regular,12
// 字模高度:21
// XBF字体,外部bin文件
const lv_font_t YaHeiFont12 = {.get_glyph_bitmap = __user_font_get_bitmap,.get_glyph_dsc = __user_font_get_glyph_dsc,.line_height = 21,.base_line = 0,
};

配置LVGL

1. 在 lv_conf.h 中添加自定义字体

stm-loc8.png

2. 设置标签控件的字体

stm-loc9.png

最终效果

成功实现外挂字库显示中文:
stm-loc10.png

通过以上方案,完美解决了LVGL与FATFS编码格式冲突问题,并实现了灵活的外挂字库功能。

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

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

相关文章

我是如何用浏览器插件轻松抓取抖音评论并实现精准搜索分析的

vx:llike620 gofly.v1kf.com 之前我成功用浏览器插件获取了抖音粉丝数据,这个经验让我意识到,同样的技术原理完全可以应用到抖音评论抓取上。现在,我已经实现了这个想法,让我来分享这个实用的数据获取方法。 我是…

重练算法(代码随想录版) day24 - 回溯part3

今日刷题量:3 当前刷题总量:104 Easy: 53 Mid: 49 Hard: 2 Day24 常用思想 1.一定要学会剪枝,判断怎么去剪枝可以优化递归分支 2.组合问题和分割问题都是收集树的叶子节点,而子集问题是找树的所有节点 3.去重问题一…

详解np.random.normal(0, 3, size=x.shape)

一、完整语法与参数解释 np.random.normal(loc=0, scale=1, size=None) 是 NumPy 中生成「正态分布(高斯分布)」随机数的核心函数,参数含义如下:参数名 默认值 作用说明 对应代码中的含义loc 0 正态分布的「均值(…

代码随想录Day23_回溯_组合.md

代码随想录Day23_回溯_组合.md回溯练习:再有重复元素和无重复元素的数组中分别找到和为target的子集,以及给出指定字符串的回文子字符串。在数组中找出和为固定值的组合在有重复数字的数组中找出和为固定值的组合 给…

详细介绍:【JUnit实战3_21】第十二章:JUnit 5 与主流 IDE 的集成 + 第十三章:用 JUnit 5 做持续集成(上):在本地安装 Jenkins

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

代码随想录Day24_回溯_复原IP.md

代码随想录Day24_回溯_复原IP.md复原IP地址 题目理解 1.给出的是字符串,IP地址在【0,255】之间,字符串转数字; 2.0可以单独出现,但是不能跟数字出现; 3.字符串中要插入.; 4.字符串的大小范围在4~12之间; 5.不能…

何以为生

何以为生何以为生人造的东西 价值不贵。 天然的才是资源。不能打断别人说话, 不急不躁。很想买入一支股票。。。

GraphRAG进阶:基于Neo4j与LlamaIndex的DRIFT搜索实现详解

微软的GraphRAG算得上是最早一批成熟的GraphRAG系统,它把索引阶段(抽取实体、关系、构建层级社区并生成摘要)和查询阶段的高级能力整合到了一起。这套方案的优势在于,可以借助预先计算好的实体、关系、社区摘要来回…

Gemini3疯了!0.09接入Nano Banana Pro 4k画质API(附实战教程)

2025年11月20日谷歌正式推出Nano Banana Pro(官方名称Gemini 3 Pro Image)时,Ai图像生成最强模型。这款基于Gemini 3 Pro foundation打造的新一代图像生成与编辑模型,不仅在图像质量上达到了全新高度,更在4K高清分…

11/28

今天没课,嘿嘿

noip板子

倍增法lca const int N = 500010; int n, m, s; vector<int> g[N]; void addeg(int u, int v) {g[u].push_back(v);g[v].push_back(u); }int d[N], anc[N][25]; void dfs(int u, int fa) {d[u] = d[fa] + 1;for …

东方博宜OJ 1119:求各位数字之和 ← 循环结构

​【题目来源】https://oj.czos.cn/p/1119【题目描述】输入一个正整数 N(0≤N≤2147483647),求它的各位数字之和。【输入格式】一行,一个正整数 N。【输出格式】一行,一个整数。【输入样例】189【输出样例】18【数…

2025.11.28

起床,吃饭,躺着,上网课,洗澡,买酸奶,吃饭,睡觉

10个免费查重降重工具分享,降AIGC率工具

在当前的学术环境中,确保论文的原创性和降低AI生成内容(AIGC)的检测率变得尤为重要。以下是一些能够有效降低论文AIGC率的工具,包括它们的功能、使用方法、效果以及用户评价。 SpeedAI 功能:SpeedAI专注于去除文档…

Linux_Socket_浅谈UDP - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

Jetlinks 物联网平台 开源版学习源码分析

2022-06-25 Jetlinks Jetlinks 是一个非常优秀物联网基础平台, 还支持开源二次开发, 且他们的开发团队还非常友好的, 即使你使用的是开源的版本还挺愿意帮你解决问题 (当然我司也购买了企业版, 但不能分享学习笔记) 文…

多项式次数选择完整演示

多项式次数选择完整演示(Python) 本文将通过 人工生成数据→数据划分→多次数模型训练→验证集筛选最优次数→测试集评估 的全流程,演示多项式回归中如何通过验证集选择最优次数,所有代码逐行解释,兼顾理论与实践…

Java 线程池深度解析:原理、策略与生产环境调优指南

在现代 Java 应用中,线程池已成为并发处理的核心基础设施。无论是 Web 服务、定时任务、RPC 框架还是大数据处理,线程池都扮演着至关重要的角色。正确理解线程池的工作机制与调优方法,将直接影响系统的吞吐、延迟与…