fatfs文件系統(tǒng)與lvgl字符編碼的適配
????通常我們使用lvgl的時(shí)候還會(huì)搭配fatfs文件系統(tǒng)來(lái)做一些文件IO,比如用lvgl做MP3,相冊(cè)這類的,肯定需要用fatfs來(lái)讀取文件。咱們是中國(guó)人,肯定是講漢語(yǔ),讀漢字的,文件的命名也肯定會(huì)有中文,那就需要讓文件系統(tǒng)讀取到的中文碼流讓lvgl正確識(shí)別和顯示了。
????首先要了解兩種的字符編碼格式,fatfs的文件路徑采用的是unicode編碼,而lvgl采用的是UTF-8編碼,這兩者的轉(zhuǎn)換可以說(shuō)是非常簡(jiǎn)單,只需要進(jìn)行幾步位運(yùn)算即可,而不需要使用fatfs自帶的cc936里面2個(gè)龐大的數(shù)組,轉(zhuǎn)換效率高,又省空間,可謂是一舉兩得。
????特別說(shuō)明一下,對(duì)于文件(路徑)名如果不進(jìn)行轉(zhuǎn)換的話,其字符編碼格式通常與操作系統(tǒng)有關(guān),對(duì)于中文語(yǔ)言通常是GB2312。也就是說(shuō),如果在電腦上創(chuàng)建了一個(gè)文本內(nèi)容為UTF8編碼的txt文本文件,lvgl是可以正確識(shí)別讀取到的中文的(前提是在fatfs讀取的時(shí)候需要使用字節(jié)流api而非字符流api)。但有的時(shí)候需要在lvgl上顯示文件名或者路徑,比如遍歷一個(gè)文件夾下的所有文件(例:.mp3文件)并顯示出來(lái),這就有問(wèn)題了。
????上面吧啦了那么多,總的來(lái)講我們要做的就是讓lvgl可以正確識(shí)別和顯示fatfs獲取到的文件(路徑)名。下面就分步驟詳細(xì)說(shuō)明操作方法:
1.修改fatfs配置文件ffconf.h
首先是未修改前的基本配置:
????順便解釋一下代碼頁(yè)的作用:因?yàn)閒atfs是使用Unicode編碼的,但在電腦上往里存的文件或者說(shuō)在fatfs上編輯后要從電腦上正確打開的文件不一定是unicode編碼的,這就需要針對(duì)不同語(yǔ)言的編碼標(biāo)準(zhǔn)與Unicode之間進(jìn)行轉(zhuǎn)換,比如中文(936)就是在GB2312和Unicode之間進(jìn)行轉(zhuǎn)換。
????確保以上配置編譯運(yùn)行后可以正常打開英文路徑的文件后,就可以進(jìn)行修改了,需要修改的配置如下:
2.修改文件名編碼方式為UTF8
????上面說(shuō)了CODE_PAGE的作用,電腦上文件名使用的字符編碼因?yàn)椴皇荱nicode才需要進(jìn)行轉(zhuǎn)換,而且上文也說(shuō)了Unicode和UTF8轉(zhuǎn)換非常方便。所以只要我們把存進(jìn)去的文件名字符編碼修改為UTF8,這樣就可以擺脫那2個(gè)龐大的936轉(zhuǎn)換數(shù)組了,也給lvgl顯示中文帶來(lái)了方便。修改文件名編碼方式為UTF8有2種方法:
①在Linux系統(tǒng)下使用convmv工具轉(zhuǎn)換
如果你的系統(tǒng)沒有convmv這個(gè)工具,使用以下命令安裝
然后使用以下命令轉(zhuǎn)換即可:
如果已經(jīng)是UTF8編碼了,工具會(huì)提示already UTF-8: 文件名。
②修改windows下強(qiáng)制UTF8編碼
這個(gè)方法可以一勞永逸,但缺點(diǎn)是如果有些軟件的UI字符不支持UTF8,那么軟件下的中文可能顯示異常,比如keil5的下方信息框中顯示中文會(huì)亂碼,在調(diào)試時(shí)看內(nèi)存的中文字符串也會(huì)亂碼。
首先打開windows設(shè)置,選擇“時(shí)間和語(yǔ)言”->“語(yǔ)言”:
????點(diǎn)擊“管理語(yǔ)言設(shè)置”

????在“更改系統(tǒng)區(qū)域設(shè)置”中將“Beta版.....”打勾,然后確認(rèn)即可,系統(tǒng)會(huì)提示重啟。重啟之后系統(tǒng)會(huì)自動(dòng)將磁盤里所有的文件名全部改成UTF8編碼,往后創(chuàng)建的文件也會(huì)是UTF8編碼。

3.修改編輯器的字符編碼方式為UTF8
????編輯器的字符編碼方式?jīng)Q定了編譯成二進(jìn)制文件后,其中的字符串對(duì)應(yīng)的二進(jìn)制數(shù)值是何種編碼格式。具體操作方法這里就不細(xì)說(shuō)了,因?yàn)槊總€(gè)人的編輯器可能不一樣,大家可以自己百度查找方法。
4.給你的工程添加UTF8和Unicode互轉(zhuǎn)函數(shù)
????UTF8是以字節(jié)為單位,Unicode是以半字為單位。所以fatfs在使能了_LFN_UNICODE選項(xiàng)后,文件路徑會(huì)從原來(lái)的char *變成 unsigned short *,任何字符都是2個(gè)字節(jié)存儲(chǔ),包括ascii字符。但是在編譯器中對(duì)常量ascii字符的處理是以1個(gè)字節(jié)來(lái)儲(chǔ)存,所以我們需要將一個(gè)完整的UTF8字符串轉(zhuǎn)換成每個(gè)字符都以2個(gè)字節(jié)存儲(chǔ),除此之外還需要對(duì)非ascii字符在UTF8和Unicode之間進(jìn)行轉(zhuǎn)換,這一步僅需要幾步位運(yùn)算即可。因?yàn)樾枰p向轉(zhuǎn)換,所以需要寫成2個(gè)函數(shù):
這兩個(gè)函數(shù)內(nèi)容不多,我會(huì)在文章末尾貼出來(lái),大家需要的話直接復(fù)制即可。
5.打開文件或目錄
????打開一個(gè)文件時(shí),在以前我們是這樣做的:
????直接傳入文件路徑常量字符串就可以打開文件。但設(shè)置了unicode后,f_open的第二個(gè)參數(shù)類型就不是const char*了。這時(shí)我們可以使用上面那兩個(gè)轉(zhuǎn)換函數(shù)進(jìn)行轉(zhuǎn)換:
????上方的TCHAR是fatfs重定義的一個(gè)類型,在沒有設(shè)置unicode前為char,設(shè)置了unicode后就是unsigned short。這樣就可以正確打開文件了。打開目錄也是同理的,需要先進(jìn)行轉(zhuǎn)換。
????在使用f_readdir函數(shù)讀取目錄文件時(shí),文件信息中的文件名fname也是unicode字符編碼格式,如果需要在lvgl上顯示,就需要進(jìn)行轉(zhuǎn)換:
????好了,這樣操作之后就實(shí)現(xiàn)了fatfs和lvgl的字符編碼適配,如果要使用lvgl+fatfs做一個(gè)類似MP3的東西,需要遍歷目錄中含有中文名的文件并顯示就非常方便了。
????如果需要工程參考,可以參考我的視頻(BV1eR4y1c7QV)中plus板的音樂(lè)播放器代碼。
2個(gè)函數(shù)完整代碼: