一、准备工作
(1)一个可以实现SD的初始化和读写磁盘的基本工程
(2)FATFS源码下载
FatFs - Generic FAT Filesystem Module (elm-chan.org)
二、移植
(1) 新建文件夹FATFS,将源码中source目录下的文件全部放入
(2)keil工程下新建分组,加入所有.c文件,并添加路径
(3)打开ffconf.h文件,找到对应宏并修改以下参数
#define FF_CODE_PAGE 936 //默认支持日文,改为936以支持简体中文
#define FF_USE_LFN 1 //是否使用长文件名,修改为1,使用静态区BSS存储,最长文件名为255个字符
(4)修改diskio.c文件为以下代码
/*-----------------------------------------------------------------------*/
/* Low level disk I/O module SKELETON for FatFs (C)ChaN, 2019 */
/*-----------------------------------------------------------------------*/
/* If a working storage control module is available, it should be */
/* attached to the FatFs via a glue function rather than modifying it. */
/* This is an example of glue functions to attach various exsisting */
/* storage control modules to the FatFs module with a defined API. */
/*-----------------------------------------------------------------------*/
#include "ff.h" /* Obtains integer types */
#include "diskio.h" /* Declarations of disk functions */
#include "sdio_sdcard.h"
/* Definitions of physical drive number for each drive */
#define DEV_RAM 1 /* Example: Map Ramdisk to physical drive 0 */
#define DEV_MMC 0 /* Example: Map MMC/SD card to physical drive 1 */
#define DEV_USB 2 /* Example: Map USB MSD to physical drive 2 */
/*-----------------------------------------------------------------------*/
/* Get Drive Status */
/*-----------------------------------------------------------------------*/
DSTATUS disk_status (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
switch (pdrv)
{
case DEV_RAM :
break;
case DEV_MMC :
return 0;
case DEV_USB :
break;
}
return STA_NOINIT;
}
/*-----------------------------------------------------------------------*/
/* Inidialize a Drive */
/*-----------------------------------------------------------------------*/
DSTATUS disk_initialize (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
int result;
switch (pdrv)
{
case DEV_RAM :
break;
case DEV_MMC :
result = SD_Init();
if(result==0)
return 0;
break;
case DEV_USB :
break;
}
return STA_NOINIT;
}
/*-----------------------------------------------------------------------*/
/* Read Sector(s) */
/*-----------------------------------------------------------------------*/
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 */
)
{
int result;
switch (pdrv)
{
case DEV_RAM :
break;
case DEV_MMC :
result=SD_ReadDisk(buff,sector,count);
while(result)//读出错
{
SD_Init(); //重新初始化SD卡
result=SD_ReadDisk(buff,sector,count);
//printf("sd rd error:%d\r\n",res);
}
return 0;
case DEV_USB :
break;
}
return RES_PARERR;
}
/*-----------------------------------------------------------------------*/
/* Write Sector(s) */
/*-----------------------------------------------------------------------*/
#if FF_FS_READONLY == 0
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 */
)
{
int res;
switch (pdrv)
{
case DEV_RAM :
break;
case DEV_MMC :
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);
}
return 0;
case DEV_USB :
break;
}
return RES_PARERR;
}
#endif
/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions */
/*-----------------------------------------------------------------------*/
DRESULT disk_ioctl (
BYTE pdrv, /* Physical drive nmuber (0..) */
BYTE cmd, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
int res;
switch (pdrv)
{
case DEV_RAM :
break;
case DEV_MMC :
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;
}
return 0;
case DEV_USB :
break;
}
return RES_PARERR;
}
DWORD get_fattime (void)
{
return 0;
}
三、测试移植情况
main.c
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "key.h"
#include "sdio_sdcard.h"
#include "ff.h"
#include "string.h"
int main(void)
{
u8 key;
u32 sd_size;
u8 buf[512]={0};
FATFS fs;
FIL file;
char *text="我是某某某ksfjsakjfkasdfjklsads\0";
FRESULT result;
unsigned int bw;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
uart_init(115200); //初始化串口波特率为115200
while(SD_Init())//检测不到SD卡
{
printf("SD Card Error!\r\n");
delay_ms(1000);
}
printf("SD Card OK\r\n");
result = f_mount(&fs,"0:",1);
printf("f_mount %d\r\n",result);
result = f_open(&file, "0:FatFs读写测试文件.txt",FA_CREATE_ALWAYS | FA_WRITE );
printf("f_open %d\r\n",result);
if ( result == FR_OK )
{
printf("》打开/创建FatFs读写测试文件.txt文件成功,向文件写入数据。\r\n");
/* 将指定存储区内容写入到文件内 */
result=f_write(&file,text,strlen(text),&bw);
if(result==FR_OK)
{
printf("》文件写入成功,写入字节数据:%d\r\n",bw);
printf("》向文件写入的数据为:\r\n%s\r\n",text);
}
else
{
printf("!!文件写入失败:\n");
}
f_close(&file);/* 不再读写,关闭文件 */
}
result = f_mount(&fs,"0:",1);
printf("f_mount %d\r\n",result);
while(1)
{
}
}
四、测试结果
完整工程代码
链接:https://pan.baidu.com/s/1ZdwXVfNDOwMfTbCtBoz4tg?pwd=8888
提取码:8888