本博文要求各位初步了解Fatfs文件系統
友情提示Fatfs官網:http://elm-chan.org/fsw/ff/00index_e.html
1.開發軟件
keil5,Cube5.21
2.實驗目的
往SDHC卡上移植Fatfs文件
SDHC:
SDHC是"Secure Digital High Capacity“的縮寫,即“高容量SD存儲卡”。2006年5月SD協會發布了SD 2.0的系統規范,並在其中規定SDHC是符合該規范、SDHC存儲卡容量為“4GB-32GB”。
3.Cube配置
(1)在Cube上點開芯片功能的SDIO,因為我用的是4GB的SDHC卡,所以用SD 4 bits,用默認配置即可與SD卡通信

紅框內為SDIO協議引用的引腳
PC8 ------> SDIO_D0
PC9 ------> SDIO_D1
PC10 ------> SDIO_D2
PC11 ------> SDIO_D3
PC12 ------> SDIO_CK
PD2 ------> SDIO_CMD

(2)再點開下面的FATFS,即向工程里添加fatfs移植文件,然后再勾選SD Card,底層的disiko接口默認添加SD卡讀寫程序

(3)配置時鍾完成后,就可生成工程

4.工程講解
(1)下面的文件是Cube幫你移植的Fatfs文件,但不用修改里面的程序

(2)下面的兩個C文件,一個是SD的diskio接口層,Cube已往里面調用了HAL庫的SD卡讀寫函數,可以不修改,另一個是上層的fatfs文件功能函數,可根據需要添加函數,也可以不用修改。

(3)雖然Cube使用了MX_SDIO_SD_Init();進行了SD卡的初始化,但還要用下面的初始化進行初始化才能使用SD卡,它們在stm32f4xx_hal_sd.c里
HAL_SD_Init(&hsd);
HAL_SD_InitCard(&hsd);
5.程序測試
(1)使用FATFS_GetAttachedDriversNbr()判斷SD卡是否掛載上驅動
i=FATFS_GetAttachedDriversNbr();
printf("已掛載的驅動:%d",i);

(2)調用ff.c的文件功能函數,如果返回FR_OK(0)則成功
/* USER CODE BEGIN Application */ void SD_Fatfs_Test(void) { printf("文件掛載\n" ); retSD=f_mount(&SDFatFS, "0:/",0); if(retSD==FR_OK) { printf("MOUNT OK\n"); printf("FAILED0: %d\n",retSD); } else printf("FAILED2: %d\n",retSD); printf("文件打開\n" ); retSD=f_open(&SDFile, "0:hellow.txt", FA_CREATE_ALWAYS | FA_WRITE | FA_READ ); if(retSD==FR_OK) { printf("OPEN OK\n"); } else printf("FAILED3: %d\n",retSD); printf("文件關閉\n" ); retSD=f_close(&SDFile); if(retSD==FR_OK) { printf("closk OK\n"); } else printf("FAILED5: %d\n",retSD); }

(3)HAL_SD_ReadBlocks()和HAL_SD_WriteBlocks()可以往SD卡讀寫數據
(4)用以下的HAKL庫函數可讀取SD卡的信息,有興趣可以去弄
HAL_SD_CardStateTypeDef HAL_SD_GetCardState(SD_HandleTypeDef *hsd);
HAL_StatusTypeDef HAL_SD_GetCardCID(SD_HandleTypeDef *hsd, HAL_SD_CardCIDTypeDef *pCID);
HAL_StatusTypeDef HAL_SD_GetCardCSD(SD_HandleTypeDef *hsd, HAL_SD_CardCSDTypeDef *pCSD);
HAL_StatusTypeDef HAL_SD_GetCardStatus(SD_HandleTypeDef *hsd, HAL_SD_CardStatusTypeDef *pStatus);
HAL_StatusTypeDef HAL_SD_GetCardInfo(SD_HandleTypeDef *hsd, HAL_SD_CardInfoTypeDef *pCardInfo);
6.Fatfs使用小經驗
(1)使用FATFS,FIL等類型的變量時,可能要先申請內存空間,才能使用。具體是怎樣請先學習STM32的內存管理。
(2)使用f_mount,f_close等文件功能函數出錯時,請看其返回函數為何值,更容易調試。
typedef enum { FR_OK = 0, /* (0) Succeeded */ FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */ FR_INT_ERR, /* (2) Assertion failed */ FR_NOT_READY, /* (3) The physical drive cannot work */ FR_NO_FILE, /* (4) Could not find the file */ FR_NO_PATH, /* (5) Could not find the path */ FR_INVALID_NAME, /* (6) The path name format is invalid */ FR_DENIED, /* (7) Access denied due to prohibited access or directory full */ FR_EXIST, /* (8) Access denied due to prohibited access */ FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */ FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */ FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */ FR_NOT_ENABLED, /* (12) The volume has no work area */ FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */ FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any problem */ FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */ FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */ FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */ FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_LOCK */ FR_INVALID_PARAMETER /* (19) Given parameter is invalid */ } FRESULT;
(3)要先加載文件卷,才能用文件功能函數。
(4)程序出錯一般是底層接口函數沒寫好。
粗糙之作,有不合之處請多多指教。
