打印
[研电赛技术支持]

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

[复制链接]
2524|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xiaoqi000|  楼主 | 2021-10-27 16:15 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
今天我们移植下fatfs,让他显示SD卡当前容量~
先下载FATFS包,这里途径很多可用其他工程上的,直接拿来修改下就能用了。
我们先配置好SD卡,板上的SPI FLASH太小512K字节,就不使用了。
SD卡采用的sdio接口,我们直接用给出的例程(gd32-f303-master\03 例程\Project\16_SDIO_SDCardTest)。
编译下载,正常~(2.0的卡正常。这了用3.0新卡试验过。能读不能写,可能配置的速度不够,未去深究)

使用特权

评论回复
沙发
xiaoqi000|  楼主 | 2021-10-27 16:16 | 只看该作者
好,我们就在这个例子的基础上,移植FATFS,我们把包添加进工程:

使用特权

评论回复
板凳
xiaoqi000|  楼主 | 2021-10-27 16:18 | 只看该作者
并把头文件路径,包含进工程:

使用特权

评论回复
地板
xiaoqi000|  楼主 | 2021-10-27 16:19 | 只看该作者
配置好后,我们对代码的一些初始化、读写等改成我们之前配置的SD的底层操作函数。我们主要对"sd_diskio.c"进行修改~

使用特权

评论回复
5
xiaoqi000|  楼主 | 2021-10-27 16:20 | 只看该作者
/**
  ******************************************************************************
  * [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
  * [url=home.php?mod=space&uid=212281]@date[/url]    08-May-2015
  * [url=home.php?mod=space&uid=2666770]@Brief[/url]   SD Disk I/O driver
  ******************************************************************************
  * @attention
  *
  * <h2><center>© COPYRIGHT 2015 STmicroelectronics</center></h2>
  *
  * 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 <string.h>
#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 ---------------------------------------------------------*/

/**
  * [url=home.php?mod=space&uid=247401]@brief[/url]  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****/

使用特权

评论回复
6
xiaoqi000|  楼主 | 2021-10-27 16:22 | 只看该作者
我们再创建一个文件用来写自己的一些FATFS的应用的函数:
fatfs_user.h

使用特权

评论回复
7
xiaoqi000|  楼主 | 2021-10-27 16:22 | 只看该作者
#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

使用特权

评论回复
8
xiaoqi000|  楼主 | 2021-10-27 16:23 | 只看该作者
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("\r\n%s FATFS LinkDriver error\r\n",DriverString[driver]);
    return 0;
  }
  else{
    printf("\r\n%s FATFS LinkDriver OK,Drive path is %s\r\n",DriverString[driver],Path);
  }
    /*##-2- Register the file system object to the FatFs module ##############*/
    printf("%s FATFS mount\r\n",DriverString[driver]);
    res = f_mount(Fatfs, (TCHAR const*)Path, 0);
    if(res != FR_OK)
    {
      printf("%s FATFS mount Error\r\n",DriverString[driver]);
      FATFS_UnLinkDriver(Path);
      return 0;
    }
    else{
      printf("%s FATFS mount OK,Fatfs init done\r\n",DriverString[driver]);
    }
  res =  Fatfs_getfree(driver);//计算当时SD的容量跟剩余大小
  if(res != FR_OK)
  {
    printf("%s FATFS get size Error\r\n",DriverString[driver]);
    return 0;
  }
  else{
    printf("%s FATFS  total size is %d,free size is %d.\r\n",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:%d\r\n",retSD);
    }
    else printf("FATFS open file[%s] ok!\r\n",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<len/512;i++)
        {
                retSD=f_read(&openfile,pdata,512,&bytesread);
                if(retSD)
                {
                        printf("Read Error:%d\r\n",retSD);
                        break;
                }else
                {
                        tlen+=bytesread;
      pdata += bytesread;
                }
        }
        if(len%512)
        {
                retSD=f_read(&openfile,pdata,len%512,&bytesread);
                if(retSD)        //读数据出错了
                {
                        printf("\r\nRead Error:%d\r\n",retSD);   
                }else
                {
                        tlen+=bytesread;
                }         
        }
        if(tlen)printf("\r\nReaded data len:%d\r\n",tlen);//读到的数据长度
        printf("Read data over\r\n");         
        return retSD;
}

//写入数据
//data:数据缓存区
//len:写入长度
//返回值:执行结果
uint8_t Fatfs_write(uint8_t *data,uint32_t len)
{
  uint32_t byteswrite;                                             
  printf("\r\nBegin Write file...\r\n");
  printf("Write data len:%d\r\n",len);         
    retSD=f_write(&openfile,data,len,&byteswrite);
    if(retSD)
    {
      printf("Write Error:%d\r\n",retSD);   
    }else printf("Writed data len:%d\r\n",byteswrite);
    printf("Write data over.\r\n");
    return retSD;
}

使用特权

评论回复
9
xiaoqi000|  楼主 | 2021-10-27 16:24 | 只看该作者
好,到这我们就移植好了,我们开始在main函数里面,初始化,并挂载SD卡~

使用特权

评论回复
10
xiaoqi000|  楼主 | 2021-10-27 16:25 | 只看该作者
 while(Fatfs_init(SDCard)!=1)
  {
    printf("FATTS INI fail!\r\n");
  }
  printf("FATTS INI OK!\r\n");

使用特权

评论回复
11
xiaoqi000|  楼主 | 2021-10-27 16:25 | 只看该作者
其中Fatfs_init(SDCard)里面会挂载,并打印一些SD卡的信息:

使用特权

评论回复
12
xiaoqi000|  楼主 | 2021-10-27 16:26 | 只看该作者
//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("\r\n%s FATFS LinkDriver error\r\n",DriverString[driver]);
    return 0;
  }
  else{
    printf("\r\n%s FATFS LinkDriver OK,Drive path is %s\r\n",DriverString[driver],Path);
  }
    /*##-2- Register the file system object to the FatFs module ##############*/
    printf("%s FATFS mount\r\n",DriverString[driver]);
    res = f_mount(Fatfs, (TCHAR const*)Path, 0);
    if(res != FR_OK)
    {
      printf("%s FATFS mount Error\r\n",DriverString[driver]);
      FATFS_UnLinkDriver(Path);
      return 0;
    }
    else{
      printf("%s FATFS mount OK,Fatfs init done\r\n",DriverString[driver]);
    }
  res =  Fatfs_getfree(driver);//计算当时SD的容量跟剩余大小
  if(res != FR_OK)
  {
    printf("%s FATFS get size Error\r\n",DriverString[driver]);
    return 0;
  }
  else{
    printf("%s FATFS  total size is %d,free size is %d.\r\n",DriverString[driver],totalsize,freesize);
    return 1;
  }
}

使用特权

评论回复
13
xiaoqi000|  楼主 | 2021-10-27 16:26 | 只看该作者
我们编译,下载程序~并插好SD卡~
查看串口输出:

使用特权

评论回复
14
xiaoqi000|  楼主 | 2021-10-27 16:31 | 只看该作者
好了,FATFS移植就到这儿了~

使用特权

评论回复
15
yanzhengxin1| | 2021-11-5 15:41 | 只看该作者
用rtthread

使用特权

评论回复
16
hua_ren| | 2021-11-8 11:43 | 只看该作者
挂载SD卡的教程,最近也在研究这个,不错的东西,做产品很实用。

使用特权

评论回复
17
redone| | 2021-11-8 16:15 | 只看该作者
非常不错啊~~赞

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

45

主题

671

帖子

0

粉丝