日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > windows >内容正文

windows

基于SD卡的FatFs文件系统(FatFs移植到STM32)

發(fā)布時(shí)間:2025/4/5 windows 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于SD卡的FatFs文件系统(FatFs移植到STM32) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

平臺(tái):STM32ZET6(核心板)+ST-LINK/V2+SD卡+USB串口線

工程介紹:主要文件在USER組中,bsp_sdio_sdcard.c,bsp_sdio_sdcard.h和main.c,另外FatFs是用來后面移植文件系統(tǒng)使用的,對(duì)于本節(jié)內(nèi)容暫時(shí)不需要。bsp_sdio_sdcard.c和bsp_sdio_sdcard.h文件主要參考教材《STM32庫(kù)開發(fā)實(shí)戰(zhàn)指南——基于STM32F03》。另外就是本教材用到的FatFs系統(tǒng)源代碼,這里溫馨提示一下,關(guān)于FatFs目前網(wǎng)上筆者找到的最新版的參考資料不是太多,所以筆者在用最新版做的時(shí)候,一些函數(shù)原型發(fā)生了變化,雖然變化不大,也給我造成了一定的阻礙,所以建議大家下載稍微老一點(diǎn)的版本,這樣資料較多,出問題好解決,我最終用的版本是R0.09,因?yàn)樵谑褂煤瘮?shù)f_mkfs()的過程中遇到問題,無法格式化SD卡,最終選擇較老的版本。本文有些內(nèi)容來自于其他網(wǎng)友總結(jié),在此表示感謝。

整體的項(xiàng)目和上一節(jié)中的SDIO讀寫SD卡類似,細(xì)節(jié)上在添加了FatFs組,專門存放FatFs移植的內(nèi)容。對(duì)于移植過程,就是對(duì)diskio.c文件的修改的過程。這個(gè)文件完成了與底層有多的操作,我們只需要實(shí)現(xiàn)一下函數(shù)即可,不同的平臺(tái)函數(shù)實(shí)現(xiàn)略有不同,但是提供給用戶最終的接口是相同的,也正是因?yàn)檫@一點(diǎn),使得FatFs文件系統(tǒng)有了很好的可移植性。

再次申明一下,FatFs文件系統(tǒng)與存儲(chǔ)設(shè)備的接口函數(shù)再diskio.c文件中,我們只需要完善該文件即可。這也就是所謂的軟件移植裁剪過程吧。我們需要完善五個(gè)函數(shù)disk_status,disk_initialize,disk_read,disk_write,disk_ioctl等,還有一個(gè)獲取時(shí)間戳的函數(shù),可以直接return 0;

1.宏定義


#define SD_CARD?? ? 0 ?//SD卡,卷標(biāo)為0
#define EX_FLASH 1?? ?//外部flash,卷標(biāo)為1,為以后外部Flash擴(kuò)展預(yù)留的
?
#define SD_BLOCKSIZE 512
?
//聲明外部變量
extern SD_CardInfo SDCardInfo;
2.dis_status 獲取磁盤的狀態(tài)

//獲得磁盤狀態(tài)
DSTATUS disk_status (
?? ?BYTE pdrv?? ??? ?/* Physical drive nmuber to identify the drive */
)
{
?? ?DSTATUS status = STA_NOINIT;
?? ?switch(pdrv)
?? ?{
?? ??? ?case SD_CARD://SD卡
?? ??? ??? ?status &= ~STA_NOINIT;
? ?? ??? ?break;
?? ??? ?case EX_FLASH://外部flash
??? ??? ??? ?break;
?? ??? ?default:
?? ??? ??? ?status = STA_NOINIT;
?? ??? ??? ?break;
?? ?}
?? ?return status;
} ?
3. disk_initialize 初始化磁盤,當(dāng)遇到無法掛載SD卡,或者其他問題時(shí),優(yōu)先檢查該函數(shù),該函數(shù)會(huì)調(diào)用SD_Init函數(shù),需要檢查
SD_Init函數(shù)的返回結(jié)果是否為SD_OK。


//初始化磁盤
DSTATUS disk_initialize (
?? ?BYTE pdrv?? ??? ??? ??? ?/* Physical drive nmuber to identify the drive */
)
{
?? ?DSTATUS status = STA_NOINIT;
?? ?switch(pdrv)
?? ?{
?? ??? ?case SD_CARD://SD卡
?? ??? ??? ?if(SD_OK == SD_Init())//SD卡初始化?
?? ??? ??? ?{
?? ??? ??? ??? ?status &= ~STA_NOINIT;
?? ??? ??? ?}
?? ??? ??? ?else
?? ??? ??? ?{
?? ??? ??? ??? ?status = STA_NOINIT;
?? ??? ??? ?}
? ?? ??? ?break;
?? ??? ?case EX_FLASH://外部flash
??? ??? ??? ?break;
?? ??? ?default:
?? ??? ??? ?status = STA_NOINIT;
?? ??? ??? ?break;
?? ?}
?? ?return status;
}?
4. disk_read 讀取SD卡

//讀扇區(qū)
//pdrv:磁盤編號(hào)0~9
//*buff:數(shù)據(jù)接收緩沖首地址
//sector:扇區(qū)地址
//count:需要讀取的扇區(qū)數(shù)
DRESULT disk_read (
?? ?BYTE pdrv,?? ??? ?/* Physical drive nmuber to identify the drive */
?? ?BYTE *buff,?? ??? ?/* Data buffer to store read data */
?? ?DWORD sector,?? ?/* Sector address in LBA */
?? ?UINT count?? ??? ?/* Number of sectors to read */
)
{
?? ?DRESULT status = RES_PARERR;
?? ?SD_Error SD_Status = SD_OK;
?? ?
?? ?switch(pdrv)
?? ?{
?? ??? ?case SD_CARD://SD卡
?? ??? ??? ?if((DWORD)buff & 3)
?? ??? ??? ?{
?? ??? ??? ??? ?DRESULT res = RES_OK;
?? ??? ??? ??? ?DWORD scratch[SD_BLOCKSIZE / 4];
?? ??? ??? ??? ?
?? ??? ??? ??? ?while(count--)
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?res = disk_read(SD_CARD, (void*)scratch, sector++, 1);
?? ??? ??? ??? ??? ?
?? ??? ??? ??? ??? ?if(res != RES_OK)
?? ??? ??? ??? ??? ?{
?? ??? ??? ??? ??? ??? ?break;
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?memcpy(buff, scratch, SD_BLOCKSIZE);
?? ??? ??? ??? ??? ?buff += SD_BLOCKSIZE;
?? ??? ??? ??? ?}
?? ??? ??? ??? ?return res;
?? ??? ??? ?}
?? ??? ??? ?
?? ??? ??? ?SD_Status = SD_ReadMultiBlocks(buff, sector*SD_BLOCKSIZE,SD_BLOCKSIZE,count);
?? ??? ??? ?
?? ??? ??? ?if(SD_Status == SD_OK)
?? ??? ??? ?{
?? ??? ??? ??? ?//檢查傳輸是否完成
?? ??? ??? ??? ?SD_Status = SD_WaitReadOperation();
?? ??? ??? ??? ?while(SD_GetStatus() != SD_TRANSFER_OK);
?? ??? ??? ?}
?? ??? ??? ?
?? ??? ??? ?if(SD_Status != SD_OK)
?? ??? ??? ?{
?? ??? ??? ??? ?status = RES_PARERR;
?? ??? ??? ?}
?? ??? ??? ?else
?? ??? ??? ?{
?? ??? ??? ??? ?status = RES_OK;
?? ??? ??? ?}
? ?? ??? ?break;
?? ??? ?case EX_FLASH://外部flash
??? ??? ??? ?break;
?? ??? ?default:
?? ??? ??? ?status = RES_PARERR;
?? ??? ??? ?break;
?? ?}
?? ?return status;
}
5.disk_write 寫數(shù)據(jù)到SD卡

//寫扇區(qū)
//pdrv:磁盤編號(hào)0~9
//*buff:發(fā)送數(shù)據(jù)首地址
//sector:扇區(qū)地址
//count:需要寫入的扇區(qū)數(shù)
#if _USE_WRITE
DRESULT disk_write (
?? ?BYTE pdrv,?? ??? ??? ?/* Physical drive nmuber to identify the drive */
?? ?const BYTE *buff,?? ?/* Data to be written */
?? ?DWORD sector,?? ??? ?/* Sector address in LBA */
?? ?UINT count?? ??? ??? ?/* Number of sectors to write */
)
{
?? ?DRESULT status = RES_PARERR;
?? ?SD_Error SD_Status = SD_OK;
?? ?
?? ?//檢查參數(shù)
?? ?if(!count)
?? ?{
?? ??? ?return RES_PARERR;
?? ?}
?? ?
?? ?switch(pdrv)
?? ?{
?? ??? ?case SD_CARD://SD卡
?? ??? ??? ?if((DWORD)buff & 3)
?? ??? ??? ?{
?? ??? ??? ??? ?DRESULT res = RES_OK;
?? ??? ??? ??? ?DWORD scratch[SD_BLOCKSIZE / 4];
?? ??? ??? ??? ?
?? ??? ??? ??? ?while(count--)
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?memcpy(scratch, buff, SD_BLOCKSIZE);
?? ??? ??? ??? ??? ?
?? ??? ??? ??? ??? ?res = disk_write(SD_CARD, (void*)scratch, sector++, 1);
?? ??? ??? ??? ??? ?if(res != RES_OK)
?? ??? ??? ??? ??? ?{
?? ??? ??? ??? ??? ??? ?break;
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?buff += SD_BLOCKSIZE;
?? ??? ??? ??? ?}
?? ??? ??? ??? ?return res;
?? ??? ??? ?}
?? ??? ??? ?
?? ??? ??? ?SD_Status = SD_WriteMultiBlocks((uint8_t *)buff, sector*SD_BLOCKSIZE,SD_BLOCKSIZE,count);
?? ??? ??? ?
?? ??? ??? ?if(SD_Status == SD_OK)
?? ??? ??? ?{
?? ??? ??? ??? ?//檢查傳輸是否完成
?? ??? ??? ??? ?SD_Status = SD_WaitReadOperation();
?? ??? ??? ??? ?while(SD_GetStatus() != SD_TRANSFER_OK);
?? ??? ??? ?}
?? ??? ??? ?
?? ??? ??? ?if(SD_Status != SD_OK)
?? ??? ??? ?{
?? ??? ??? ??? ?status = RES_PARERR;
?? ??? ??? ?}
?? ??? ??? ?else
?? ??? ??? ?{
?? ??? ??? ??? ?status = RES_OK;
?? ??? ??? ?}
? ?? ??? ?break;
?? ??? ?case EX_FLASH://外部flash
??? ??? ??? ?break;
?? ??? ?default:
?? ??? ??? ?status = RES_PARERR;
?? ??? ??? ?break;
?? ?}
?? ?return status;
}
6.disk_ioctl 函數(shù),獲取SD卡的某些參數(shù),如塊大小等。

//其他表參數(shù)的獲得
//pdrv:磁盤編號(hào)0~9
//ctrl:控制代碼
//*buff:發(fā)送/接收緩沖區(qū)指針
#if _USE_IOCTL
DRESULT disk_ioctl (
?? ?BYTE pdrv,?? ??? ?/* Physical drive nmuber (0..) */
?? ?BYTE cmd,?? ??? ?/* Control code */
?? ?void *buff?? ??? ?/* Buffer to send/receive control data */
)
{
?? ?DRESULT res = RES_ERROR;?? ??? ??? ??? ??? ??? ? ??? ??? ??? ? ? ??
?? ?switch(pdrv)//SD卡
?? ?{
?? ??? ?case SD_CARD:
?? ? ? ?switch(cmd)
?? ? ? ?{
?? ??? ? ? ?case GET_SECTOR_SIZE:
?? ??? ??? ??? ??? ?*(WORD*)buff = SD_BLOCKSIZE;?
?? ??? ? ? ? ?break;?? ??
?? ??? ? ? ?case GET_BLOCK_SIZE:
?? ??? ??? ??? ??? ?*(DWORD*)buff = SDCardInfo.CardBlockSize;
?? ??? ? ? ? ?break;?? ??
?? ??? ? ? ?case GET_SECTOR_COUNT:
?? ??? ? ? ? ?*(DWORD*)buff = SDCardInfo.CardCapacity / SD_BLOCKSIZE;
?? ??? ? ? ? ?break;
?? ??? ? ? ?case CTRL_SYNC:
?? ??? ? ? ? ?break;
?? ? ? ?}
?? ??? ? ?res = RES_OK;
?? ??? ??? ?break;
?? ??? ?case EX_FLASH://外部flash
??? ??? ??? ?break;
?? ??? ?default:
?? ??? ??? ?res = RES_PARERR;
?? ??? ??? ?break;
?? ?}
? return res;
}
7.get_fattime函數(shù),獲取時(shí)間戳。沒有實(shí)現(xiàn)。

//獲得時(shí)間 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
DWORD get_fattime (void)
{
?? ?//返回當(dāng)前時(shí)間戳
?? ?return 0;
}
8.另外需要修改ffconf.h文件,另外注意,新版本的該文件都會(huì)在宏的前面加上FF前綴,例如對(duì)于_USE_LEN,新版本的可能是
FF_USE_LLEN,本節(jié)的內(nèi)容都是按照舊版本來說的,因此宏沒有以FF為前綴。


#define _USE_LEN 2 ?//長(zhǎng)文件名支持,默認(rèn)不支持長(zhǎng)文件名
#define _USE_MKFS 1 ?//格式化功能選擇,使能FatFs的格式化功能
#define _CODE_PAGE 936 ?//語言功能選擇,需要同時(shí)把語言文件添加到工程中,為支持簡(jiǎn)體中文,我們需要添加cc963.c文件
#define _VOLUMES 2 ?//物理設(shè)備數(shù)量,這里設(shè)置為2,包括SD卡和預(yù)留的外部Flash芯片
#define _MIN_SS 512 ? //指定扇區(qū)大小的最小值
#define _MAX_SS 4096 ?//指定扇區(qū)大小的最大值
以上就完成了FatFs的移植過程,接下來是對(duì)功能的測(cè)試,直接上代碼了。
測(cè)試:


//FAT功能測(cè)試:格式化測(cè)試,文件寫入測(cè)試,文件讀取測(cè)試(基本功能)
FATFS fs; //FatFs文件系統(tǒng)對(duì)象
FIL fnew; //文件對(duì)象
FRESULT res_sd;//文件操作結(jié)果
UINT fnum; //文件成功讀寫數(shù)量
BYTE ReadBuffer[1024] = {0};
BYTE WriteBuffer[] = "成功移植了FatFs文件系統(tǒng)!\r\n"; //寫緩存區(qū)
main 主函數(shù),包含格式化測(cè)試和文件讀寫測(cè)試。
int main()
{
?? ?//串口配置
?? ?USART_Config();
?? ?
?? ?//初始化LED
?? ?LED_GPIO_Config();
?? ?
?? ?//初始化SD卡
?? ?if(SD_Init() == SD_OK)
?? ?{
?? ??? ?printf("SD卡初始化成功,即將掛載SD卡。\r\n");
?? ?}
?? ?
?? ?//掛載SD卡
?? ?res_sd = f_mount(&fs, "0:", 1);
?? ?
?? ?//***********************格式化測(cè)試****************************
?? ?if(res_sd == FR_NO_FILESYSTEM)
?? ?{
?? ??? ?printf("SD卡沒有文件系統(tǒng),即將進(jìn)行格式化...\r\n");
?? ??? ?//格式化
?? ??? ?res_sd = f_mkfs("0:", 0, 0);
?? ??? ?
?? ??? ?if(res_sd == FR_OK)
?? ??? ?{
?? ??? ??? ?printf("SD卡成功格式化!\r\n");
?? ??? ??? ?//格式化后先取消掛載
?? ??? ??? ?res_sd = f_mount(NULL, "0:", 1);
?? ??? ??? ?//再重新掛載
?? ??? ??? ?res_sd = f_mount(&fs, "0:", 1);
?? ??? ?}
?? ??? ?else
?? ??? ?{
?? ??? ??? ?printf("文件格式化失敗!錯(cuò)誤代碼:%d\r\n",res_sd);
?? ??? ??? ?while(1);
?? ??? ?}
?? ?}
?? ?else if(res_sd != FR_OK)
?? ?{
?? ??? ?printf("掛載文件系統(tǒng)失敗!可能是因?yàn)槲募跏蓟?#xff01;錯(cuò)誤代碼:%d\r\n", res_sd);
?? ?}
?? ?else
?? ?{
?? ??? ?printf("文件系統(tǒng)掛載成功, 可進(jìn)行讀寫測(cè)試!\r\n");
?? ?}
?? ?
?? ?//***********************寫測(cè)試****************************
?? ?//打開文件,如果文件不存在則創(chuàng)建它
?? ?printf("即將進(jìn)行文件寫入測(cè)試....\r\n");
?? ?//打開文件,若不存在就創(chuàng)建
?? ?res_sd = f_open(&fnew, "0:FatFs讀寫測(cè)試文件.txt", FA_CREATE_ALWAYS | FA_WRITE);
?? ?//文件打開成功
?? ?if(res_sd == FR_OK)
?? ?{
?? ??? ?printf("打開文件成功!開始寫入數(shù)據(jù)!\r\n");
?? ??? ?res_sd= f_write(&fnew, WriteBuffer, sizeof(WriteBuffer), &fnum);
?? ??? ?
?? ??? ?if(res_sd == FR_OK)
?? ??? ?{
?? ??? ??? ?printf("數(shù)據(jù)寫入成功!\r\n");
?? ??? ??? ?printf("數(shù)據(jù):%s。共寫入%d個(gè)字符\r\n", WriteBuffer, fnum);
?? ??? ?}
?? ??? ?else
?? ??? ?{
?? ??? ??? ?printf("數(shù)據(jù)寫入失敗!\r\n");
?? ??? ?}
?? ??? ?
?? ??? ?//關(guān)閉文件
?? ??? ?f_close(&fnew);
?? ?}
?? ?
?? ?//***********************讀測(cè)試****************************
?? ?//打開文件,如果文件不存在則創(chuàng)建它
?? ?printf("即將進(jìn)行文件讀取測(cè)試....\r\n");
?? ?//打開文件,若不存在就創(chuàng)建
?? ?res_sd = f_open(&fnew, "0:FatFs讀寫測(cè)試文件.txt", FA_OPEN_EXISTING | FA_READ);
?? ?//文件打開成功
?? ?if(res_sd == FR_OK)
?? ?{
?? ??? ?printf("打開文件成功!開始讀取數(shù)據(jù)!\r\n");
?? ??? ?res_sd= f_read(&fnew, ReadBuffer, sizeof(ReadBuffer), &fnum);
?? ??? ?
?? ??? ?if(res_sd == FR_OK)
?? ??? ?{
?? ??? ??? ?printf("數(shù)據(jù)讀取成功!\r\n");
?? ??? ??? ?printf("數(shù)據(jù):%s\r\n", ReadBuffer);
?? ??? ?}
?? ??? ?else
?? ??? ?{
?? ??? ??? ?printf("數(shù)據(jù)讀取失敗!\r\n");
?? ??? ?}
?? ??? ?
?? ??? ?//關(guān)閉文件
?? ??? ?f_close(&fnew);
?? ?}
?? ?
?? ?scan_files("FatFs讀寫測(cè)試文件.txt");
?? ?
?? ?//其他功能測(cè)試
?? ?file_check();
?? ?
?? ?//多項(xiàng)功能測(cè)試
?? ?miscellaneous();
?? ?
?? ?//取消掛載文件系統(tǒng)
?? ?f_mount(NULL, "0:", 1);
?? ?
?? ?while(1);
}
補(bǔ)充,如有需要可以借鑒,其他功能測(cè)試。
//多項(xiàng)功能測(cè)試
static FRESULT miscellaneous()
{
?? ?DIR dir;
?? ?FATFS *pfs;
?? ?DWORD fre_clust, fre_sect, tot_sect;
?? ?
?? ?printf("\r\n*************************設(shè)備信息獲取***************************\r\n");
?? ?//獲取設(shè)備信息和空簇大小
?? ?res_sd = f_getfree("0:", &fre_clust, &pfs);
?? ?
?? ?//計(jì)算得到總的扇區(qū)個(gè)數(shù)和空扇區(qū)個(gè)數(shù)
?? ?tot_sect = (pfs->n_fatent - 2) * pfs->csize;
?? ?fre_sect = fre_clust * pfs->csize;
?? ?
?? ?printf("設(shè)備總空間:%10lu KB\r\n可用空間:%10lu KB。\r\n", tot_sect*4, fre_sect*4);
?? ?
?? ?printf("\r\n*************************文件定位和格式化寫入功能測(cè)試***************************\r\n");
?? ?//打開文件,若不存在就創(chuàng)建
?? ?res_sd = f_open(&fnew, "0:FatFs多項(xiàng)功能測(cè)試文件.txt", FA_CREATE_ALWAYS | FA_WRITE | FA_READ);
?? ?//文件打開成功
?? ?if(res_sd == FR_OK)
?? ?{
?? ??? ?printf("打開文件成功!開始讀取數(shù)據(jù)!\r\n");
?? ??? ?res_sd= f_write(&fnew, WriteBuffer, sizeof(WriteBuffer), &fnum);
?? ??? ?
?? ??? ?if(res_sd == FR_OK)
?? ??? ?{
?? ??? ??? ?printf("數(shù)據(jù)寫入成功!\r\n");
?? ??? ??? ?printf("數(shù)據(jù):%s\r\n", WriteBuffer);
?? ??? ??? ?//文件定位,定位到文件末尾,f_size獲取文件大小
?? ??? ??? ?res_sd = f_lseek(&fnew, f_size(&fnew) - 1);
?? ??? ??? ?if(res_sd == FR_OK)
?? ??? ??? ?{
?? ??? ??? ??? ?//在原文件中追加一行內(nèi)容
?? ??? ??? ??? ?f_printf(&fnew, "在原文件中追加一行內(nèi)容。\n");
?? ??? ??? ??? ?f_printf(&fnew, "設(shè)備總空間:%10lu KB\r\n可用空間:%10lu KB。\r\n", tot_sect*4, fre_sect*4);
?? ??? ??? ??? ?
?? ??? ??? ??? ?//文件定位到起始位置
?? ??? ??? ??? ?res_sd = f_lseek(&fnew, 0);
?? ??? ??? ??? ?
?? ??? ??? ??? ?if(res_sd == FR_OK)
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?//打開文件,若不存在就創(chuàng)建
?? ??? ??? ??? ??? ?res_sd = f_open(&fnew, "0:FatFs多項(xiàng)功能測(cè)試文件.txt", FA_OPEN_EXISTING | FA_READ);
?? ??? ??? ??? ??? ?//文件打開成功
?? ??? ??? ??? ??? ?if(res_sd == FR_OK)
?? ??? ??? ??? ??? ?{
?? ??? ??? ??? ??? ??? ?printf("打開文件成功!開始讀取數(shù)據(jù)!\r\n");
?? ??? ??? ??? ??? ??? ?res_sd= f_read(&fnew, ReadBuffer, sizeof(ReadBuffer), &fnum);
?? ??? ??? ??? ??? ??? ?
?? ??? ??? ??? ??? ??? ?if(res_sd == FR_OK)
?? ??? ??? ??? ??? ??? ?{
?? ??? ??? ??? ??? ??? ??? ?printf("數(shù)據(jù)讀取成功!\r\n");
?? ??? ??? ??? ??? ??? ??? ?printf("數(shù)據(jù):%s\r\n", ReadBuffer);
?? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ??? ?else
?? ??? ??? ??? ??? ??? ?{
?? ??? ??? ??? ??? ??? ??? ?printf("數(shù)據(jù)讀取失敗!\r\n");
?? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ??? ?
?? ??? ??? ??? ??? ??? ?//關(guān)閉文件
?? ??? ??? ??? ??? ??? ?f_close(&fnew);
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ?}
?? ??? ?else
?? ??? ?{
?? ??? ??? ?printf("數(shù)據(jù)讀取失敗!\r\n");
?? ??? ?}
?? ??? ?
?? ??? ?//關(guān)閉文件
?? ??? ?f_close(&fnew);
?? ?}
?? ?printf("\r\n*************************目錄創(chuàng)建和重命名功能測(cè)試***************************\r\n");
?? ?//嘗試打開目錄
?? ?res_sd = f_opendir(&dir, "0:TestDir");
?? ?if(res_sd != FR_OK)
?? ?{
?? ??? ?//打開目錄失敗,開始創(chuàng)建目錄
?? ??? ?res_sd = f_mkdir("0:TestDir");
?? ?}
?? ?else
?? ?{
?? ??? ?//如果目錄已經(jīng)存在,關(guān)閉它
?? ??? ?res_sd = f_closedir(&dir);
?? ??? ?//刪除文件
?? ??? ?f_unlink("0:FatFs讀寫測(cè)試文件.txt");
?? ?}
?? ?
?? ?if(res_sd == FR_OK)
?? ?{
?? ??? ?//重命名并移動(dòng)文件
?? ??? ?res_sd = f_rename("0:FatFs多項(xiàng)功能測(cè)試文件.txt", "0:/TestDir/FatFs多項(xiàng)功能測(cè)試文件.txt");
?? ??? ?
?? ??? ?if(res_sd == FR_OK)
?? ??? ?{
?? ??? ??? ?printf("重命名并移動(dòng)文件成功!\r\n");
?? ??? ?}
?? ??? ?else
?? ??? ?{
?? ??? ??? ?printf("重命名并移動(dòng)文件失敗!\r\n");
?? ??? ?}
?? ?}
}
?
//文件信息獲取
static FRESULT file_check()
{
?? ?//文件信息
?? ?static FILINFO fno;
?? ?
?? ?//獲取文件信息,必須確保文件存在
?? ?res_sd = f_stat("0:FatFs讀寫測(cè)試文件.txt", &fno);
?? ?
?? ?if(res_sd == FR_OK)
?? ?{
?? ??? ?printf("0:FatFs讀寫測(cè)試文件.txt的信息如下:\r\n");
?? ??? ?printf("文件大小:%ld\r\n", fno.fsize);
?? ??? ?printf("時(shí)間戳:%u/%02u/%02u, %02u:%02u\r\n", (fno.fdate >> 9) + 1980, fno.fdate >> 5 & 15, fno.fdate & 31, fno.ftime >> 11, fno.ftime >> 5 &63);
?? ??? ?printf("屬性:%c%c%c%c%c\r\n",?
?? ??? ?(fno.fattrib & AM_DIR) ? 'D' : '-', //目錄
?? ??? ?(fno.fattrib & AM_RDO) ? 'R' : '-', //只讀
?? ??? ?(fno.fattrib & AM_HID) ? 'H' : '-', //隱藏
?? ??? ?(fno.fattrib & AM_SYS) ? 'S' : '-', //系統(tǒng)文件
?? ??? ?(fno.fattrib & AM_ARC) ? 'A' : '-');//檔案文件
?? ?}
}
?
//路徑掃描
static FRESULT scan_files(char* path)
{
?? ?FRESULT res;//在遞歸過程中被修改,不用全局變量
?? ?FILINFO fno;
?? ?DIR dir;
?? ?int i;
?? ?char* fn;
?? ?
?? ?#if _USE_LEN//長(zhǎng)文件名支持
?? ?//簡(jiǎn)體中文需要兩個(gè)字節(jié)保存一個(gè)字
?? ?static char lfn[_MAX_LFN*2+1];
?? ?fno.lfname = lfn;
?? ?fno.lfsize = sizeof(lfn);
?? ?#endif
?? ?
?? ?//打開目錄
?? ?res = f_opendir(&dir, path);
?? ?if(res == FR_OK)
?? ?{
?? ??? ?i = strlen(path);
?? ??? ?while(1)
?? ??? ?{
?? ??? ??? ?//讀取目錄下的內(nèi)容
?? ??? ??? ?res = f_readdir(&dir, &fno);
?? ??? ??? ?if(res != FR_OK || fno.fname[0] == 0)
?? ??? ??? ?{
?? ??? ??? ??? ?break;
?? ??? ??? ?}
?? ??? ??? ?#if _USE_LEN
?? ??? ??? ?fn = *fno.lfname ? fno.lfname : fno.fname;
?? ??? ??? ?#else
?? ??? ??? ?fn = fno.fname;
?? ??? ??? ?#endif
?? ??? ??? ?
?? ??? ??? ?//點(diǎn)表示當(dāng)前目錄,跳過
?? ??? ??? ?if(*fn == '.')
?? ??? ??? ??? ?continue;
?? ??? ??? ?//目錄,遞歸讀取
?? ??? ??? ?if(fno.fattrib & AM_DIR)
?? ??? ??? ?{
?? ??? ??? ??? ?//合成完整目錄名
?? ??? ??? ??? ?sprintf(&path[i], "/%s", fn);
?? ??? ??? ??? ?
?? ??? ??? ??? ?//遞歸遍歷
?? ??? ??? ??? ?res = scan_files(path);
?? ??? ??? ??? ?
?? ??? ??? ??? ?path[i] = 0;
?? ??? ??? ??? ?if(res != FR_OK)
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?break;
?? ??? ??? ??? ?}
?? ??? ??? ??? ?else
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?printf("%s/%s\r\n", path, fn);//輸出文件名,可以在這里提取特定格式的文件路徑
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ?}
?? ?}
?? ?return res;
}
感謝大家的耐心閱讀,如果有問題,歡迎一起討論。
————————————————
版權(quán)聲明:本文為CSDN博主「CallMeJacky」的原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/zyxhangiian123456789/article/details/79098483

總結(jié)

以上是生活随笔為你收集整理的基于SD卡的FatFs文件系统(FatFs移植到STM32)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。