今天我们移植下FATFS,让他显示SD卡当前容量~
先下载FATFS包,这里途径很多可用其他工程上的,直接拿来修改下就能用了。
我们先配置好SD卡,板上的SPI FLASH太小512K字节,就不使用了。
SD卡采用的SDIO接口,我们直接用给出的例程(gd32-f303-master 3 例程Project16_SDIO_SDCardTest)。
编译下载,正常~(2.0的卡正常。这了用3.0新卡试验过。能读不能写,可能配置的速度不够,未去深究)
好,我们就在这个例子的基础上,移植FATFS,我们把包添加进工程:
并把头文件路径,包含进工程:
配置好后,我们对代码的一些初始化、读写等改成我们之前配置的SD的底层操作函数。我们主要对"sd_diskio.c"进行修改~
- /**
- ******************************************************************************
- * [url=home.php?mod=space&uid=1455510]@file[/url] sd_diskio.c
- * [url=home.php?mod=space&uid=40524]@author[/url] MCD Application Team
- * [url=home.php?mod=space&uid=644434]@version[/url] V1.3.0
- * @date 08-May-2015
- * [url=home.php?mod=space&uid=2666770]@Brief[/url] SD Disk I/O driver
- ******************************************************************************
- * @attention
- *
- *
© COPYRIGHT 2015 STMicroelectronics
- *
- * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
- * You may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.st.com/software_license_agreement_liberty_v2
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- ******************************************************************************
- */
- /* Includes ------------------------------------------------------------------*/
- #include
- #include "ff_gen_drv.h"
- #include "sdio_sdcard.h"
- #include "sdcard_user.h"
- /* Private typedef -----------------------------------------------------------*/
- /* Private define ------------------------------------------------------------*/
- /* Block Size in Bytes */
- #define BLOCK_SIZE 512
- /* Private variables ---------------------------------------------------------*/
- /* Disk status */
- static volatile DSTATUS Stat = STA_NOINIT;
- /* Private function prototypes -----------------------------------------------*/
- DSTATUS SD_initialize (BYTE);
- DSTATUS SD_status (BYTE);
- DRESULT SD_read (BYTE, BYTE*, DWORD, UINT);
- #if _USE_WRITE == 1
- DRESULT SD_write (BYTE, const BYTE*, DWORD, UINT);
- #endif /* _USE_WRITE == 1 */
- #if _USE_IOCTL == 1
- DRESULT SD_ioctl (BYTE, BYTE, void*);
- #endif /* _USE_IOCTL == 1 */
-
- const Diskio_drvTypeDef SD_Driver =
- {
- SD_initialize,
- SD_status,
- SD_read,
- #if _USE_WRITE == 1
- SD_write,
- #endif /* _USE_WRITE == 1 */
-
- #if _USE_IOCTL == 1
- SD_ioctl,
- #endif /* _USE_IOCTL == 1 */
- };
- /* Private functions ---------------------------------------------------------*/
- /**
- * @brief Initializes a Drive
- * [url=home.php?mod=space&uid=3142012]@param[/url] lun : not used
- * @retval DSTATUS: Operation status
- */
- DSTATUS SD_initialize(BYTE lun)
- {
- Stat = STA_NOINIT;
-
- /* Configure the uSD device */
- if(sd_io_init() == SD_OK)
- {
- Stat &= ~STA_NOINIT;
- }
- return Stat;
- }
- /**
- * @brief Gets Disk Status
- * @param lun : not used
- * @retval DSTATUS: Operation status
- */
- DSTATUS SD_status(BYTE lun)
- {
- Stat = STA_NOINIT;
- if(sd_transfer_state_get() == SD_NO_TRANSFER)
- {
- Stat &= ~STA_NOINIT;
- }
-
- return Stat;
- }
- /**
- * @brief Reads Sector(s)
- * @param lun : not used
- * @param *buff: Data buffer to store read data
- * @param sector: Sector address (LBA)
- * @param count: Number of sectors to read (1..128)
- * @retval DRESULT: Operation result
- */
- DRESULT SD_read(BYTE lun, BYTE *buff, DWORD sector, UINT count)
- {
- DRESULT res = RES_OK;
-
- if(sd_multiblocks_read((uint32_t*)buff,
- (uint64_t) (sector * BLOCK_SIZE),
- BLOCK_SIZE,
- count) != SD_OK)
- {
- res = RES_ERROR;
- }
-
- return res;
- }
- /**
- * @brief Writes Sector(s)
- * @param lun : not used
- * @param *buff: Data to be written
- * @param sector: Sector address (LBA)
- * @param count: Number of sectors to write (1..128)
- * @retval DRESULT: Operation result
- */
- #if _USE_WRITE == 1
- DRESULT SD_write(BYTE lun, const BYTE *buff, DWORD sector, UINT count)
- {
- DRESULT res = RES_OK;
-
- if(sd_multiblocks_write((uint32_t*)buff,
- (uint64_t)(sector * BLOCK_SIZE),
- BLOCK_SIZE, count) != SD_OK)
- {
- res = RES_ERROR;
- }
-
- return res;
- }
- #endif /* _USE_WRITE == 1 */
- /**
- * @brief I/O control operation
- * @param lun : not used
- * @param cmd: Control code
- * @param *buff: Buffer to send/receive control data
- * @retval DRESULT: Operation result
- */
- #if _USE_IOCTL == 1
- DRESULT SD_ioctl(BYTE lun, BYTE cmd, void *buff)
- {
- DRESULT res = RES_ERROR;
- // SD_CardInfo CardInfo;
-
- if (Stat & STA_NOINIT) return RES_NOTRDY;
-
- switch (cmd)
- {
- /* Make sure that no pending write process */
- case CTRL_SYNC :
- res = RES_OK;
- break;
-
- /* Get number of sectors on the disk (DWORD) */
- case GET_SECTOR_COUNT :
- card_info_get();
- *(DWORD*)buff = sd_cardinfo.card_capacity / BLOCK_SIZE;
- res = RES_OK;
- break;
-
- /* Get R/W sector size (WORD) */
- case GET_SECTOR_SIZE :
- *(WORD*)buff = BLOCK_SIZE;
- res = RES_OK;
- break;
-
- /* Get erase block size in unit of sector (DWORD) */
- case GET_BLOCK_SIZE :
- *(DWORD*)buff = BLOCK_SIZE;
- break;
-
- default:
- res = RES_PARERR;
- }
-
- return res;
- }
- #endif /* _USE_IOCTL == 1 */
-
- /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
复制代码
我们再创建一个文件用来写自己的一些FATFS的应用的函数:
fatfs_user.h
- #ifndef __FATFS_H
- #define __FATFS_H
- #include "gd32f30x.h"
- #include "ff.h"
- #include "ff_gen_drv.h"
- #include "sd_diskio.h" /* defines SD_Driver as external */
- enum{
- USBDisk = 0,
- SDCard
- };
- extern FIL openfile;
- extern uint32_t totalsize;
- extern uint32_t freesize;
- uint8_t Fatfs_init(uint8_t driver);
- uint8_t Fatfs_getfree(uint8_t driver);
- uint8_t Fatfs_open(uint8_t driver,uint8_t*path,uint8_t mode);
- uint8_t Fatfs_close(void);
- uint8_t Fatfs_read(uint8_t *data,uint32_t len);
- uint8_t Fatfs_write(uint8_t *data,uint32_t len);
- #endif //__FATFS_H
复制代码
fatfs_user.c
- #include "fatfs_user.h"
- #include "usart.h"
- #include "stdbool.h"
- #include "string.h"
- uint32_t totalsize = 0;
- uint32_t freesize = 0;
- FIL openfile;
- FATFS SDFatFs = {0};
- char SD_Path[4]={0,0,0,0};
- FATFS USBfatfs;
- char UDisk_Path[4]={0,0,0,0};
- extern Diskio_drvTypeDef USBH_Driver;
- uint8_t retSD; /* Return value for SD */
- const char* DriverString[2]={
- {"USBDisk"},
- {"SDCard"}
- };
- //return 0:no sd card find
- //return 1: find sd card
- uint8_t Fatfs_init(uint8_t driver)
- {
- uint8_t res;
- FATFS *Fatfs;
- char *Path;
- Diskio_drvTypeDef *Driver;
- if(driver == SDCard)
- {
- Fatfs = &SDFatFs;
- Path = (char*)&SD_Path;
- Driver = &SD_Driver;
- }else if(driver == USBDisk)
- {
- // Fatfs = &USBfatfs;
- // Path = (char*)&UDisk_Path;
- // Driver = &USBH_Driver;
- }
- /*## FatFS: Link the SD driver ###########################*/
- res = FATFS_LinkDriver(Driver, Path);
- if(res != FR_OK)
- {
- printf("rn%s FATFS LinkDriver errorrn",DriverString[driver]);
- return 0;
- }
- else{
- printf("rn%s FATFS LinkDriver OK,Drive path is %srn",DriverString[driver],Path);
- }
- /*##-2- Register the file system object to the FatFs module ##############*/
- printf("%s FATFS mountrn",DriverString[driver]);
- res = f_mount(Fatfs, (TCHAR const*)Path, 0);
- if(res != FR_OK)
- {
- printf("%s FATFS mount Errorrn",DriverString[driver]);
- FATFS_UnLinkDriver(Path);
- return 0;
- }
- else{
- printf("%s FATFS mount OK,Fatfs init donern",DriverString[driver]);
- }
- res = Fatfs_getfree(driver);//计算当时SD的容量跟剩余大小
- if(res != FR_OK)
- {
- printf("%s FATFS get size Errorrn",DriverString[driver]);
- return 0;
- }
- else{
- printf("%s FATFS total size is %d,free size is %d.rn",DriverString[driver],totalsize,freesize);
- return 1;
- }
- }
- uint8_t Fatfs_getfree(uint8_t driver)
- {
- uint8_t res;
- FATFS *fs1;
- uint32_t fre_clust=0, fre_sect=0, tot_sect=0;
-
- char *Path;
- if(driver == SDCard)
- {
- Path = (char*)&SD_Path;
- }else if(driver == USBDisk)
- {
- Path = (char*)&UDisk_Path;
- }
- //得到磁盘信息及空闲簇数量
- res =(uint32_t)f_getfree((const TCHAR*)Path, (DWORD*)&fre_clust, &fs1);
- if(res==0)
- {
- tot_sect=(fs1->n_fatent-2)*fs1->csize; //得到总扇区数
- fre_sect=fre_clust*fs1->csize; //得到空闲扇区数
- #if _MAX_SS!=512 //扇区大小不是512字节,则转换为512字节
- tot_sect*=fs1->ssize/512;
- fre_sect*=fs1->ssize/512;
- #endif
- totalsize=tot_sect>>1; //单位为KB
- freesize=fre_sect>>1; //单位为KB
- }
- return res;
- }
- uint8_t Fatfs_open(uint8_t driver,uint8_t*path,uint8_t mode)
- {
- char filepath[50];
- memset(filepath,0,20);
- if(driver == SDCard)
- {
- strcat(filepath,SD_Path);
- }else if(driver == USBDisk)
- {
- strcat(filepath,UDisk_Path);
- }
- strcat((char*)filepath,(const char*)path);
- retSD=f_open(&openfile,(const TCHAR*)filepath,mode);//打开文件夹
- if(retSD != FR_OK)
- {
- printf("FATFS open Error:%drn",retSD);
- }
- else printf("FATFS open file[%s] ok!rn",filepath);
- return retSD;
- }
- uint8_t Fatfs_close(void)
- {
- retSD=f_close(&openfile);
- return retSD;
- }
- //读出数据
- //len:读出的长度
- //返回值:执行结果
- uint8_t Fatfs_read(uint8_t *data,uint32_t len)
- {
- uint16_t i;
- uint32_t tlen=0;
- uint32_t bytesread;
- uint8_t *pdata = data;
- for(i=0;i
- {
- retSD=f_read(&openfile,pdata,512,&bytesread);
- if(retSD)
- {
- printf("Read Error:%drn",retSD);
- break;
- }else
- {
- tlen+=bytesread;
- pdata += bytesread;
- }
- }
- if(len%512)
- {
- retSD=f_read(&openfile,pdata,len%512,&bytesread);
- if(retSD) //读数据出错了
- {
- printf("rnRead Error:%drn",retSD);
- }else
- {
- tlen+=bytesread;
- }
- }
- if(tlen)printf("rnReaded data len:%drn",tlen);//读到的数据长度
- printf("Read data overrn");
- return retSD;
- }
- //写入数据
- //data:数据缓存区
- //len:写入长度
- //返回值:执行结果
- uint8_t Fatfs_write(uint8_t *data,uint32_t len)
- {
- uint32_t byteswrite;
- printf("rnBegin Write file...rn");
- printf("Write data len:%drn",len);
- retSD=f_write(&openfile,data,len,&byteswrite);
- if(retSD)
- {
- printf("Write Error:%drn",retSD);
- }else printf("Writed data len:%drn",byteswrite);
- printf("Write data over.rn");
- return retSD;
- }
复制代码
好,到这我们就移植好了,我们开始在main函数里面,初始化,并挂载SD卡~
- while(Fatfs_init(SDCard)!=1)
- {
- printf("FATTS INI fail!rn");
- }
- printf("FATTS INI OK!rn");
-
复制代码
其中Fatfs_init(SDCard)里面会挂载,并打印一些SD卡的信息:
- //return 0:no sd card find
- //return 1: find sd card
- uint8_t Fatfs_init(uint8_t driver)
- {
- uint8_t res;
- FATFS *Fatfs;
- char *Path;
- Diskio_drvTypeDef *Driver;
- if(driver == SDCard)
- {
- Fatfs = &SDFatFs;
- Path = (char*)&SD_Path;
- Driver = &SD_Driver;
- }else if(driver == USBDisk)
- {
- // Fatfs = &USBfatfs;
- // Path = (char*)&UDisk_Path;
- // Driver = &USBH_Driver;
- }
- /*## FatFS: Link the SD driver ###########################*/
- res = FATFS_LinkDriver(Driver, Path);
- if(res != FR_OK)
- {
- printf("rn%s FATFS LinkDriver errorrn",DriverString[driver]);
- return 0;
- }
- else{
- printf("rn%s FATFS LinkDriver OK,Drive path is %srn",DriverString[driver],Path);
- }
- /*##-2- Register the file system object to the FatFs module ##############*/
- printf("%s FATFS mountrn",DriverString[driver]);
- res = f_mount(Fatfs, (TCHAR const*)Path, 0);
- if(res != FR_OK)
- {
- printf("%s FATFS mount Errorrn",DriverString[driver]);
- FATFS_UnLinkDriver(Path);
- return 0;
- }
- else{
- printf("%s FATFS mount OK,Fatfs init donern",DriverString[driver]);
- }
- res = Fatfs_getfree(driver);//计算当时SD的容量跟剩余大小
- if(res != FR_OK)
- {
- printf("%s FATFS get size Errorrn",DriverString[driver]);
- return 0;
- }
- else{
- printf("%s FATFS total size is %d,free size is %d.rn",DriverString[driver],totalsize,freesize);
- return 1;
- }
- }
复制代码
我们编译,下载程序~并插好SD卡~
查看串口输出:
好了,FATFS移植就到这儿了~
FATFS包:
使用的配置文件:
1
|
|
|
|