在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

基于STM32+CS創世 SD NAND(貼片SD卡)完成FATFS文件系統移植與測試(下篇)

深圳市雷龍發展有限公司 ? 2023-03-03 13:52 ? 次閱讀

四、移植FATFS文件系統

前面第3章,完成了SD NAND的驅動代碼編寫,這一章節實現FATFS文件的移植。

4.1 FATFS文件系統介紹

(1)介紹

FatFs 是一種完全免費開源的 FAT 文件系統模塊,專門為小型的嵌入式系統而設計。它完全用標準C 語言編寫,所以具有良好的硬件平臺獨立性,可以移植到 8051、 PIC、 AVR、 SH、 Z80、 H8、 ARM 等系列單片機上而只需做簡單的修改。它支持 FATl2、 FATl6 和 FAT32,支持多個存儲媒介;有獨立的緩沖區,可以對多個文件進行讀/寫,并特別對 8 位單片機和 16 位單片機做了優化。

(2)特點

【1】Windows兼容的FAT文件系統

【2】不依賴于平臺,易于移植

【3】代碼和工作區占用空間非常小

【4】多種配置選項

【5】多卷(物理驅動器和分區)

【6】多ANSI/OEM代碼頁,包括DBCS

【7】在ANSI/OEM或Unicode中長文件名的支持

【8】RTOS的支持

【9】多扇區大小的支持

【10】只讀,最少API,I/O緩沖區等等

(3)移植性

fatfs模塊是ANSI C(C89)編寫的。 沒有平臺的依賴, 編譯器只要符合ANSI C標準就可以編譯。

fatf模塊假設大小的字符/短/長8/16/32位和int是16或32位。 這些數據類型在integer.h文件中定義。這些數據類型在大多數的編譯器中定義都符合要求。 如果現有的定義與編譯器有任何沖突發生時,需要自己解決。

4.2 下載源碼

13.png

FATFS有兩個版本,一個大版本,一個小版本。小版本主要用于8位機(內存小)使用。

下載圖:

14.png


4.3 源碼結構介紹

將下載的源碼解壓后可以得到兩個文件夾: doc 和 src。 doc 里面主要是對 FATFS 的介紹(離線文檔—英文和日文),而 src 里面才是我們需要的源碼。

其中,與平臺無關的是:

ffconf.h FATFS配置文件

ff.h 應用層頭文件

ff.c 應用層源文件

diskio.h 硬件層頭文件

interger.h 數據類型定義頭文件

option 可選的外部功能(比如支持中文等)

與平臺相關的代碼:

diskio.c 底層接口文件(需要用戶提供)

FATFS 模塊在移植的時候,我們一般只需要修改 2 個文件,即 ffconf.h 和 diskio.c。

FATFS模塊的所有配置項都是存放在 ffconf.h 里面,我們可以通過配置里面的一些選項,來滿足自己的需求。

15.png

最頂層是應用層,使用者無需理會 FATFS 的內部結構和復雜的 FAT 協議,只需要調用FATFS 模塊提供給用戶的一系列應用接口函數,如 f_open, f_read, f_write 和 f_close 等,就可以像在 PC 上讀寫文件那樣簡單。

中間層 FATFS 模塊, 實現了 FAT 文件讀/寫協議。 FATFS 模塊提供的是 ff.c 和 ff.h。除非有必要,使用者一般不用修改,使用時將頭文件直接包含進去即可。

需要我們編寫移植代碼的是 FATFS 模塊提供的底層接口,它包括存儲媒介讀/寫接口 ( disk、I/O) 和供給文件創建修改時間的實時時鐘

4.4 下載源碼并加入到工程

先準備好一個有SD NAND驅動代碼的STM32工程(代碼前面第3章已經貼了),接著就完成下面的步驟。

16.png

打開KEIL工程,添加FATFS文件源碼:

17.png18.png


加入.h文件主要是方便配。cc936.c 用于支持中文。

4.5 修改代碼進行移植

(1)修改diskio.c文件

19.png



注釋掉現在不需要的用到的文件,因為我們現在用的是SD卡,與USB,ATA,MMC卡沒關系。

并加入一個新的宏 :

#define SD 0

定義SD卡的物理驅動器號為0。

修改 disk_status函數,該函數主要是用來獲取磁盤狀態。現在未用到,可以直接函數體內代碼刪除。

修改截圖:

20.png

代碼示例:

#include "diskio.h" /* fatf底層API */

#include "sd.h" /* SD卡驅動頭文件 */

/* 定義每個驅動器的物理驅動器號*/

#define SD 0

/*-----------------------------------------------------------------------*/

/* 獲取設備(磁盤)狀態 */

/*-----------------------------------------------------------------------*/

DSTATUS disk_status (

BYTE pdrv /* 物理驅動識別 */

)

{

return 0; //該函數現在無需用到,直接返回0

}


修改disk_initialize函數,添加SD卡的初始化,其他不用到的代碼直接刪掉,該函數成功返回0,失敗返回1。

修改截圖:

21.png


代碼示例:

/*-----------------------------------------------------------------------*/

/* 初始化磁盤驅動 */

/*-----------------------------------------------------------------------*/

DSTATUS disk_initialize (

BYTE pdrv /* 物理驅動識別 */

)

{

DSTATUS stat;

int result;

switch (pdrv) {

case SD : //選擇SD卡

stat=SD_Init(); //初始化SD卡-用戶自己提供

}

if(stat)return STA_NOINIT; //磁盤未初始化

return 0; //初始化成功

}


修改disk_read函數,加入SD卡讀任意扇區的函數(需要用戶自己提供),其他不用到的選項可以刪掉。

22.png


修改代碼如下:

/*-----------------------------------------------------------------------*/

/* 讀扇區 */

/*-----------------------------------------------------------------------*/

DRESULT disk_read (

BYTE pdrv, /* 物理驅動編號 - 范圍0-9*/

BYTE *buff, /* 數據緩沖區存儲讀取數據 */

DWORD sector, /* 扇區地址*/

UINT count /* 需要讀取的扇區數*/

)

{

DRESULT res;

int result;

switch (pdrv) {

case SD:

res=SD_Read_Data((u8*)buff,sector,count); //讀SD扇區函數--用戶提供

return res; //在此處可以判錯誤

}

return RES_PARERR; //無效參數

}


修改disk_write 函數,添加寫扇區函數:

23.png

代碼:

/*-----------------------------------------------------------------------*/

/* 寫扇區 */

/*-----------------------------------------------------------------------*/

#if _USE_WRITE

DRESULT disk_write (

BYTE pdrv, /* 物理驅動號*/

const BYTE *buff, /* 要寫入數據的首地址 */

DWORD sector, /* 扇區地址 */

UINT count /* 扇區數量*/

)

{

DRESULT res;

int result;

switch (pdrv) {

case SD:

res=SD_Write_Data((u8*)buff,sector,count); //寫入扇區

return res;

}

return RES_PARERR; //無效參數

}

#endif

修改disk_ioctl 函數,填充ioctl命令功能。這些功能是標準的命令,在diskio.h有定義。

24.png

代碼如下:

/*-----------------------------------------------------------------------*/

/* 其他函數 */

/*-----------------------------------------------------------------------*/

#if _USE_IOCTL

DRESULT disk_ioctl (

BYTE pdrv, /* 物理驅動號 */

BYTE cmd, /* 控制碼 */

void *buff /* 發送/接收數據緩沖區地址 */

)

{

DRESULT res;

int result;

switch (pdrv) {

case SD:

switch(cmd)

{

case CTRL_SYNC: //等待寫過程

SD_CS(0); //選中SD卡

if(SD_Wait_Ready())result = RES_ERROR;/*等待卡準備好*/

else res = RES_OK; //成功

SD_CS(1); //釋放SD卡

break;

case GET_SECTOR_SIZE://獲取扇區大小

*(DWORD*)buff = 512;

res = RES_OK; //成功

break;

case GET_BLOCK_SIZE: //獲取塊大小

*(WORD*)buff = 8; //塊大小(扇區為單位),一塊等于8個扇區

res = RES_OK;

break;

case GET_SECTOR_COUNT: //獲取總扇區數量

*(DWORD*)buff = SD_Get_Sector_Count();

res = RES_OK;

break;

default: //命令錯誤

res = RES_PARERR;

break;

}

return res;

}

return RES_PARERR; //返回狀態

}


(2)修改ffconf.h文件

需要注意的一些宏配置:

#define _CODE_PAGE 936 //采用中文GBK編碼 (64行)

#define _USE_LFN 3 //動態的堆上工作 (93行)

#define _MAX_LFN 255 /*_USE_LFN選項開關LFN(長文件名)特性。

#define _VOLUMES 1 /* 支持的磁盤數量(邏輯驅動器)。 */ (142行)

#define _MIN_SS 512 (165行)

#define _MAX_SS 512 /*這些選項配置支持扇區大小的范圍。(512,1024, 4096*/

#define _FS_NORTC 0 /*啟用RTC時間功能*/ (202行)

#define _NORTC_MON 1

#define _NORTC_MDAY 1

#define _NORTC_YEAR 2015 //年

/*需要實現:get_fattime()函數*/


ffconf.h 文件源碼:

/*---------------------------------------------------------------------------/

/ FatFs - FAT文件系統模塊配置文件 R0.11a (C)ChaN, 2015

/---------------------------------------------------------------------------*/

#define _FFCONF 64180 /* 版本識別*/

/*---------------------------------------------------------------------------/

/ 功能配置

/---------------------------------------------------------------------------*/

#define _FS_READONLY 0

/* 這個選項開關只讀配置。(0:讀/寫或1:只讀)

/只讀配置刪除編寫API函數,f_write(),f_sync(),

/ f_unlink(),f_mkdir(),f_chmod(),f_rename(),f_truncate(),f_getfree()

/寫和可選的功能. */

#define _FS_MINIMIZE 0

/*此選項定義刪除一些基本的API函數極小化水平。

/

/ 0:所有基本功能都是激活的。

/ 1:f_stat(),f_getfree(),f_unlink(),f_mkdir(),f_chmod(),f_utime(),

/ f_truncate()和f_rename()函數刪除。

/ 2:f_opendir(),f_readdir()和f_closedir()中除了1。

/ 3:f_lseek()函數刪除除了2。*/

#define _USE_STRFUNC 1

/*這個選項開關字符串函數,f_gets(),f_putc(),f_puts()和

/ f_printf()。

/

/ 0:禁用字符串函數。

/ 1:啟用沒有LF-CRLF轉換。

/ 2:啟用LF-CRLF(回車換行)轉換。*/

#define _USE_FIND 0

/*這個選項開關過濾目錄讀取特性和相關功能,

/ f_findfirst()和f_findnext()。(0:禁用或1:啟用)*/

#define _USE_MKFS 1

/* 這個選項開關f_mkfs()函數。(0:禁用或1:啟用) */

#define _USE_FASTSEEK 1

/* 這個選項開關快速尋求功能。(0:禁用或1:啟用) */

#define _USE_LABEL 1

/* 磁盤卷標這個選項開關功能,f_getlabel()和f_setlabel()。

/(0:禁用或1:啟用) */

#define _USE_FORWARD 0

/* 這個選項開關f_forward()函數。(0:禁用或1:啟用)

/啟用它,也_FS_TINY需要設置為1. */

/*---------------------------------------------------------------------------/

/ 語言環境和名稱空間配置

/---------------------------------------------------------------------------*/

#define _CODE_PAGE 936 //采用中文GBK編碼

/*這個選項指定OEM代碼頁在目標系統上使用。

/不正確的代碼頁的設置會導致文件打開失敗.

/

/ 1 - ASCII (沒有擴展字符。Non-LFN cfg。只有)

/ 437 - U.S.

/ 720 - 阿拉伯語

/ 737 - 希臘語;

/ 771 - 阿富汗

/ 775 - 波羅的海

/ 850 - 拉丁1

/ 852 - 拉丁2

/ 855 - 西里爾字母

/ 857 - 土耳其語

/ 860 - 葡萄牙語

/ 861 - 冰島語

/ 862 - 希伯來人

/ 863 - 加拿大法語

/ 864 - 阿拉伯語

/ 865 - 日耳曼民族的

/ 866 - 俄語

/ 869 - 希臘 2

/ 932 - 日本人 (DBCS)

/ 936 - 簡體中文(DBCS)

/ 949 - 韓國人 (DBCS)

/ 950 - 繁體中文(DBCS)

*/

#define _USE_LFN 3 //動態的堆上工作

#define _MAX_LFN 255

/*_USE_LFN選項開關LFN(長文件名)特性。

/

/ 0:禁用LFN特性。_MAX_LFN沒有影響。

/ 1:啟用LFN BSS靜態工作緩沖區。總是不是線程安全的。

/ 2:啟用LFN與動態緩沖棧上的工作。

/ 3:使LFN與動態緩沖區在堆上工作。

/

/ 當啟用LFN(長文件名)特性,Unicode(選項/ unicode.c)必須處理功能

/被添加到項目中。LFN工作緩沖區占用(_MAX_LFN + 1)* 2字節。

/當使用堆棧緩沖區,照顧堆棧溢出。當使用堆

/工作緩沖區內存,內存管理功能,ff_memalloc()和

/ ff_memfree(),必須添加到項目中。 */

#define _LFN_UNICODE 0

/* 這個選項開關字符編碼的API。(0:ANSI / OEM或1:Unicode)

路徑名/使用Unicode字符串,并設置_LFN_UNICODE啟用LFN特性

/1。這個選項也會影響行為的字符串的I / O功能。

*/

#define _STRF_ENCODE 3

/* 當_LFN(長文件名)_UNICODE是1,這個選項選擇文件的字符編碼

/通過字符串讀取/寫入I /O功能,f_gets(),f_putc(),f_puts和f_printf().

/

/ 0: ANSI/OEM

/ 1: UTF-16LE

/ 2: UTF-16BE

/ 3: UTF-8

/

/ 當_LFN_UNICODE = 0時,該選項沒有影響。*/

#define _FS_RPATH 0

/*這個選項配置相對路徑的功能。/

/ 0:禁用相對路徑特性和刪除相關功能。

/ 1:啟用相對路徑特性。f_chdir()和f_chdrive()是可用的。

/ 2:f_getcwd()函數可用除了1。/

/注意,目錄項讀通過f_readdir()這個選項。

*/

/*---------------------------------------------------------------------------/

/ 驅動/卷配置

/---------------------------------------------------------------------------*/

#define _VOLUMES 1

/* 支持的磁盤數量(邏輯驅動器)。 */

#define _STR_VOLUME_ID 0

#define _VOLUME_STRS "RAM","NAND","CF","SD1","SD2","USB1","USB2","USB3"

/* STR_VOLUME_ID選項開關卷ID字符串功能。

/當_STR_VOLUME_ID設置為1時,也可以使用預先定義的字符串在路徑名稱/數量。

為每個_VOLUME_STRS定義驅動ID字符串

/邏輯驅動器。條目的數量必須等于_VOLUMES。有效字符

/驅動ID字符串:a - z和0 - 9。*/

#define _MULTI_PARTITION 0

/* 這個選項開關多分區的特性。在默認情況下(0),每個邏輯驅動器

/號綁定到相同的物理驅動器號

/物理驅動器將被安裝。當啟用分區特性(1),

/每個邏輯驅動器號是綁定到任意物理驅動器和分區

/中列出VolToPart[]。還f_fdisk()函數可用. */

#define _MIN_SS 512

#define _MAX_SS 512

/* 這些選項配置支持扇區大小的范圍。(512,1024,

/ 2048或4096)總是為大多數系統設置兩個512,卡和所有類型的內存

/硬盤。但是可能需要更大的值為車載閃存和一些

/類型的光學媒體。當_MAX_SS大于_MIN_SS,fatf配置

/變量扇區大小和GET_SECTOR_SIZE命令必須執行disk_ioctl()函數. */

#define _USE_TRIM 0

/* 這個選項開關ATA-TRIM特性。(0:禁用或1:啟用)

/啟用削減特性,也應該實現CTRL_TRIM命令

/ disk_ioctl()函數。*/

#define _FS_NOFSINFO 0

/*

如果你需要知道正確的自由空間體積FAT32,設置一些0

/選項,f_getfree()函數在第一次后體積將迫使山

/全脂肪掃描。位1控制使用的集群數量分配。/

/ bit0 = 0:使用免費的集群計算FSINFO如果可用。

/ bit0 = 1:不相信自由FSINFO集群計算。

/ bit1 = 0:最后使用集群可用FSINFO如果數量分配。

/ bit1 = 1:不相信最后分配FSINFO集群數量.

*/

/*---------------------------------------------------------------------------/

/ 系統配置列表

/---------------------------------------------------------------------------*/

#define _FS_TINY 0

/* 這個選項開關小緩沖區配置。(0:正常或1:小)

/小配置,文件對象的大小(FIL)_MAX_SS減少字節。而不是私人部門從文件對象,緩沖了

/公共部門緩沖文件系統中的對象(fatf)是用于該文件

/數據傳輸. */

#define _FS_NORTC 0

#define _NORTC_MON 1

#define _NORTC_MDAY 1

#define _NORTC_YEAR 2015 //年

/* _FS_NORTC選項開關時間戳的特性。如果系統沒有/

RTC函數或不需要有效的時間戳,_FS_NORTC 1設置為禁用/

時間戳的特性。所有對象修改fatf將有一個固定的時間戳。/

固定的時間定義為_NORTC_MON _NORTC_MDAY _NORTC_YEAR。

/當啟用時間戳特性(_FS_NORTC = = 0),需要實現get_fattime()函數。/

添加到項目RTC讀當前時間形式。_NORTC_MON, /

_NORTC_MDAY和_NORTC_YEAR沒有效果。

/這些選項沒有影響只讀配置(_FS_READONLY = = 1)。 */

#define _FS_LOCK 0

/* _FS_LOCK選項開關控制復制的文件打開的文件鎖定功能

/和非法操作打開對象。這個選項_FS_READONLY時必須是0

/是1。/

/ 0:禁用文件鎖定功能。為了避免體積腐敗、應用程序

/應該避免非法打開,刪除和重命名的開放對象。

/ > 0:啟用文件鎖定功能。值定義了多少文件/子目錄

可以同時打開的/文件鎖的控制之下。注意,這個文件獨立于re-entrancy /鎖功能。 */

#define _FS_REENTRANT 0

#define _FS_TIMEOUT 1000

#define _SYNC_t HANDLE

/* _FS_REENTRANT選項開關re-entrancy fatf的(線程安全)

/模塊本身。注意,不管這個選項,文件訪問不同

/體積始終是凹角和音量控制功能,f_mount(),f_mkfs()

/和f_fdisk()函數,總是不凹角。只有文件/目錄的訪問

/相同的體積是這個功能的控制。

/

/ 0:禁用re-entrancy。_FS_TIMEOUT和_SYNC_t沒有效果。

/ 1:啟用re-entrancy。還提供用戶同步處理程序,

/ ff_req_grant(),ff_rel_grant(),ff_del_syncobj()和ff_cre_syncobj()

/函數,必須添加到項目中。樣品中可用

/選項

/ syscall.c。

/

/ _FS_TIMEOUT定義超時時間單位的滴答聲。

/ _SYNC_t定義了O

/ S依賴同步對象類型。例如處理、ID、OS_EVENT *

/ SemaphoreHandle_t等. .O / S的頭文件定義需要

/包括在ff.c的范圍。 */

#define _WORD_ACCESS 0

/* _WORD_ACCESS選項是一個只有依賴于平臺的選擇。

它定義了這個詞/訪問方法是用來體積上的數據。

/

/ 0:逐字節的訪問。總是兼容所有平臺。

/ 1:詞的訪問。不要選擇這個,除非在下列條件。

/

/ *地址對齊內存訪問總是允許所有指令。

/ *字節順序的記憶是低位優先。

/

/如果是這樣的情況,_WORD_ACCESS也可以減少代碼的大小設置為1。

/下表顯示允許設置某種類型的處理器

/

/ ARM7TDMI 0 *2 ColdFire 0 *1 V850E 0 *2

/ Cortex-M3 0 *3 Z80 0/1 V850ES 0/1

/ Cortex-M0 0 *2 x86 0/1 TLCS-870 0/1

/ AVR 0/1 RX600(LE) 0/1 TLCS-900 0/1

/ AVR32 0 *1 RL78 0 *2 R32C 0 *2

/ PIC18 0/1 SH-2 0 *1 M16C 0/1

/ PIC24 0 *2 H8S 0 *1 MSP430 0 *2

/ PIC32 0 *1 H8/300H 0 *1 8051 0/1

/

/

* 1:高位優先。/

* 2:不支持不連續的內存訪問。/

* 3:一些編譯器生成LDM(邏輯磁盤管理器 ) / STM mem_cpy(內存拷貝)函數。

*/


(3)實現動態內存分配函數與時間函數

ff.h文件有動態內存的釋放,動態內存申請,時間獲取函數接口。

25.png


在diskio.c文件實現函數功能:

26.png


代碼實現如下:

//動態內存分配

void* ff_memalloc (UINT msize) /* 分配內存塊 */

{

return (void*)malloc(msize); //分配空間

}

//動態內存釋放

void ff_memfree (void* mblock) /* 空閑內存塊 */

{

free(mblock); //釋放空間

}

//返回FATFS時間

//獲得時間

DWORD get_fattime (void)

{

//Get_RTC_Timer(); //獲取一次RTC時間

return (RTC_Timer.year-1980)<<25|? ?//年

RTC_Timer.month<<21|? //月

RTC_Timer.day<<16|? ? //日

RTC_Timer.hour<<11|? ?//時

RTC_Timer.minute<<5|? //分

RTC_Timer.sec; //秒

}

/*

Return Value

Currnet local time is returned with packed into a DWORD value. The bit field is as follows:

bit31:25

Year origin from the 1980 (0..127)

bit24:21

Month (1..12)

bit20:16

Day of the month(1..31)

bit15:11

Hour (0..23)

bit10:5

Minute (0..59)

bit4:0

Second / 2 (0..29)

*/


(4)修改堆棧空間

完成了上述的修改,還需要修改堆棧空間,因為長文件支持需要占用堆空間。

修改STM32啟動文件如下:

27.png



(5)編譯工程測試

修改完畢之后,給開發板插上SD卡,調用API函數在SD卡創建一個文件,并寫入數據,測試是否成功:

#include "ff.h"

FATFS fs; // 用戶定義的文件系統結構體

FIL file; // 用戶定義的文件系統結構體

u8 buff[]="123 知識!!";

int main(void)

{

u32 data; //檢測SD卡容量

u8 i,res;

LED_Init(); //LED燈初始化

Delay_Init();

KEY_Init();

USART1_Init(72,115200);

USART2_Init(36,115200);

FLASH_Init();

Set_Font_addr(); //字庫地址初始化

FSMC_SRAM_Init();

LCD_Init();

RTC_Init(); //RTC時鐘初始化

while(SD_Init()) //檢測不到SD卡,SD相關硬件初始化

{

i=!i;

LCD_ShowString(60,150,200,16,16,"SD Card Error! Please Check SD Card!!",0xf800);

Delay_ms(500);

LED1(i)//DS0閃爍

}

f_mount(&fs,"0",1); // 注冊工作區,驅動器號 0,初始化后其他函數可使用里面的參數

printf("注冊工作區!\n");

if(f_mkfs("0",0,4096)) //格式化SD卡

{

printf("格式化失敗!!\n");

}

else

{

printf("格式化成功!!\n");

}

res = f_open(&file, "/file.c", FA_OPEN_ALWAYS | FA_READ | FA_WRITE);

if(res==0)

{

printf("文件創建成功!!\n");

}

else

{

printf("文件創建失敗!!\n");

}

res =f_write(&file,buff,strlen((const char*)buff),&data);

if(res==0)

{

printf("數據寫入成功!!\n");

}

else

{

printf("數據寫入失敗!!\n");

}

printf("成功寫入%d字節數據\n",data);

f_close(&file); //關閉文件

//_FS_RPATH

while(1)

{

Delay_ms(1000);

LED1(1);

Delay_ms(500);

LED1(0);

}

}


五、案例使用

5.1 讀取GBK字庫文件(LCD漢字顯示)

產品開發中,如果設備帶有LCD顯示屏,一般會顯示各種文字提示,或者機器操作說明,顯示中文需要字庫,為了方便字模的提取,可以將字庫文件制作好之后放到SD NAND上,通過文件系統打開字庫文件,讀取字模進行顯示。

下面貼出文件系統讀取字模的核心代碼:

/*

函數功能: 顯示GBK字庫數據

u32 x 范圍0~319

u32 y 范圍0~479

u32 size 數據的寬度(必須是8的倍數) 是正方形

u8 *p 中文

說明: 取模橫向坐標必須保證是8的倍數

*/

void ILI9341_DisplayGBKData(u32 x,u32 y,u32 size,u8 *p)

{

FIL fp;

UINT br;

u8 L,H;

u32 Addr;

u16 font_size=size/8*size; //字體占用的點陣碼字節大小

u8 *buff=NULL;

H=*p;

L=*(p+1);

if(L<0x7f)L=L-0x40;

else L=L-0x41;

H=H-0x81;

Addr=(190*H+L)*font_size; //中文在字庫里的偏移量

buff=malloc(font_size); //使用的堆空間

if(buff==NULL)return;

switch(size)

{

case 16:

if(f_open(&fp,"0:/font/gbk16.DZK",FA_READ)!=FR_OK)

{

printf("f_open error.\r\n");

}

f_lseek(&fp,Addr);

f_read(&fp,buff,font_size,&br);

f_close(&fp);

break;

case 24:

f_open(&fp,"0:/font/gbk24.DZK",FA_READ);

f_lseek(&fp,Addr);

f_read(&fp,buff,font_size,&br);

f_close(&fp);

break;

case 32:

break;

}

//顯示中文

ILI9341_DisplayData(x,y,size,size,buff);

//釋放空間

free(buff);

}


這是讀取字模,顯示的效果:


28.png


5.2 讀取MP3文件播放(開機音樂)

這個例子是演示文件系統的目錄掃描函數使用方式,讀取指定目錄下的MP3文件進行播放。

u8 PlayerMP3(const char *path);

FATFS FatFs;

int main()

{

LED_Init();

BEEP_Init();

KeyInit();

USARTx_Init(USART1,72,115200);

SDCardDeviceInit(); //初始化SD卡

// res=f_mkfs("0:",FM_ANY,0,work,sizeof work);

// if(res)printf("格式化失敗!\n");

// else printf("格式化成功!\n");

f_mount(&FatFs, "0:", 0); //注冊工作區

PlayerMP3("0:/MP3");

while(1)

{

DelayMs(100);

LED0=!LED0;

}

}

/*

函數功能: 掃描目錄mp3播放

0表示成功 1表示失敗

*/

u8 PlayerMP3(const char *path)

{

DIR dir;

FRESULT res;

FILINFO fno; //存放讀取的文件信息

char *abs_path=NULL;

/*1. 打開目錄*/

res=f_opendir(&dir,path);

if(res!=FR_OK)return res;

/*2. 循環讀取目錄*/

while(1)

{

res=f_readdir(&dir,&fno);

if(fno.fname[0] == 0 || res!=0)break;

printf("文件名稱: %s,文件大小: %ld 字節\r\n",fno.fname,fno.fsize);

/*過濾目錄*/

if(strstr(fno.fname,".mp3"))

{

//申請存放文件名稱的長度

abs_path=malloc(strlen(path)+strlen(fno.fname)+1);

if(abs_path==NULL)break;

strcpy(abs_path,path);

strcat(abs_path,"/");

strcat(abs_path,fno.fname);

printf("abs_path=%s\n",abs_path);

VS1053_MP3(0,0,abs_path);

free(abs_path);

}

}

/*3. 關閉目錄*/

f_closedir(&dir);

return 0;

}

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • FlaSh
    +關注

    關注

    10

    文章

    1635

    瀏覽量

    148035
  • 閃存芯片
    +關注

    關注

    1

    文章

    120

    瀏覽量

    19619
  • emmc
    +關注

    關注

    7

    文章

    216

    瀏覽量

    52746
收藏 人收藏

    評論

    相關推薦

    關于SD NAND 的概述

    以其卓越的性能、可靠性和小巧的尺寸,受到市場的廣泛關注和應用。   2.CS創世SD NAND的特點   1. 小巧的尺寸:采用6x8mm LGA-8封裝,便于機器
    發表于 12-06 11:22

    SD NAND 概述

    SD NAND是一種小型、可表面貼裝的存儲解決方案,適用于各種嵌入式系統和便攜式設備。SD NAND技術是近年來在存儲領域內的一項創新,它結
    的頭像 發表于 12-06 11:21 ?180次閱讀

    雷龍CS SD NAND貼片式TF體驗與性能測試

    最近有幸獲得了雷龍發展提供的貼片式TF樣品,收到的快遞中包含兩片 CS SD NAND 芯片和一個轉接板。以下是芯片和轉接板的實物照片:
    發表于 11-26 10:04

    Arduino程序:實現SD NAND貼片sd)的讀寫功能

      單片機上傳程序的時候,有時候感覺它的rom和 ram有時直接限制了他的使用,之前使用eeprom,和sd模塊. []()   然后最近看到了出的SD NAND 就是下面這個
    發表于 11-07 17:45

    CS創世 SD NANDSD NAND芯片的測評與使用(基于卷積神經網絡的數字識別)

    通過SD進行系統移植,但一些設計不合理的卡槽經常不能保護SD,反而會損壞折斷。相比之下,
    發表于 07-24 18:24

    貼片SD功能介紹【MK SD NAND

    SDNAND,通常稱為嵌入式SD貼片式TFSD Flash、直接貼裝SD
    的頭像 發表于 07-05 17:03 ?784次閱讀
    <b class='flag-5'>貼片</b>式<b class='flag-5'>SD</b><b class='flag-5'>卡</b>功能介紹【MK <b class='flag-5'>SD</b> <b class='flag-5'>NAND</b>】

    SD NAND文件系統:技術解析與應用指南

    MK米客方德的SD NAND是一種使用NAND閃存技術的貼片式TF,因起耐用性和較小的體積而受到廣泛歡迎。
    的頭像 發表于 06-07 14:45 ?430次閱讀
    <b class='flag-5'>SD</b> <b class='flag-5'>NAND</b>與<b class='flag-5'>文件系統</b>:技術解析與應用指南

    SD NAND 簡介

    SD NAND是一種創新的存儲芯片,可直接貼片,又名貼片式TF貼片式T
    的頭像 發表于 05-29 16:34 ?1210次閱讀
    <b class='flag-5'>SD</b> <b class='flag-5'>NAND</b> 簡介

    NAND Flash(貼片式TF)存儲新突破,基礎示例

    with FatFs \\\\r\\\\nSTM32FATFS文件系統測試\\\\r\\\\n \"; // 在外部
    發表于 05-21 17:13

    STM32F412使用SD,SDIO,FATFS系統SD掛載文件系統失敗的原因?

    求助,STM32F412RET6 使用SD,使用SDIO接口,FATFS系統SD
    發表于 04-11 07:15

    【嵌入式SD NAND】基于FATFS/Littlefs文件系統的日志框架實現

    `deinit`3.5全部代碼匯總4.測試5.總結1.概述那么在移植好了文件系統之后,我們又應該如何應用文件系統呢?很多人會說,這個簡單,就操作文件
    的頭像 發表于 03-14 18:12 ?1161次閱讀
    【嵌入式<b class='flag-5'>SD</b> <b class='flag-5'>NAND</b>】基于<b class='flag-5'>FATFS</b>/Littlefs<b class='flag-5'>文件系統</b>的日志框架實現

    CS 創世SD NAND FLASH 存儲芯片,比TF更小巧輕便易用的大容量存儲,TF替代方案

    ,符合標準SD2.0協議,且外形尺寸為8.5mm x 7mm。   CS創世SD NAND也被許多開發者朋友稱為
    發表于 01-24 18:30

    stm32 CubeMx 怎么實現SD/sd nand FATFS讀寫測試

    本實驗僅用于記錄和分享技術經驗若涉及侵權請聯系我刪除。   stm32 CubeMx 實現SD/sd nand
    發表于 01-09 17:37

    什么是SD NAND存儲芯片? SD NAND與TF的區別

    什么是SD NAND?它俗稱貼片式T貼片式TF貼片
    的頭像 發表于 01-06 14:35 ?1793次閱讀
    什么是<b class='flag-5'>SD</b> <b class='flag-5'>NAND</b>存儲芯片? <b class='flag-5'>SD</b> <b class='flag-5'>NAND</b>與TF<b class='flag-5'>卡</b>的區別

    什么是SD NAND存儲芯片?

    前言   大家好,我們一般在STM32項目開發中或者在其他嵌入式開發中,經常會用到存儲芯片存儲數據。今天我和大家來介紹一款存儲芯片,我這里采用(雷龍) CS創世 SD
    發表于 01-05 17:54
    主站蜘蛛池模板: 亚洲男人的天堂久久香蕉| 爱爱456高清国语在线456| 免费不卡毛片| 国产在线小视频| 人人揉揉香蕉大青草| 性做久久久久久久| 亚洲宅男天堂a在线| 亚洲美女黄视频| 五月婷花| 欧美人与禽| 成色网| 手机亚洲第一页| 日本与大黑人xxxx| 亚洲国产精品婷婷久久| 欧美午夜电影| 丁香综合五月| 久久天天躁狠狠躁夜夜爽| 中文字幕一二三区乱码老| 亚洲精品成人在线| 国产精品高清一区二区三区| 色依依视频视频在线观看| 黄色在线| 亚洲电影在线| 成人网视频免费播放| 欧美交片| 天天怕夜夜怕狠狠怕| 九九久久国产精品大片| 五月天婷婷在线播放| 欧美中出在线| 日毛片| 夜夜夜操| 男人搡女人视频免费看| 色多多网址| 日日夜夜天天干干| 亚洲一区二区电影| 99精品免费视频| 视频在线播放免费| 日本成人免费观看| 午夜爽爽性刺激一区二区视频| 四虎影视永久在线 yin56xyz | 狠狠色噜噜狠狠狠狠米奇777|