旗点科技星空派(GD32)
直播中

qjp1988113

12年用户 343经验值
擅长:测量仪表 嵌入式技术 处理器/DSP 控制/MCU EDA/IC设计
私信 关注
[GD32F303]

【星空派GD32F303开发板试用体验】+FATFS移植

今天我们移植下FATFS,让他显示SD卡当前容量~
先下载FATFS包,这里途径很多可用其他工程上的,直接拿来修改下就能用了。
我们先配置好SD卡,板上的SPI FLASH太小512K字节,就不使用了。
SD卡采用的SDIO接口,我们直接用给出的例程(gd32-f303-master3 例程Project16_SDIO_SDCardTest)。
编译下载,正常~(2.0的卡正常。这了用3.0新卡试验过。能读不能写,可能配置的速度不够,未去深究)
MM1.png
好,我们就在这个例子的基础上,移植FATFS,我们把包添加进工程:
ZZ1.png
并把头文件路径,包含进工程:
ZZ2.png
配置好后,我们对代码的一些初始化、读写等改成我们之前配置的SD的底层操作函数。我们主要对"sd_diskio.c"进行修改~
  1. /**
  2.   ******************************************************************************
  3.   * [url=home.php?mod=space&uid=1455510]@file[/url]    sd_diskio.c
  4.   * [url=home.php?mod=space&uid=40524]@author[/url]  MCD Application Team
  5.   * [url=home.php?mod=space&uid=644434]@version[/url] V1.3.0
  6.   * @date    08-May-2015
  7.   * [url=home.php?mod=space&uid=2666770]@Brief[/url]   SD Disk I/O driver
  8.   ******************************************************************************
  9.   * @attention
  10.   *
  11.   *

    © COPYRIGHT 2015 STMicroelectronics


  12.   *
  13.   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
  14.   * You may not use this file except in compliance with the License.
  15.   * You may obtain a copy of the License at:
  16.   *
  17.   *        http://www.st.com/software_license_agreement_liberty_v2
  18.   *
  19.   * Unless required by applicable law or agreed to in writing, software
  20.   * distributed under the License is distributed on an "AS IS" BASIS,
  21.   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  22.   * See the License for the specific language governing permissions and
  23.   * limitations under the License.
  24.   *
  25.   ******************************************************************************
  26.   */

  27. /* Includes ------------------------------------------------------------------*/
  28. #include
  29. #include "ff_gen_drv.h"
  30. #include "sdio_sdcard.h"
  31. #include "sdcard_user.h"

  32. /* Private typedef -----------------------------------------------------------*/
  33. /* Private define ------------------------------------------------------------*/
  34. /* Block Size in Bytes */
  35. #define BLOCK_SIZE                512

  36. /* Private variables ---------------------------------------------------------*/
  37. /* Disk status */
  38. static volatile DSTATUS Stat = STA_NOINIT;

  39. /* Private function prototypes -----------------------------------------------*/
  40. DSTATUS SD_initialize (BYTE);
  41. DSTATUS SD_status (BYTE);
  42. DRESULT SD_read (BYTE, BYTE*, DWORD, UINT);
  43. #if _USE_WRITE == 1
  44.   DRESULT SD_write (BYTE, const BYTE*, DWORD, UINT);
  45. #endif /* _USE_WRITE == 1 */
  46. #if _USE_IOCTL == 1
  47.   DRESULT SD_ioctl (BYTE, BYTE, void*);
  48. #endif  /* _USE_IOCTL == 1 */
  49.   
  50. const Diskio_drvTypeDef  SD_Driver =
  51. {
  52.   SD_initialize,
  53.   SD_status,
  54.   SD_read,
  55. #if  _USE_WRITE == 1
  56.   SD_write,
  57. #endif /* _USE_WRITE == 1 */
  58.   
  59. #if  _USE_IOCTL == 1
  60.   SD_ioctl,
  61. #endif /* _USE_IOCTL == 1 */
  62. };

  63. /* Private functions ---------------------------------------------------------*/

  64. /**
  65.   * @brief  Initializes a Drive
  66.   * [url=home.php?mod=space&uid=3142012]@param[/url]  lun : not used
  67.   * @retval DSTATUS: Operation status
  68.   */
  69. DSTATUS SD_initialize(BYTE lun)
  70. {
  71.   Stat = STA_NOINIT;
  72.   
  73.   /* Configure the uSD device */
  74.   if(sd_io_init() == SD_OK)
  75.   {
  76.     Stat &= ~STA_NOINIT;
  77.   }

  78.   return Stat;
  79. }

  80. /**
  81.   * @brief  Gets Disk Status
  82.   * @param  lun : not used
  83.   * @retval DSTATUS: Operation status
  84.   */
  85. DSTATUS SD_status(BYTE lun)
  86. {
  87.   Stat = STA_NOINIT;

  88.   if(sd_transfer_state_get() == SD_NO_TRANSFER)
  89.   {
  90.     Stat &= ~STA_NOINIT;
  91.   }
  92.   
  93.   return Stat;
  94. }

  95. /**
  96.   * @brief  Reads Sector(s)
  97.   * @param  lun : not used
  98.   * @param  *buff: Data buffer to store read data
  99.   * @param  sector: Sector address (LBA)
  100.   * @param  count: Number of sectors to read (1..128)
  101.   * @retval DRESULT: Operation result
  102.   */
  103. DRESULT SD_read(BYTE lun, BYTE *buff, DWORD sector, UINT count)
  104. {
  105.   DRESULT res = RES_OK;
  106.   
  107.   if(sd_multiblocks_read((uint32_t*)buff,
  108.                        (uint64_t) (sector * BLOCK_SIZE),
  109.                        BLOCK_SIZE,
  110.                        count) != SD_OK)
  111.   {
  112.     res = RES_ERROR;
  113.   }
  114.   
  115.   return res;
  116. }

  117. /**
  118.   * @brief  Writes Sector(s)
  119.   * @param  lun : not used
  120.   * @param  *buff: Data to be written
  121.   * @param  sector: Sector address (LBA)
  122.   * @param  count: Number of sectors to write (1..128)
  123.   * @retval DRESULT: Operation result
  124.   */
  125. #if _USE_WRITE == 1
  126. DRESULT SD_write(BYTE lun, const BYTE *buff, DWORD sector, UINT count)
  127. {
  128.   DRESULT res = RES_OK;
  129.   
  130.   if(sd_multiblocks_write((uint32_t*)buff,
  131.                         (uint64_t)(sector * BLOCK_SIZE),
  132.                         BLOCK_SIZE, count) != SD_OK)
  133.   {
  134.     res = RES_ERROR;
  135.   }
  136.   
  137.   return res;
  138. }
  139. #endif /* _USE_WRITE == 1 */

  140. /**
  141.   * @brief  I/O control operation
  142.   * @param  lun : not used
  143.   * @param  cmd: Control code
  144.   * @param  *buff: Buffer to send/receive control data
  145.   * @retval DRESULT: Operation result
  146.   */
  147. #if _USE_IOCTL == 1
  148. DRESULT SD_ioctl(BYTE lun, BYTE cmd, void *buff)
  149. {
  150.   DRESULT res = RES_ERROR;
  151. // SD_CardInfo CardInfo;
  152.   
  153.   if (Stat & STA_NOINIT) return RES_NOTRDY;
  154.   
  155.   switch (cmd)
  156.   {
  157.   /* Make sure that no pending write process */
  158.   case CTRL_SYNC :
  159.     res = RES_OK;
  160.     break;
  161.   
  162.   /* Get number of sectors on the disk (DWORD) */
  163.   case GET_SECTOR_COUNT :
  164.     card_info_get();
  165.     *(DWORD*)buff = sd_cardinfo.card_capacity / BLOCK_SIZE;
  166.     res = RES_OK;
  167.     break;
  168.   
  169.   /* Get R/W sector size (WORD) */
  170.   case GET_SECTOR_SIZE :
  171.     *(WORD*)buff = BLOCK_SIZE;
  172.     res = RES_OK;
  173.     break;
  174.   
  175.   /* Get erase block size in unit of sector (DWORD) */
  176.   case GET_BLOCK_SIZE :
  177.     *(DWORD*)buff = BLOCK_SIZE;
  178.     break;
  179.   
  180.   default:
  181.     res = RES_PARERR;
  182.   }
  183.   
  184.   return res;
  185. }
  186. #endif /* _USE_IOCTL == 1 */
  187.   
  188. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/




我们再创建一个文件用来写自己的一些FATFS的应用的函数:
fatfs_user.h
  1. #ifndef __FATFS_H
  2. #define __FATFS_H
  3. #include "gd32f30x.h"
  4. #include "ff.h"
  5. #include "ff_gen_drv.h"
  6. #include "sd_diskio.h" /* defines SD_Driver as external */

  7. enum{
  8.     USBDisk = 0,
  9.     SDCard
  10. };


  11. extern FIL openfile;
  12. extern uint32_t totalsize;
  13. extern uint32_t freesize;

  14. uint8_t Fatfs_init(uint8_t driver);
  15. uint8_t Fatfs_getfree(uint8_t driver);
  16. uint8_t Fatfs_open(uint8_t driver,uint8_t*path,uint8_t mode);
  17. uint8_t Fatfs_close(void);
  18. uint8_t Fatfs_read(uint8_t *data,uint32_t len);
  19. uint8_t Fatfs_write(uint8_t *data,uint32_t len);
  20. #endif //__FATFS_H
fatfs_user.c
  1. #include "fatfs_user.h"
  2. #include "usart.h"
  3. #include "stdbool.h"
  4. #include "string.h"
  5. uint32_t totalsize = 0;
  6. uint32_t freesize = 0;

  7. FIL openfile;
  8. FATFS SDFatFs = {0};
  9. char SD_Path[4]={0,0,0,0};

  10. FATFS USBfatfs;
  11. char UDisk_Path[4]={0,0,0,0};
  12. extern Diskio_drvTypeDef  USBH_Driver;
  13. uint8_t retSD; /* Return value for SD */

  14. const char* DriverString[2]={
  15.         {"USBDisk"},
  16.   {"SDCard"}
  17. };

  18. //return 0:no sd card find
  19. //return 1: find sd card
  20. uint8_t Fatfs_init(uint8_t driver)
  21. {
  22.         uint8_t res;
  23.   FATFS *Fatfs;
  24.   char *Path;
  25.   Diskio_drvTypeDef *Driver;

  26.   if(driver == SDCard)
  27.   {
  28.     Fatfs = &SDFatFs;
  29.     Path = (char*)&SD_Path;
  30.     Driver = &SD_Driver;
  31.   }else if(driver == USBDisk)
  32.   {
  33.   //  Fatfs = &USBfatfs;
  34. //   Path = (char*)&UDisk_Path;
  35.   //  Driver = &USBH_Driver;
  36.   }
  37.   /*## FatFS: Link the SD driver ###########################*/
  38.   res = FATFS_LinkDriver(Driver, Path);
  39.   if(res != FR_OK)
  40.   {
  41.     printf("rn%s FATFS LinkDriver errorrn",DriverString[driver]);
  42.     return 0;
  43.   }
  44.   else{
  45.     printf("rn%s FATFS LinkDriver OK,Drive path is %srn",DriverString[driver],Path);
  46.   }
  47.     /*##-2- Register the file system object to the FatFs module ##############*/
  48.     printf("%s FATFS mountrn",DriverString[driver]);
  49.     res = f_mount(Fatfs, (TCHAR const*)Path, 0);
  50.     if(res != FR_OK)
  51.     {
  52.       printf("%s FATFS mount Errorrn",DriverString[driver]);
  53.       FATFS_UnLinkDriver(Path);
  54.       return 0;
  55.     }
  56.     else{
  57.       printf("%s FATFS mount OK,Fatfs init donern",DriverString[driver]);
  58.     }
  59.   res =  Fatfs_getfree(driver);//计算当时SD的容量跟剩余大小
  60.   if(res != FR_OK)
  61.   {
  62.     printf("%s FATFS get size Errorrn",DriverString[driver]);
  63.     return 0;
  64.   }
  65.   else{
  66.     printf("%s FATFS  total size is %d,free size is %d.rn",DriverString[driver],totalsize,freesize);
  67.     return 1;
  68.   }
  69. }

  70. uint8_t Fatfs_getfree(uint8_t driver)
  71. {
  72.     uint8_t res;
  73.     FATFS *fs1;
  74.     uint32_t fre_clust=0, fre_sect=0, tot_sect=0;

  75.    char *Path;

  76.   if(driver == SDCard)
  77.   {
  78.     Path = (char*)&SD_Path;
  79.   }else if(driver == USBDisk)
  80.   {
  81.     Path = (char*)&UDisk_Path;
  82.   }

  83.     //得到磁盘信息及空闲簇数量
  84.     res =(uint32_t)f_getfree((const TCHAR*)Path, (DWORD*)&fre_clust, &fs1);
  85.     if(res==0)
  86.         {                                                                                          
  87.             tot_sect=(fs1->n_fatent-2)*fs1->csize;        //得到总扇区数
  88.             fre_sect=fre_clust*fs1->csize;                        //得到空闲扇区数          
  89. #if _MAX_SS!=512                                                                  //扇区大小不是512字节,则转换为512字节
  90.                 tot_sect*=fs1->ssize/512;
  91.                 fre_sect*=fs1->ssize/512;
  92. #endif          
  93.     totalsize=tot_sect>>1;        //单位为KB
  94.                 freesize=fre_sect>>1;        //单位为KB
  95.    }
  96.    return res;
  97. }

  98. uint8_t Fatfs_open(uint8_t driver,uint8_t*path,uint8_t mode)
  99. {
  100.   char  filepath[50];
  101.         memset(filepath,0,20);
  102.   if(driver == SDCard)
  103.   {
  104.       strcat(filepath,SD_Path);
  105.   }else if(driver == USBDisk)
  106.   {
  107.       strcat(filepath,UDisk_Path);
  108.   }
  109.   strcat((char*)filepath,(const char*)path);
  110.   retSD=f_open(&openfile,(const TCHAR*)filepath,mode);//打开文件夹
  111.   if(retSD != FR_OK)
  112.     {
  113.       printf("FATFS open Error:%drn",retSD);
  114.     }
  115.     else printf("FATFS open file[%s] ok!rn",filepath);
  116.   return retSD;
  117. }

  118. uint8_t Fatfs_close(void)
  119. {
  120.   retSD=f_close(&openfile);
  121.         return retSD;
  122. }

  123. //读出数据
  124. //len:读出的长度
  125. //返回值:执行结果
  126. uint8_t Fatfs_read(uint8_t *data,uint32_t len)
  127. {
  128.   uint16_t i;
  129.   uint32_t tlen=0;
  130.   uint32_t bytesread;
  131.   uint8_t *pdata = data;
  132.         for(i=0;i
  133.         {
  134.                 retSD=f_read(&openfile,pdata,512,&bytesread);
  135.                 if(retSD)
  136.                 {
  137.                         printf("Read Error:%drn",retSD);
  138.                         break;
  139.                 }else
  140.                 {
  141.                         tlen+=bytesread;
  142.       pdata += bytesread;
  143.                 }
  144.         }
  145.         if(len%512)
  146.         {
  147.                 retSD=f_read(&openfile,pdata,len%512,&bytesread);
  148.                 if(retSD)        //读数据出错了
  149.                 {
  150.                         printf("rnRead Error:%drn",retSD);   
  151.                 }else
  152.                 {
  153.                         tlen+=bytesread;
  154.                 }         
  155.         }
  156.         if(tlen)printf("rnReaded data len:%drn",tlen);//读到的数据长度
  157.         printf("Read data overrn");         
  158.         return retSD;
  159. }

  160. //写入数据
  161. //data:数据缓存区
  162. //len:写入长度
  163. //返回值:执行结果
  164. uint8_t Fatfs_write(uint8_t *data,uint32_t len)
  165. {
  166.   uint32_t byteswrite;                                            
  167.   printf("rnBegin Write file...rn");
  168.   printf("Write data len:%drn",len);         
  169.     retSD=f_write(&openfile,data,len,&byteswrite);
  170.     if(retSD)
  171.     {
  172.       printf("Write Error:%drn",retSD);   
  173.     }else printf("Writed data len:%drn",byteswrite);
  174.     printf("Write data over.rn");
  175.     return retSD;
  176. }
好,到这我们就移植好了,我们开始在main函数里面,初始化,并挂载SD卡~
  1.   while(Fatfs_init(SDCard)!=1)
  2.   {
  3.     printf("FATTS INI fail!rn");
  4.   }
  5.   printf("FATTS INI OK!rn");
  6.   
其中Fatfs_init(SDCard)里面会挂载,并打印一些SD卡的信息:
  1. //return 0:no sd card find
  2. //return 1: find sd card
  3. uint8_t Fatfs_init(uint8_t driver)
  4. {
  5.         uint8_t res;
  6.   FATFS *Fatfs;
  7.   char *Path;
  8.   Diskio_drvTypeDef *Driver;

  9.   if(driver == SDCard)
  10.   {
  11.     Fatfs = &SDFatFs;
  12.     Path = (char*)&SD_Path;
  13.     Driver = &SD_Driver;
  14.   }else if(driver == USBDisk)
  15.   {
  16.   //  Fatfs = &USBfatfs;
  17. //   Path = (char*)&UDisk_Path;
  18.   //  Driver = &USBH_Driver;
  19.   }
  20.   /*## FatFS: Link the SD driver ###########################*/
  21.   res = FATFS_LinkDriver(Driver, Path);
  22.   if(res != FR_OK)
  23.   {
  24.     printf("rn%s FATFS LinkDriver errorrn",DriverString[driver]);
  25.     return 0;
  26.   }
  27.   else{
  28.     printf("rn%s FATFS LinkDriver OK,Drive path is %srn",DriverString[driver],Path);
  29.   }
  30.     /*##-2- Register the file system object to the FatFs module ##############*/
  31.     printf("%s FATFS mountrn",DriverString[driver]);
  32.     res = f_mount(Fatfs, (TCHAR const*)Path, 0);
  33.     if(res != FR_OK)
  34.     {
  35.       printf("%s FATFS mount Errorrn",DriverString[driver]);
  36.       FATFS_UnLinkDriver(Path);
  37.       return 0;
  38.     }
  39.     else{
  40.       printf("%s FATFS mount OK,Fatfs init donern",DriverString[driver]);
  41.     }
  42.   res =  Fatfs_getfree(driver);//计算当时SD的容量跟剩余大小
  43.   if(res != FR_OK)
  44.   {
  45.     printf("%s FATFS get size Errorrn",DriverString[driver]);
  46.     return 0;
  47.   }
  48.   else{
  49.     printf("%s FATFS  total size is %d,free size is %d.rn",DriverString[driver],totalsize,freesize);
  50.     return 1;
  51.   }
  52. }
我们编译,下载程序~并插好SD卡~
查看串口输出:
ZZ3.png
好了,FATFS移植就到这儿了~
FATFS包:
FatFs.rar (502.57 KB)
(下载次数: 27, 2021-10-24 09:35 上传)

使用的配置文件:
FATFS_User.rar (7.27 KB)
(下载次数: 24, 2021-10-24 09:35 上传)



回帖(3)

jinglixixi

2021-10-31 15:23:06
在编译时报错,提示缺少“sys.h”,注释掉后又提示缺少“sdio_sdcard.h”,能否把这些文件也上传一下。
1 举报
  • qjp1988113: 好,这个其实一个就是数据类型的头文件定义,一个就是SD卡的底层驱动。

qjp1988113

2021-11-1 08:26:02
这个工程上传了~
举报

jinglixixi

2021-11-1 08:28:54
好的多谢了!                 
举报

更多回帖

发帖
×
20
完善资料,
赚取积分