首先准备一个例程,这里准备一个原子的SD_SDIO实验
修改文件夹名称为FATFS,防止中文出错,编译下载,测试工程是否正确
前往FATFS官网下载源码 http://elm-chan.org/fsw/ff/00index_e.html 点击下载最新版
工程目录下新建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:%d\r\n",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:%d\r\n",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..... \r\n");
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:%d\r\n",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] = '\0'; //添加结束符,不添加结束符,会导致末尾多出乱
printf("ERROR:%d\r\nDATA:%s\r\n",ff_rec,Test_Buff); //打印错误
while(1)
{
LED1 =! LED1;
delay_ms(500);
};
}
编译下载,下载,串口打印无错误
查看SD卡内容,数据正确
成功移植FATFS
个人见解,感谢阅读。