STM32
直播中

杨帆

7年用户 1352经验值
私信 关注
[问答]

怎样去移植基于STM32F103的FATFS文件系统呢

怎样去移植基于STM32F103的FATFS文件系统呢?有哪些步骤?

回帖(1)

王燕

2021-12-13 13:46:33
首先准备一个例程,这里准备一个原子的SD_SDIO实验
  
  

  

  修改文件夹名称为FATFS,防止中文出错,编译下载,测试工程是否正确
  
  

  

  
  

  

  前往FATFS官网下载源码点击下载最新版
  
  

  

  工程目录下新建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:%drn",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:%drn",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..... rn");
                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:%drn",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] = '';                                                        //添加结束符,不添加结束符,会导致末尾多出乱
        printf("ERROR:%drnDATA:%srn",ff_rec,Test_Buff);                        //打印错误
               
        while(1)
        {
                LED1 =! LED1;
                delay_ms(500);
        };
}


  编译下载,下载,串口打印无错误
  
  

  

  查看SD卡内容,数据正确
  
  

  

  成功移植FATFS
   
  个人见解,感谢阅读。
举报

更多回帖

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