STM32F103-FATFS 檔案系統移植
阿新 • • 發佈:2020-12-28
首先準備一個例程,這裡準備一個原子的串列埠實驗
修改資料夾名稱為FATFS,防止中文出錯,編譯下載,測試工程是否正確
前往FATFS官網下載原始碼 http://elm-chan.org/fsw/ff/00index_e.html 點選下載最新版
工程目錄下新建FATFS 資料夾,用於存放原始碼
將所有檔案複製大工程的FATFS資料夾下,最上面兩個可以刪除
開啟工程新建檔案加新增檔案並新增路徑
修改 diskio.c
增加標頭檔案和巨集定義 #include "usart.h" #include "sdio_sdcard.h" #define SD_CARD 0 //SD卡,卷標為0 #define SPI_FLASH 1 //SPI Flash,卷標為1
修改 disk_status 函式
DSTATUS disk_status (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
return RES_OK;
}
修改 disk_initialize 函式
DSTATUS disk_initialize ( BYTE pdrv /* Physical drive nmuber to identify the drive */ ) { DSTATUS stat=0; switch(pdrv) { case SD_CARD: stat=SD_Init();//SD卡初始化 break; case SPI_FLASH: /*未使用 SPIFLASH 預設為無*/ break; default: stat=1; } if(stat) {return STA_NOINIT;} else {return 0; } //初始化成功 }
修改 disk_read 函式
DRESULT disk_read ( BYTE pdrv, /* Physical drive nmuber to identify the drive */ BYTE *buff, /* Data buffer to store read data */ LBA_t sector, /* Start sector in LBA */ UINT count /* Number of sectors to read */ ) { u8 res; if (!count)return RES_PARERR; //count不能等於0,否則返回引數錯誤 switch(pdrv) { case SD_CARD: res=SD_ReadDisk(buff,sector,count); while(res)//讀出錯 { SD_Init(); //重新初始化SD卡 res=SD_ReadDisk(buff,sector,count); //printf("sd rd error:%d\r\n",res); } break; case SPI_FLASH: /*未使用 SPIFLASH 預設為無*/ res=0; break; default: res=1; } //處理返回值,將SPI_SD_driver.c的返回值轉成ff.c的返回值 if(res==0x00) {return RES_OK; } else {return RES_ERROR;} }
修改 disk_write 函式
DRESULT disk_write (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
const BYTE *buff, /* Data to be written */
LBA_t sector, /* Start sector in LBA */
UINT count /* Number of sectors to write */
)
{
u8 res;
if (!count)return RES_PARERR; //count不能等於0,否則返回引數錯誤
switch(pdrv)
{
case SD_CARD:
res=SD_WriteDisk((u8*)buff,sector,count);
while(res)//寫出錯
{
SD_Init(); //重新初始化SD卡
res=SD_WriteDisk((u8*)buff,sector,count);
//printf("sd wr error:%d\r\n",res);
}
break;
case SPI_FLASH:
/*未使用 SPIFLASH 預設為無*/
res=0;
break;
default:
res=1;
}
//處理返回值,將SPI_SD_driver.c的返回值轉成ff.c的返回值
if(res == 0x00) {return RES_OK; }
else {return RES_ERROR;}
}
修改 disk_ioctl 函式 ,如果沒有移植此函式,大部分情況可以正常使用,但是偶爾會有提示磁碟存在防寫,類似問題大概率是因為此函式移植問題!!!
DRESULT disk_ioctl (
BYTE pdrv, /* Physical drive nmuber (0..) */
BYTE cmd, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
DRESULT res;
if(pdrv==SD_CARD)//SD卡
{
switch(cmd)
{
case CTRL_SYNC:
res = RES_OK;
break;
case GET_SECTOR_SIZE:
*(DWORD*)buff = 512;
res = RES_OK;
break;
case GET_BLOCK_SIZE:
*(WORD*)buff = SDCardInfo.CardBlockSize;
res = RES_OK;
break;
case GET_SECTOR_COUNT:
*(DWORD*)buff = SDCardInfo.CardCapacity/512;
res = RES_OK;
break;
default:
res = RES_PARERR;
break;
}
}
else if(pdrv==SPI_FLASH) //外部FLASH
{
/*未使用 SPIFLASH 預設為無*/
}
else
{
res=RES_ERROR;//其他的不支援
}
return res;
}
增加 get_fattime 函式
DWORD get_fattime(void)
{
return 0;
}
修改ffconf.h
#define FF_FS_READONLY 0
#define FF_FS_MINIMIZE 0
#define FF_USE_STRFUNC 1
#define FF_USE_FIND 0
#define FF_USE_MKFS 1
#define FF_USE_FASTSEEK 1
#define FF_USE_EXPAND 0
#define FF_USE_CHMOD 0
#define FF_USE_LABEL 1
#define FF_USE_FORWARD 0
#define FF_CODE_PAGE 936
#define FF_USE_LFN 2
#define FF_MAX_LFN 255
#define FF_LFN_UNICODE 0
#define FF_LFN_BUF 255
#define FF_SFN_BUF 12
#define FF_STRF_ENCODE 3
#define FF_FS_RPATH 0
#define FF_VOLUMES 2
#define FF_STR_VOLUME_ID 0
#define FF_VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3"
#define FF_MULTI_PARTITION 0
#define FF_MIN_SS 512
#define FF_MAX_SS 512
#define FF_LBA64 0
#define FF_MIN_GPT 0x10000000
#define FF_USE_TRIM 0
#define FF_FS_TINY 0
#define FF_FS_EXFAT 0
#define FF_FS_NORTC 0
#define FF_NORTC_MON 1
#define FF_NORTC_MDAY 1
#define FF_NORTC_YEAR 2020
#define FF_FS_NOFSINFO 0
#define FF_FS_LOCK 0
#define FF_FS_REENTRANT 0
#define FF_FS_TIMEOUT 1000
#define FF_SYNC_t HANDLE
修改main.c
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "key.h"
#include "stdio.h"
#include "string.h"
#include "ff.h"
#include "sdio_sdcard.h"
//檔案系統定義使用
FATFS ff_disk; /* FatFs檔案系統物件 */
FIL ff_file; /* 檔案物件 */
FRESULT ff_rec; /* 檔案操作結果 */
UINT ff_num; /* 檔案成功讀寫數量 */
DIR ff_dir; /* 資料夾名稱 */
FILINFO ff_info; /* 檔案資訊讀取儲存 */
BYTE ff_buff[99]={0}; /* SD卡操作緩衝區 */
uint8_t Test_Buff[33] = {"檔案系統測試資料 FATFS TEST DATA"};
int main(void)
{
delay_init(); //延時函式初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設定中斷優先順序分組為組2:2位搶佔優先順序,2位響應優先順序
uart_init(115200); //串列埠初始化為115200
LED_Init(); //初始化與LED連線的硬體介面
while(SD_Init()) //檢測是否存在SD卡
{
LED0 =! LED0;
printf("SD Card Test..... \r\n");
delay_ms(300);
};
LED0 = 1;
ff_rec = f_mount(&ff_disk,"0:",0); //掛載SD卡
ff_rec = f_mkdir("0:/data"); //建立資料夾
ff_rec = f_open(&ff_file,"0:/test.txt",FA_CREATE_ALWAYS | FA_WRITE); //開啟一個檔案,如果沒有則建立一個,有則覆蓋掉之前,並開啟寫入屬性
printf("ERROR:%d\r\n",ff_rec); //列印錯誤
ff_rec = f_write(&ff_file,Test_Buff,32,&ff_num); //寫資料
ff_rec = f_close(&ff_file); //關閉檔案
memset(Test_Buff,0,32); //清零Test_Buff
ff_rec = f_open(&ff_file,"0:/test.txt",FA_READ); //開啟檔案
ff_rec = f_read(&ff_file,Test_Buff,32,&ff_num); //讀檔案內容
ff_rec = f_close(&ff_file); //關閉檔案
Test_Buff[32] = '\0'; //新增結束符,不新增結束符,會導致末尾多出亂
printf("ERROR:%d\r\nDATA:%s\r\n",ff_rec,Test_Buff); //列印錯誤
while(1)
{
LED1 =! LED1;
delay_ms(500);
};
}
編譯下載,下載,串列埠列印無錯誤
檢視SD卡內容,資料正確
成功移植FATFS
個人見解,感謝閱讀。