1 添加下列文件至项目列表并包含头文件。
主要有以下几个文件 : diskio.c ffconf.h
1 官方源码已经有写好的代码框架,只需要添加ATA(指SD卡)部分即可
(1) 获取设备状态部分,由于SD卡起始状态特别多,此处默认检测到SD卡设备。
case ATA :
//默认设备检测成功
status &= ~STA_NOINIT;
break;
(2) 设备初始化部分,调用sdio.c中的初始化函数即可。
case ATA :
if(SD_Init()==SD_OK)
{
status &= ~STA_NOINIT;
}
else
{
status = STA_NOINIT;
}
break;
(3) 读扇区部分,由于SD卡读写时采用DMA,必须4字节对齐,当读缓冲区地址不是4字对齐时,必须特殊处理,先用disk_read()将数据读取至双字对齐的自定义数组中,然后利用memcpy()将数组的值复制至读数据缓冲区。当读缓冲区地址是4字对齐时,直接调用SD_ReadMultiBlocks() 读取即可。
case ATA :
if((DWORD)buff&3)
{
DRESULT res = RES_OK;
DWORD scratch[SD_BLOCKSIZE / 4];
while (count--)
{
res = disk_read(ATA,(BYTE *)scratch, sector++, 1);
if (res != RES_OK)
{
break;
}
memcpy(buff, scratch, SD_BLOCKSIZE);
buff += SD_BLOCKSIZE;
}
status = res;
}
else
{
SD_state=SD_ReadMultiBlocks(buff,(uint64_t)sector*SD_BLOCKSIZE,SD_BLOCKSIZE,count);
if(SD_state==SD_OK)
{
/* Check if the Transfer is finished */
SD_state=SD_WaitReadOperation();
while(SD_GetStatus() != SD_TRANSFER_OK);
}
if(SD_state!=SD_OK)
status = RES_PARERR;
else
status = RES_OK;
}
break;
(4)写扇区部分,原理同读。
case ATA :
if((DWORD)buff&3)
{
DRESULT res = RES_OK;
DWORD scratch[SD_BLOCKSIZE / 4];
while (count--)
{
memcpy( scratch,buff,SD_BLOCKSIZE);
res = disk_write(ATA,(BYTE *)scratch, sector++, 1);
if (res != RES_OK)
{
break;
}
buff += SD_BLOCKSIZE;
}
status = res;
}
else
{
SD_state=SD_WriteMultiBlocks((uint8_t *)buff,(uint64_t)sector*SD_BLOCKSIZE,SD_BLOCKSIZE,count);
if(SD_state==SD_OK)
{
/* Check if the Transfer is finished */
SD_state=SD_WaitWriteOperation();
/* Wait until end of DMA transfer */
while(SD_GetStatus() != SD_TRANSFER_OK);
}
if(SD_state!=SD_OK)
status = RES_PARERR;
else
status = RES_OK;
}
break;
(5)杂项参数配置。
case ATA :
switch (cmd)
{
// Get R/W sector size (WORD)
case GET_SECTOR_SIZE :
*(WORD * )buff = SD_BLOCKSIZE;
break;
// Get erase block size in unit of sector (DWORD)
case GET_BLOCK_SIZE :
*(DWORD * )buff = 1;
break;
case GET_SECTOR_COUNT:
*(DWORD * )buff = SDCardInfo.CardCapacity/SDCardInfo.CardBlockSize;
break;
case CTRL_SYNC :
break;
}
status = RES_OK;
break;
至此diskio.c移植完成
需要修改的参数如下:
//准许使用文件字符串函数: f_gets(), f_putc(), f_puts() and/ f_printf()
#define _USE_STRFUNC 1
//支持格式化函数f_mkfs()
#define _USE_MKFS 1
//支持使用长文件名
#define _USE_LFN 2
#define _MAX_LFN 255
//使用UTF-8编码
#define _STRF_ENCODE 3
//设备数目
#define _VOLUMES 1
//支持最小最大扇区字节数
#define _MIN_SS 512
#define _MAX_SS 4096
//文件时间配置
#define _FS_NORTC 0
#define _NORTC_MON 1
#define _NORTC_MDAY 1
#define _NORTC_YEAR 2015