fatfs文件系统与lvgl字符编码的适配
通常我们使用lvgl的时候还会搭配fatfs文件系统来做一些文件IO,比如用lvgl做MP3,相册这类的,肯定需要用fatfs来读取文件。咱们是中国人,肯定是讲汉语,读汉字的,文件的命名也肯定会有中文,那就需要让文件系统读取到的中文码流让lvgl正确识别和显示了。
首先要了解两种的字符编码格式,fatfs的文件路径采用的是unicode编码,而lvgl采用的是UTF-8编码,这两者的转换可以说是非常简单,只需要进行几步位运算即可,而不需要使用fatfs自带的cc936里面2个庞大的数组,转换效率高,又省空间,可谓是一举两得。
特别说明一下,对于文件(路径)名如果不进行转换的话,其字符编码格式通常与操作系统有关,对于中文语言通常是GB2312。也就是说,如果在电脑上创建了一个文本内容为UTF8编码的txt文本文件,lvgl是可以正确识别读取到的中文的(前提是在fatfs读取的时候需要使用字节流api而非字符流api)。但有的时候需要在lvgl上显示文件名或者路径,比如遍历一个文件夹下的所有文件(例:.mp3文件)并显示出来,这就有问题了。
上面吧啦了那么多,总的来讲我们要做的就是让lvgl可以正确识别和显示fatfs获取到的文件(路径)名。下面就分步骤详细说明操作方法:
1.修改fatfs配置文件ffconf.h
首先是未修改前的基本配置:
顺便解释一下代码页的作用:因为fatfs是使用Unicode编码的,但在电脑上往里存的文件或者说在fatfs上编辑后要从电脑上正确打开的文件不一定是unicode编码的,这就需要针对不同语言的编码标准与Unicode之间进行转换,比如中文(936)就是在GB2312和Unicode之间进行转换。
确保以上配置编译运行后可以正常打开英文路径的文件后,就可以进行修改了,需要修改的配置如下:
2.修改文件名编码方式为UTF8
上面说了CODE_PAGE的作用,电脑上文件名使用的字符编码因为不是Unicode才需要进行转换,而且上文也说了Unicode和UTF8转换非常方便。所以只要我们把存进去的文件名字符编码修改为UTF8,这样就可以摆脱那2个庞大的936转换数组了,也给lvgl显示中文带来了方便。修改文件名编码方式为UTF8有2种方法:
①在Linux系统下使用convmv工具转换
如果你的系统没有convmv这个工具,使用以下命令安装
然后使用以下命令转换即可:
如果已经是UTF8编码了,工具会提示already UTF-8: 文件名。
②修改windows下强制UTF8编码
这个方法可以一劳永逸,但缺点是如果有些软件的UI字符不支持UTF8,那么软件下的中文可能显示异常,比如keil5的下方信息框中显示中文会乱码,在调试时看内存的中文字符串也会乱码。
首先打开windows设置,选择“时间和语言”->“语言”:
点击“管理语言设置”

在“更改系统区域设置”中将“Beta版.....”打勾,然后确认即可,系统会提示重启。重启之后系统会自动将磁盘里所有的文件名全部改成UTF8编码,往后创建的文件也会是UTF8编码。

3.修改编辑器的字符编码方式为UTF8
编辑器的字符编码方式决定了编译成二进制文件后,其中的字符串对应的二进制数值是何种编码格式。具体操作方法这里就不细说了,因为每个人的编辑器可能不一样,大家可以自己百度查找方法。
4.给你的工程添加UTF8和Unicode互转函数
UTF8是以字节为单位,Unicode是以半字为单位。所以fatfs在使能了_LFN_UNICODE选项后,文件路径会从原来的char *变成 unsigned short *,任何字符都是2个字节存储,包括ascii字符。但是在编译器中对常量ascii字符的处理是以1个字节来储存,所以我们需要将一个完整的UTF8字符串转换成每个字符都以2个字节存储,除此之外还需要对非ascii字符在UTF8和Unicode之间进行转换,这一步仅需要几步位运算即可。因为需要双向转换,所以需要写成2个函数:
这两个函数内容不多,我会在文章末尾贴出来,大家需要的话直接复制即可。
5.打开文件或目录
打开一个文件时,在以前我们是这样做的:
直接传入文件路径常量字符串就可以打开文件。但设置了unicode后,f_open的第二个参数类型就不是const char*了。这时我们可以使用上面那两个转换函数进行转换:
上方的TCHAR是fatfs重定义的一个类型,在没有设置unicode前为char,设置了unicode后就是unsigned short。这样就可以正确打开文件了。打开目录也是同理的,需要先进行转换。
在使用f_readdir函数读取目录文件时,文件信息中的文件名fname也是unicode字符编码格式,如果需要在lvgl上显示,就需要进行转换:
好了,这样操作之后就实现了fatfs和lvgl的字符编码适配,如果要使用lvgl+fatfs做一个类似MP3的东西,需要遍历目录中含有中文名的文件并显示就非常方便了。
如果需要工程参考,可以参考我的视频(BV1eR4y1c7QV)中plus板的音乐播放器代码。
2个函数完整代码: