开端移植fatfs遇到了许多问题,很是苦恼啊,移植成功思来之不易,特共享一下经历。硬件是STM32F103RBT6内存只需20kB,Flash只需128KB,考虑到内存有限,就不能支撑长文件名了,在原子论坛上下载的所以要改动,在此感谢原子论坛给我带来的协助还有安富莱论坛http://bbs.armfly.com/read.php?tid=3601给我带来的启示。别的硬件还有一个大的相机的SD卡,网上买的模块当然也能够自己焊接一个,选用SPI接口,SPI1和SPI2都行,看图
移植前做了很多预备,在网上尤其是原子论坛翻看各种其他人移植的心得,去fatfs的官方网站下载0.10版别的程序,看各种相关的移植心得,文档版别很多,目不暇接,花了点时刻看了看一些函数。看得差不多了,就直接把0.10的版别考到自己的工程目录下开端make,通过很多的翻阅和实践,要动的当地只需diskio.c和ffconfig.h,第一个需求把底层驱动函数sd_inti();增加进去。sd卡的读单块和读多块,写单块写多块填进去,ffconfig.h里面需求改几个宏界说的值参照他人的例程就能够完成很简单。
DSTATUS disk_initialize (
BYTE drv/* Physical drive nmuber (0..) */
)
{
u8 state;
state=SD_Init();
if(!state){
return STA_NODISK;
}
return 0;
}
/*———————————————————————–*/
/* Return Disk Status */
DSTATUS disk_status (
BYTE drv/* Physical drive nmuber (0..) */
)
{return 0;
}
/*———————————————————————–*/
/* Read Sector(s) */
DRESULT disk_read (
BYTE drv,/* Physical drive nmuber (0..) */
BYTE *buff,/* Data buffer to store read data */
DWORD sector,/* Sector address (LBA) */
BYTE count/* Number of sectors to read (1..255) */
)
{
u8 res=0;
if(count==1) //1个sector的读操作
{
res = SD_ReadSingleBlock(sector, buff);
//res= SD_ReadDisk(buff,sector,count);
}
else //多个sector的读操作
{
res = SD_ReadMultiBlock(sector, buff, count);
}
//处理回来值,将SPI_SD_driver.c的回来值转成ff.c的回来值
if(res == 0x00)
{
return RES_OK;
}
else
{
return RES_ERROR;
}
}
/*———————————————————————–*/
/* Write Sector(s) */
#if _READONLY == 0
DRESULT disk_write (
BYTE drv,/* Physical drive nmuber (0..) */
const BYTE *buff,/* Data to be written */
DWORD sector,/* Sector address (LBA) */
BYTE count/* Number of sectors to write (1..255) */
)
{
u8 res;
// 读写操作
if(count == 1)
{
res = SD_WriteSingleBlock(sector, buff);;
}
else
{
res = SD_WriteMultiBlock(sector, buff, count);
}
// 回来值转化
if(res == 0)
{
return RES_OK;
}
else
{
return RES_ERROR;
}
}
#endif /* _READONLY */
/*———————————————————————–*/
/* Miscellaneous Functions */
DRESULT disk_ioctl (
BYTE drv,/* Physical drive nmuber (0..) */
BYTE ctrl,/* Control code */
void *buff/* Buffer to send/receive control data */
)
{
DRESULT res;
if (drv)
{
return RES_PARERR; //仅支撑单磁盘操作,不然回来参数过错
}
//FATFS现在版别仅需处理CTRL_SYNC,GET_SECTOR_COUNT,GET_BLOCK_SIZ三个指令
switch(ctrl)
{
case CTRL_SYNC:
res=RES_OK;
break;
case GET_BLOCK_SIZE:
*(WORD*)buff = 512;
res = RES_OK;
break;
case GET_SECTOR_COUNT:
*(DWORD*)buff = SD_GetCapacity();
res = RES_OK;
break;
default:
res = RES_PARERR;
break;
}
return res;
}
以上代码是参照网友的,当然原子的也没有问题。只需底层没有问题基本上,应用层就不会有问题。怎么判别底层函数呢?在不加fatfs前盯梢调试一下看是否初始化能成功和其他的寄存器值是否能读成功。
在sd卡底层没有问题的情况下再做应用层函数的编写。
我在移植时没有运用内存管理机制,所以卡了好几天,一向以为是底层问题,可是读sd卡肯定没有问题,还能播映MP3呢。找不到问题所在头就大,后来在论坛上留言总算网友点醒了我,本来在界说FATFS *FS;是需求分配内存的,听说空间分配有两种方法一个是数组,另一个是界说指针,界说指针时要运用malloc分配内存还要free开释内存,而我界说了fatfs结构的指针没有分配内存,形成回来值FR_NO_FILESYSTEM,/* (13) There is no valid FAT volume */,后来我改成fatfs fs;还有一个问题sd卡的挂载驱动号是1 ,我写0res= f_mount(&fs,(TCHAR*)0,1); /* Mount a logical drive */;的时分老回来FR_INVALID_DRIVE,/* (11) The logical drive number is invalid */挂载失利。假如你也遇到这个问题主张改成res= f_mount(&fs,(TCHAR*)1,1);这种方式就行了,可是翻开文件和读文件内容时还要这么写
res=exf_getfree(“0:”,&nCapacity,&free);//得到SD卡的总容量和剩下容量
res=f_open(&file, “0:/test.txt”, FA_OPEN_EXISTING|FA_READ);
res=f_read (
&file, /* Pointer to the file object */
buffer,/* Pointer to data buffer */
512,/* Number of bytes to read */
&br/* Pointer to number of bytes read */
) ;
好了,废话不多说,把main函数应用层代码张贴出来
FATFS fs;
FIL file; //文件1
FIL ftemp; //文件2.
UINT br,bw;//读写变量
FILINFO fileinfo;//文件信息
DIR dir;
FILINFO fileInfo;
UINT br,bw;