RM新时代网站-首页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

基于STM32完成FATFS文件系統(tǒng)移植與運(yùn)用

DS小龍哥-嵌入式技術(shù) ? 來源:DS小龍哥-嵌入式技術(shù) ? 作者:DS小龍哥-嵌入式技 ? 2022-03-08 09:17 ? 次閱讀

?

一、環(huán)境介紹

主控MCU: STM32F103ZET6

STM32程序開發(fā)IDE: keil5

STM32程序風(fēng)格: 采用寄存器方式開發(fā),注釋齊全,執(zhí)行效率高,方便移植

硬件包含: 一塊STM32F103ZET6系統(tǒng)板、一個(gè)SPI接口SD卡卡槽模塊、一張SD卡

這篇文章主要演示FATFS文件系統(tǒng)如何移植到自己的工程,并完成文件的讀寫。

因?yàn)镾D卡采用的是SPI模擬時(shí)序,所以,其他單片機(jī)一樣可以照著移植,代碼都可以復(fù)制粘貼的。

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

二、FATFS文件系統(tǒng)介紹

2.1 FATFS簡介

FatFs 是一種完全免費(fèi)開源的 FAT 文件系統(tǒng)模塊,專門為小型的嵌入式系統(tǒng)而設(shè)計(jì)。它完全用標(biāo)準(zhǔn)C 語言編寫,所以具有良好的硬件平臺(tái)獨(dú)立性,可以移植到 8051、 PIC、 AVR、 SH、 Z80、 H8、 ARM 等系列單片機(jī)上而只需做簡單的修改。它支持 FATl2、 FATl6 和 FAT32,支持多個(gè)存儲(chǔ)媒介;有獨(dú)立的緩沖區(qū),可以對多個(gè)文件進(jìn)行讀/寫,并特別對 8 位單片機(jī)和 16 位單片機(jī)做了優(yōu)化。

2.2 特點(diǎn)

  1. Windows兼容的FAT文件系統(tǒng)
  2. 不依賴于平臺(tái),易于移植
  3. 代碼和工作區(qū)占用空間非常小
  4. 多種配置選項(xiàng)
  5. 多卷(物理驅(qū)動(dòng)器和分區(qū))
  6. 多ANSI/OEM代碼頁,包括DBCS
  7. 在ANSI/OEM或Unicode中長文件名的支持
  8. RTOS的支持
  9. 多扇區(qū)大小的支持
  10. 只讀,最少API,I/O緩沖區(qū)等等

2.3 移植性

fatfs模塊是ANSI C(C89)編寫的。 沒有平臺(tái)的依賴, 編譯器只要符合ANSI C標(biāo)準(zhǔn)就可以編譯。

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

2.4 源碼下載

FATFS文件系統(tǒng)官網(wǎng)下載地址:http://elm-chan.org/fsw/ff/00index_e.html

這是在STM32上移植好的工程,可以直接下載使用,這個(gè)只要是STM32F103系列的所以芯片都可以使用工程:https://download.csdn.net/download/xiaolong1126626497/19687693

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

?

FATFS有兩個(gè)版本,一個(gè)大版本,一個(gè)小版本。小版本主要用于8位機(jī)(內(nèi)存小)使用。

下載圖:

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

?

2.5 FATFS源碼文件介紹

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

其中,與平臺(tái)無關(guān)的是:

ffconf.h FATFS配置文件

ff.h 應(yīng)用層頭文件

ff.c 應(yīng)用層源文件

diskio.h 硬件層頭文件

interger.h 數(shù)據(jù)類型定義頭文件

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

與平臺(tái)相關(guān)的代碼:

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

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

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

FATFS最頂層是應(yīng)用層,使用者無需理會(huì) FATFS 的內(nèi)部結(jié)構(gòu)和復(fù)雜的 FAT 協(xié)議,只需要調(diào)用FATFS 模塊提供給用戶的一系列應(yīng)用接口函數(shù),如 f_open, f_read, f_write 和 f_close 等,就可以像在 PC 上讀/寫文件那樣簡單。

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

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

三、 移植FATFS文件系統(tǒng)

移植之前,首先得準(zhǔn)備一個(gè)能正常編譯的工程,并且工程里有SD卡的驅(qū)動(dòng)代碼,提供了讀寫扇區(qū)這些函數(shù)才能進(jìn)行FATFS文件系統(tǒng)的正常移植。

關(guān)于如何編寫SD卡驅(qū)動(dòng),SD卡的時(shí)序介紹、命令介紹等知識(shí)點(diǎn)下篇文章再講解。這篇文章重點(diǎn)是FATFS文件系統(tǒng)的移植過程。

3.1 新建工程

FATFS文件系統(tǒng)源碼下載下來,解壓之后,移植修改的步驟如下:

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

?

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

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

?

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

3.2 修改diskio.c文件

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

?

注釋掉現(xiàn)在不需要的用到的文件,因?yàn)槲覀儸F(xiàn)在用的是SD卡,與USB,ATA,MMC卡沒關(guān)系。

并加入一個(gè)新的宏 :

#define SD 0

定義SD卡的物理驅(qū)動(dòng)器號(hào)為0。

修改 disk_status函數(shù),該函數(shù)主要是用來獲取磁盤狀態(tài)?,F(xiàn)在未用到,可以直接函數(shù)體內(nèi)代碼刪除。

修改截圖:

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

?

代碼示例:

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

#include "sd.h" /* SD卡驅(qū)動(dòng)頭文件 */

/* 定義每個(gè)驅(qū)動(dòng)器的物理驅(qū)動(dòng)器號(hào)*/

#define SD 0

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

/* 獲取設(shè)備(磁盤)狀態(tài) */

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

DSTATUS disk_status (

BYTE pdrv /* 物理驅(qū)動(dòng)識(shí)別 */

)

{

return 0; //該函數(shù)現(xiàn)在無需用到,直接返回0

}

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

修改截圖:

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

?

代碼示例:

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

/* 初始化磁盤驅(qū)動(dòng) */

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

DSTATUS disk_initialize (

BYTE pdrv /* 物理驅(qū)動(dòng)識(shí)別 */

)

{

DSTATUS stat;

int result;

switch (pdrv) {

case SD : //選擇SD卡

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

}

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

return 0; //初始化成功

}

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

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

?

修改代碼如下:

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

/* 讀扇區(qū) */

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

DRESULT disk_read (

BYTE pdrv, /* 物理驅(qū)動(dòng)編號(hào) - 范圍0-9*/

BYTE *buff, /* 數(shù)據(jù)緩沖區(qū)存儲(chǔ)讀取數(shù)據(jù) */

DWORD sector, /* 扇區(qū)地址*/

UINT count /* 需要讀取的扇區(qū)數(shù)*/

)

{

DRESULT res;

int result;

switch (pdrv) {

case SD:

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

return res; //在此處可以判錯(cuò)誤

}

return RES_PARERR; //無效參數(shù)

}

修改disk_write 函數(shù),添加寫扇區(qū)函數(shù):

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

?

代碼:

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

/* 寫扇區(qū) */

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

#if _USE_WRITE

DRESULT disk_write (

BYTE pdrv, /* 物理驅(qū)動(dòng)號(hào)*/

const BYTE *buff, /* 要寫入數(shù)據(jù)的首地址 */

DWORD sector, /* 扇區(qū)地址 */

UINT count /* 扇區(qū)數(shù)量*/

)

{

DRESULT res;

int result;

switch (pdrv) {

case SD:

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

return res;

}

return RES_PARERR; //無效參數(shù)

}

#endif

修改disk_ioctl 函數(shù),填充ioctl命令功能。這些功能是標(biāo)準(zhǔn)的命令,在diskio.h有定義。

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

?

代碼如下:

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

/* 其他函數(shù) */

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

#if _USE_IOCTL

DRESULT disk_ioctl (

BYTE pdrv, /* 物理驅(qū)動(dòng)號(hào) */

BYTE cmd, /* 控制碼 */

void *buff /* 發(fā)送/接收數(shù)據(jù)緩沖區(qū)地址 */

)

{

DRESULT res;

int result;

switch (pdrv) {

case SD:

switch(cmd)

{

case CTRL_SYNC: //等待寫過程

SD_CS(0); //選中SD卡

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

else res = RES_OK; //成功

SD_CS(1); //釋放SD卡

break;

case GET_SECTOR_SIZE://獲取扇區(qū)大小

*(DWORD*)buff = 512;

res = RES_OK; //成功

break;

case GET_BLOCK_SIZE: //獲取塊大小

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

res = RES_OK;

break;

case GET_SECTOR_COUNT: //獲取總扇區(qū)數(shù)量

*(DWORD*)buff = SD_Get_Sector_Count();

res = RES_OK;

break;

default: //命令錯(cuò)誤

res = RES_PARERR;

break;

}

return res;

}

return RES_PARERR; //返回狀態(tài)

}

diskio.c 文件修改完整代碼:

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

/*低級別磁盤I / O模塊框架fatf(C)ChaN)2014

*存儲(chǔ)控制模塊fatf模塊定義了一個(gè)API。 */

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

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

#include "sd.h" /* SD卡驅(qū)動(dòng)頭文件 */

/* 定義每個(gè)驅(qū)動(dòng)器的物理驅(qū)動(dòng)器號(hào)*/

#define SD 0

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

/* 獲取設(shè)備(磁盤)狀態(tài) */

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

DSTATUS disk_status (

BYTE pdrv /* 物理驅(qū)動(dòng)識(shí)別 */

)

{

return 0; //該函數(shù)現(xiàn)在無需用到,直接返回0

}

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

/* 初始化磁盤驅(qū)動(dòng) */

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

DSTATUS disk_initialize (

BYTE pdrv /* 物理驅(qū)動(dòng)識(shí)別 */

)

{

DSTATUS stat;

int result;

switch (pdrv) {

case SD : //選擇SD卡

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

}

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

return 0; //初始化成功

}

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

/* 讀扇區(qū) */

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

DRESULT disk_read (

BYTE pdrv, /* 物理驅(qū)動(dòng)編號(hào) - 范圍0-9*/

BYTE *buff, /* 數(shù)據(jù)緩沖區(qū)存儲(chǔ)讀取數(shù)據(jù) */

DWORD sector, /* 扇區(qū)地址*/

UINT count /* 需要讀取的扇區(qū)數(shù)*/

)

{

DRESULT res;

int result;

switch (pdrv) {

case SD:

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

return res; //在此處可以判錯(cuò)誤

}

return RES_PARERR; //無效參數(shù)

}

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

/* 寫扇區(qū) */

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

#if _USE_WRITE

DRESULT disk_write (

BYTE pdrv, /* 物理驅(qū)動(dòng)號(hào)*/

const BYTE *buff, /* 要寫入數(shù)據(jù)的首地址 */

DWORD sector, /* 扇區(qū)地址 */

UINT count /* 扇區(qū)數(shù)量*/

)

{

DRESULT res;

int result;

switch (pdrv) {

case SD:

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

return res;

}

return RES_PARERR; //無效參數(shù)

}

#endif

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

/* 其他函數(shù) */

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

#if _USE_IOCTL

DRESULT disk_ioctl (

BYTE pdrv, /* 物理驅(qū)動(dòng)號(hào) */

BYTE cmd, /* 控制碼 */

void *buff /* 發(fā)送/接收數(shù)據(jù)緩沖區(qū)地址 */

)

{

DRESULT res;

int result;

switch (pdrv) {

case SD:

switch(cmd)

{

case CTRL_SYNC: //等待寫過程

SD_CS(0); //選中SD卡

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

else res = RES_OK; //成功

SD_CS(1); //釋放SD卡

break;

case GET_SECTOR_SIZE://獲取扇區(qū)大小

*(DWORD*)buff = 512;

res = RES_OK; //成功

break;

case GET_BLOCK_SIZE: //獲取塊大小

*(WORD*)buff = 8; //塊大小--一塊等于8個(gè)扇區(qū)

res = RES_OK;

break;

case GET_SECTOR_COUNT: //獲取總扇區(qū)數(shù)量

*(DWORD*)buff = SD_Get_Sector_Count();

res = RES_OK;

break;

default: //命令錯(cuò)誤

res = RES_PARERR;

break;

}

return res;

}

return RES_PARERR; //返回狀態(tài)

}

#endif

//返回FATFS時(shí)間

//獲得時(shí)間

DWORD get_fattime (void)

{

return (DWORD)(2017-1980)<<25|??? //年

7<<21|??? //月

27<<16|??? //日

12<<11|??? //時(shí)

13<<5|??? //分

14; //秒

}

/*

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)

*/

3.3修改ffconf.h文件

需要注意的一些宏配置:

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

#define _USE_LFN 3 //動(dòng)態(tài)的堆上工作 (93行)

#define _MAX_LFN 255 /*_USE_LFN選項(xiàng)開關(guān)LFN(長文件名)特性。

#define _VOLUMES 1 /* 支持的磁盤數(shù)量(邏輯驅(qū)動(dòng)器)。 */ (142行)

#define _MIN_SS 512 (165行)

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

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

#define _NORTC_MON 1

#define _NORTC_MDAY 1

#define _NORTC_YEAR 2015 //年

/*需要實(shí)現(xiàn):get_fattime()函數(shù)*/

ffconf.h 文件源碼(講解):

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

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

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

#define _FFCONF 64180 /* 版本識(shí)別*/

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

/ 功能配置

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

#define _FS_READONLY 0

/* 這個(gè)選項(xiàng)開關(guān)只讀配置。(0:讀/寫或1:只讀)

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

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

/寫和可選的功能. */

#define _FS_MINIMIZE 0

/*此選項(xiàng)定義刪除一些基本的API函數(shù)極小化水平。

/

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

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

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

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

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

#define _USE_STRFUNC 1

/*這個(gè)選項(xiàng)開關(guān)字符串函數(shù),f_gets(),f_putc(),f_puts()和

/ f_printf()。

/

/ 0:禁用字符串函數(shù)。

/ 1:啟用沒有LF-CRLF轉(zhuǎn)換。

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

#define _USE_FIND 0

/*這個(gè)選項(xiàng)開關(guān)過濾目錄讀取特性和相關(guān)功能,

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

#define _USE_MKFS 1

/* 這個(gè)選項(xiàng)開關(guān)f_mkfs()函數(shù)。(0:禁用或1:啟用) */

#define _USE_FASTSEEK 1

/* 這個(gè)選項(xiàng)開關(guān)快速尋求功能。(0:禁用或1:啟用) */

#define _USE_LABEL 1

/* 磁盤卷標(biāo)這個(gè)選項(xiàng)開關(guān)功能,f_getlabel()和f_setlabel()。

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

#define _USE_FORWARD 0

/* 這個(gè)選項(xiàng)開關(guān)f_forward()函數(shù)。(0:禁用或1:啟用)

/啟用它,也_FS_TINY需要設(shè)置為1. */

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

/ 語言環(huán)境和名稱空間配置

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

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

/*這個(gè)選項(xiàng)指定OEM代碼頁在目標(biāo)系統(tǒng)上使用。

/不正確的代碼頁的設(shè)置會(huì)導(dǎo)致文件打開失敗.

/

/ 1 - ASCII (沒有擴(kuò)展字符。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 //動(dòng)態(tài)的堆上工作

#define _MAX_LFN 255

/*_USE_LFN選項(xiàng)開關(guān)LFN(長文件名)特性。

/

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

/ 1:啟用LFN BSS靜態(tài)工作緩沖區(qū)??偸遣皇蔷€程安全的。

/ 2:啟用LFN與動(dòng)態(tài)緩沖棧上的工作。

/ 3:使LFN與動(dòng)態(tài)緩沖區(qū)在堆上工作。

/

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

/被添加到項(xiàng)目中。LFN工作緩沖區(qū)占用(_MAX_LFN + 1)* 2字節(jié)。

/當(dāng)使用堆棧緩沖區(qū),照顧堆棧溢出。當(dāng)使用堆

/工作緩沖區(qū)內(nèi)存,內(nèi)存管理功能,ff_memalloc()和

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

#define _LFN_UNICODE 0

/* 這個(gè)選項(xiàng)開關(guān)字符編碼的API。(0:ANSI / OEM或1:Unicode)

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

/1。這個(gè)選項(xiàng)也會(huì)影響行為的字符串的I / O功能。

*/

#define _STRF_ENCODE 3

/* 當(dāng)_LFN(長文件名)_UNICODE是1,這個(gè)選項(xiàng)選擇文件的字符編碼

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

/

/ 0: ANSI/OEM

/ 1: UTF-16LE

/ 2: UTF-16BE

/ 3: UTF-8

/

/ 當(dāng)_LFN_UNICODE = 0時(shí),該選項(xiàng)沒有影響。*/

#define _FS_RPATH 0

/*這個(gè)選項(xiàng)配置相對路徑的功能。/

/ 0:禁用相對路徑特性和刪除相關(guān)功能。

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

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

/注意,目錄項(xiàng)讀通過f_readdir()這個(gè)選項(xiàng)。

*/

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

/ 驅(qū)動(dòng)/卷配置

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

#define _VOLUMES 1

/* 支持的磁盤數(shù)量(邏輯驅(qū)動(dòng)器)。 */

#define _STR_VOLUME_ID 0

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

/* STR_VOLUME_ID選項(xiàng)開關(guān)卷ID字符串功能。

/當(dāng)_STR_VOLUME_ID設(shè)置為1時(shí),也可以使用預(yù)先定義的字符串在路徑名稱/數(shù)量。

為每個(gè)_VOLUME_STRS定義驅(qū)動(dòng)ID字符串

/邏輯驅(qū)動(dòng)器。條目的數(shù)量必須等于_VOLUMES。有效字符

/驅(qū)動(dòng)ID字符串:a - z和0 - 9。*/

#define _MULTI_PARTITION 0

/* 這個(gè)選項(xiàng)開關(guān)多分區(qū)的特性。在默認(rèn)情況下(0),每個(gè)邏輯驅(qū)動(dòng)器

/號(hào)綁定到相同的物理驅(qū)動(dòng)器號(hào)

/物理驅(qū)動(dòng)器將被安裝。當(dāng)啟用分區(qū)特性(1),

/每個(gè)邏輯驅(qū)動(dòng)器號(hào)是綁定到任意物理驅(qū)動(dòng)器和分區(qū)

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

#define _MIN_SS 512

#define _MAX_SS 512

/* 這些選項(xiàng)配置支持扇區(qū)大小的范圍。(512,1024,

/ 2048或4096)總是為大多數(shù)系統(tǒng)設(shè)置兩個(gè)512,卡和所有類型的內(nèi)存

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

/類型的光學(xué)媒體。當(dāng)_MAX_SS大于_MIN_SS,fatf配置

/變量扇區(qū)大小和GET_SECTOR_SIZE命令必須執(zhí)行disk_ioctl()函數(shù). */

#define _USE_TRIM 0

/* 這個(gè)選項(xiàng)開關(guān)ATA-TRIM特性。(0:禁用或1:啟用)

/啟用削減特性,也應(yīng)該實(shí)現(xiàn)CTRL_TRIM命令

/ disk_ioctl()函數(shù)。*/

#define _FS_NOFSINFO 0

/*

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

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

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

/ bit0 = 0:使用免費(fèi)的集群計(jì)算FSINFO如果可用。

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

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

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

*/

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

/ 系統(tǒng)配置列表

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

#define _FS_TINY 0

/* 這個(gè)選項(xiàng)開關(guān)小緩沖區(qū)配置。(0:正?;?:小)

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

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

/數(shù)據(jù)傳輸. */

#define _FS_NORTC 0

#define _NORTC_MON 1

#define _NORTC_MDAY 1

#define _NORTC_YEAR 2015 //年

/* _FS_NORTC選項(xiàng)開關(guān)時(shí)間戳的特性。如果系統(tǒng)沒有/

RTC函數(shù)或不需要有效的時(shí)間戳,_FS_NORTC 1設(shè)置為禁用/

時(shí)間戳的特性。所有對象修改fatf將有一個(gè)固定的時(shí)間戳。/

固定的時(shí)間定義為_NORTC_MON _NORTC_MDAY _NORTC_YEAR。

/當(dāng)啟用時(shí)間戳特性(_FS_NORTC = = 0),需要實(shí)現(xiàn)get_fattime()函數(shù)。/

添加到項(xiàng)目RTC讀當(dāng)前時(shí)間形式。_NORTC_MON, /

_NORTC_MDAY和_NORTC_YEAR沒有效果。

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

#define _FS_LOCK 0

/* _FS_LOCK選項(xiàng)開關(guān)控制復(fù)制的文件打開的文件鎖定功能

/和非法操作打開對象。這個(gè)選項(xiàng)_FS_READONLY時(shí)必須是0

/是1。/

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

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

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

可以同時(shí)打開的/文件鎖的控制之下。注意,這個(gè)文件獨(dú)立于re-entrancy /鎖功能。 */

#define _FS_REENTRANT 0

#define _FS_TIMEOUT 1000

#define _SYNC_t HANDLE

/* _FS_REENTRANT選項(xiàng)開關(guān)re-entrancy fatf的(線程安全)

/模塊本身。注意,不管這個(gè)選項(xiàng),文件訪問不同

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

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

/相同的體積是這個(gè)功能的控制。

/

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

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

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

/函數(shù),必須添加到項(xiàng)目中。樣品中可用

/選項(xiàng)

/ syscall.c。

/

/ _FS_TIMEOUT定義超時(shí)時(shí)間單位的滴答聲。

/ _SYNC_t定義了O

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

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

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

#define _WORD_ACCESS 0

/* _WORD_ACCESS選項(xiàng)是一個(gè)只有依賴于平臺(tái)的選擇。

它定義了這個(gè)詞/訪問方法是用來體積上的數(shù)據(jù)。

/

/ 0:逐字節(jié)的訪問。總是兼容所有平臺(tái)。

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

/

/ *地址對齊內(nèi)存訪問總是允許所有指令。

/ *字節(jié)順序的記憶是低位優(yōu)先。

/

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

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

/

/ 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:高位優(yōu)先。/

* 2:不支持不連續(xù)的內(nèi)存訪問。/

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

*/

3.4實(shí)現(xiàn)動(dòng)態(tài)內(nèi)存分配函數(shù)與時(shí)間函數(shù)

ff.h文件有動(dòng)態(tài)內(nèi)存的釋放,動(dòng)態(tài)內(nèi)存申請,時(shí)間獲取函數(shù)接口。

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

?

在diskio.c文件實(shí)現(xiàn)函數(shù)功能:

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

?

代碼實(shí)現(xiàn)如下:

//動(dòng)態(tài)內(nèi)存分配

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

{

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

}

//動(dòng)態(tài)內(nèi)存釋放

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

{

free(mblock); //釋放空間

}

//返回FATFS時(shí)間

//獲得時(shí)間

DWORD get_fattime (void)

{

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

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

RTC_Timer.month<<21|? //月

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

RTC_Timer.hour<<11|?? //時(shí)

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)

*/

3.5 修改堆??臻g

完成了上述的修改,還需要修改堆??臻g,因?yàn)殚L文件支持需要占用堆空間。

修改STM32啟動(dòng)文件如下:

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

?

3.6編譯工程測試

修改完畢之后,給開發(fā)板插上SD卡,調(diào)用API函數(shù)在SD卡創(chuàng)建一個(gè)文件,并寫入數(shù)據(jù),測試是否成功:

#include "ff.h"

FATFS fs; // 用戶定義的文件系統(tǒng)結(jié)構(gòu)體

FIL file; // 用戶定義的文件系統(tǒng)結(jié)構(gòu)體

u8 buff[]="123 知識(shí)?。?;

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時(shí)鐘初始化

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

{

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); // 注冊工作區(qū),驅(qū)動(dòng)器號(hào) 0,初始化后其他函數(shù)可使用里面的參數(shù)

printf("注冊工作區(qū)!\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("文件創(chuàng)建成功??!\n");

}

else

{

printf("文件創(chuàng)建失敗??!\n");

}

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

if(res==0)

{

printf("數(shù)據(jù)寫入成功??!\n");

}

else

{

printf("數(shù)據(jù)寫入失?。?!\n");

}

printf("成功寫入%d字節(jié)數(shù)據(jù)\n",data);

f_close(&file); //關(guān)閉文件

//_FS_RPATH

while(1)

{

Delay_ms(1000);

LED1(1);

Delay_ms(500);

LED1(0);

}

}


?

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • STM32
    +關(guān)注

    關(guān)注

    2270

    文章

    10895

    瀏覽量

    355729
  • SPI
    SPI
    +關(guān)注

    關(guān)注

    17

    文章

    1706

    瀏覽量

    91502
  • FATFS
    +關(guān)注

    關(guān)注

    0

    文章

    44

    瀏覽量

    18298
  • keil5
    +關(guān)注

    關(guān)注

    6

    文章

    44

    瀏覽量

    20661
  • 系統(tǒng)移植
    +關(guān)注

    關(guān)注

    0

    文章

    16

    瀏覽量

    4823
收藏 人收藏

    評論

    相關(guān)推薦

    FatFS文件系統(tǒng)STM32F4上的移植和應(yīng)用

    在實(shí)現(xiàn)如U盤文件讀寫,SD卡的文件讀寫等工作時(shí),我們往往需要一個(gè)文件系統(tǒng)來支持我們的工作。特別在一些MCU應(yīng)用中,文件系統(tǒng)的加入能明顯改善系統(tǒng)
    的頭像 發(fā)表于 12-13 17:26 ?2625次閱讀
    <b class='flag-5'>FatFS</b><b class='flag-5'>文件系統(tǒng)</b>在<b class='flag-5'>STM32</b>F4上的<b class='flag-5'>移植</b>和應(yīng)用

    STM32CubeMx入門教程(10):Fatfs文件系統(tǒng)的應(yīng)用

    導(dǎo)語"fatfs是一個(gè)小型的文件系統(tǒng),在小型的嵌入式系統(tǒng)中使用非常的廣泛,STM32CubeMx自帶該文件系統(tǒng),我們通過簡單的配置就能夠使用
    發(fā)表于 07-12 11:39 ?5347次閱讀
    <b class='flag-5'>STM32</b>CubeMx入門教程(10):<b class='flag-5'>Fatfs</b><b class='flag-5'>文件系統(tǒng)</b>的應(yīng)用

    STM32+SD NAND(貼片SD卡)完成FATFS文件系統(tǒng)移植與測試

    這篇文章就手把手教大家,在STM32完成FATFS文件系統(tǒng)移植;主控芯片采用STM32F10
    的頭像 發(fā)表于 07-17 17:24 ?7550次閱讀
    <b class='flag-5'>STM32</b>+SD NAND(貼片SD卡)<b class='flag-5'>完成</b><b class='flag-5'>FATFS</b><b class='flag-5'>文件系統(tǒng)</b><b class='flag-5'>移植</b>與測試

    FATFS文件系統(tǒng)移植

    這是本人,整理的FATFS文件系統(tǒng)移植資料,很少的一部分,希望大家把自己搜到的比較好的資料,分享一下,本人正在學(xué)習(xí)fatfs文件系統(tǒng),希望和
    發(fā)表于 09-11 16:05

    FATFS文件系統(tǒng)如何移植工程

    STM32F103ZET6系統(tǒng)板、一個(gè)SPI接口的SD卡卡槽模塊、一張SD卡工程完整源碼下載地址這篇文章主要演示FATFS文件系統(tǒng)如何移植
    發(fā)表于 08-24 06:34

    FatFs文件系統(tǒng)的原理是什么?如何對FATFS進(jìn)行移植?

    FatFs文件系統(tǒng)的原理是什么?FatFs文件系統(tǒng)移植方法是什么?如何實(shí)現(xiàn)eMMC卡中文件的讀
    發(fā)表于 11-25 07:52

    【技術(shù)精選】嵌入式STM32原創(chuàng)征文活動(dòng)精選文章

    總線、W25Q64(FLASH)的詳細(xì)介紹STM32: 介紹IIC總線、讀寫AT24C02(模擬時(shí)序)STM32F103實(shí)現(xiàn)IAP在線升級應(yīng)用程序基于STM32完成
    發(fā)表于 07-27 18:26

    stm32+sdio+fatfs文件系統(tǒng)_源碼分析

    stm32+sdio+fatfs文件系統(tǒng)介紹,通俗易懂。
    發(fā)表于 11-06 09:52 ?25次下載

    FatFs文件系統(tǒng)使用

    STM系列FatFs文件系統(tǒng)使用文件,希望對大家有幫助。
    發(fā)表于 11-06 18:10 ?8次下載

    MSP430、STM32、8051單片機(jī)fatfs 文件系統(tǒng)移植 W25Q128

    MSP430、STM32、8051單片機(jī)fatfs 文件系統(tǒng)移植 W25Q128
    發(fā)表于 11-15 16:21 ?36次下載
    MSP430、<b class='flag-5'>STM32</b>、8051單片機(jī)<b class='flag-5'>fatfs</b> <b class='flag-5'>文件系統(tǒng)</b><b class='flag-5'>移植</b> W25Q128

    Fatfs文件系統(tǒng)移植

    Fatfs文件系統(tǒng)移植)一、文件系統(tǒng)介紹二、移植條件、說明1、FatFs模塊在可
    發(fā)表于 11-15 18:51 ?22次下載
    <b class='flag-5'>Fatfs</b>(<b class='flag-5'>文件系統(tǒng)</b>的<b class='flag-5'>移植</b>)

    文件系統(tǒng)FatFs文件系統(tǒng)在嵌入式芯片LPC18XX上的移植

    文件系統(tǒng)FatFs文件系統(tǒng)在嵌入式芯片LPC18XX上的移植
    發(fā)表于 12-04 10:51 ?12次下載
    【<b class='flag-5'>文件系統(tǒng)</b>】<b class='flag-5'>FatFs</b><b class='flag-5'>文件系統(tǒng)</b>在嵌入式芯片LPC18XX上的<b class='flag-5'>移植</b>

    手把手教你在flash上移植fatfs文件系統(tǒng)(含實(shí)時(shí)操作系統(tǒng))

    文章目錄基于stm32f103系列MCU,在spi_flash上移植建立fatfs文件系統(tǒng)移植準(zhǔn)備FAT
    發(fā)表于 12-09 12:51 ?30次下載
    手把手教你在flash上<b class='flag-5'>移植</b><b class='flag-5'>fatfs</b><b class='flag-5'>文件系統(tǒng)</b>(含實(shí)時(shí)操作<b class='flag-5'>系統(tǒng)</b>)

    文件系統(tǒng)FatFs移植

    FATFS是一個(gè)完全免費(fèi)開源的FAT文件系統(tǒng)模塊,專門為小型的嵌入式系統(tǒng)而設(shè)計(jì)。它完全用標(biāo)準(zhǔn)C語言編寫,所以具有良好的硬件平臺(tái)獨(dú)立性,甚至可以移植到8位的單片機(jī)上而只需做簡單的修改。
    的頭像 發(fā)表于 03-01 14:38 ?1940次閱讀
    <b class='flag-5'>文件系統(tǒng)</b><b class='flag-5'>FatFs</b>的<b class='flag-5'>移植</b>

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

    四、移植FATFS文件系統(tǒng)前面第3章,完成了SDNAND的驅(qū)動(dòng)代碼編寫,這一章節(jié)實(shí)現(xiàn)FATFS文件
    的頭像 發(fā)表于 03-03 13:52 ?1330次閱讀
    基于<b class='flag-5'>STM32</b>+CS創(chuàng)世 SD NAND(貼片SD卡)<b class='flag-5'>完成</b><b class='flag-5'>FATFS</b><b class='flag-5'>文件系統(tǒng)</b><b class='flag-5'>移植</b>與測試(下篇)
    RM新时代网站-首页