首先声明下,本文只是个人学习记录,如有错误之处,请大家谅解并提出,大家一起讨论。。。。在此谢过。。。
第一次在开发板上移植文件系统,起初刚学SD卡时,使用的是直接在SD的某个地址中直接存取数据,很不方便理解和使用。比如说,有个朋友叫你帮他存个文档下,于是你存在某个SD卡的地址中,那下次你要读取这个文档的时候,你能想到这个文档数据存放在SD卡的那个地址中吗?。。。。。这就是我们为什么要移植文件系统的原因了。下面介绍下我的移植过程。
硬件:正点原子的MiniSTM32开发板,金士顿2G卡。
主函数
#include <stm32f10x_lib.h>
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "lcd.h"
#include "mmc_sd.h" //SD卡的驱动
#include "ff.h" //基本不需修改
#include "integer.h" //基本不需修改
#include "diskio.h" //底层函数
#include "ffconf.h" //配置函数
u8 state;
FATFS fs,fatfs;
FRESULT res;
FILINFO fileInfo;
UINT br;
u16 i;
DIR dir;
FIL file,file1;
char data[512];
char *buff = "hello";
char *hanzi = "你好";
int main(void){
Stm32_Clock_Init(9);//系统时钟设置
delay_init(72); //延时初始化
uart_init(72,9600);
LCD_Init();
//SD_Init();
POINT_COLOR=RED;//设置字体为红色
LCD_ShowString(60,50,"Mini STM32");
LCD_ShowString(60,70,"SD Card TEST");
LCD_ShowString(60,90,"ATOM@ALIENTEK");
LCD_ShowString(60,110,"2011/1/1");
while(SD_Init()!=0)//检测不到SD卡
{
LCD_ShowString(60,130,"SD Card Failed!");
delay_ms(500);
LCD_ShowString(60,130,"Please Check! ");
delay_ms(500);
// LED0=!LED0;//DS0闪烁
}
//检测SD卡成功
res = f_mount(0, &fs);
res = f_open(&file,"SD.txt",FA_CREATE_NEW);
res = f_open(&file1,"例子1.doc",FA_CREATE_NEW);
res = f_open(&file,"SD.txt",FA_WRITE);
f_puts((char *)buff,&file);
res = f_open(&file1,"例子1.doc",FA_WRITE);
f_puts((char *)hanzi,&file1);
f_puts((char *)buff,&file1);
f_close(&file);
f_close(&file1);
res = f_mkdir("例子2");
while(1)
{
;
}
}
我可以使用的版本是0.08.。。。
diskio.h文件只要看个人需要更改下这两句就可以了。
#define _READONLY 0 /* 1: Remove write functions */
#define _USE_IOCTL 1 /* 1: Use disk_ioctl fucntion */
diskio.c文件中的底层驱动函数,以自己的SD卡驱动有关,要根据自己的驱动来修改,下面是我自己的驱动,参考了他人的。
/*-----------------------------------------------------------------------*/
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2007 */
/*-----------------------------------------------------------------------*/
/* This is a stub disk I/O module that acts as front end of the existing */
/* disk I/O modules and attach it to FatFs module with common interface. */
/*-----------------------------------------------------------------------*/
#include "stm32f10x_lib.h"
#include "mmc_sd.h"
#include "diskio.h"
#include "ff.h"
/*-----------------------------------------------------------------------*/
/* Inidialize a Drive */
DSTATUS disk_initialize (
BYTE drv /* Physical drive nmuber (0..) */
)
{
/* u8 state;
state=SD_Init();
if(state==0){
return STA_SUCCESS;
}else if(state==1){
return STA_NOINIT;
}else if(state==99){
return STA_NODISK ;
}else{
return STA_NOINIT;
}
*/
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);
}
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;
}
/*-----------------------------------------------------------------------*/
/* User defined function to give a current time to fatfs module */
/* 31-25: Year(0-127 org.1980), 24-21: Month(1-12), 20-16: Day(1-31) */
/* 15-11: Hour(0-23), 10-5: Minute(0-59), 4-0: Second(0-29 *2) */
DWORD get_fattime (void)
{
DWORD date=0;
return date;
}
ffconf.h文件就看大家的使用情况了配置了。下面是我自己文件的。
/*---------------------------------------------------------------------------/
/ FatFs - FAT file system module configuration file R0.08a (C)ChaN, 2010
/----------------------------------------------------------------------------/
/
/ CAUTION! Do not forget to make clean the project after any changes to
/ the configuration options.
/
/----------------------------------------------------------------------------*/
#ifndef _FFCONF
#define _FFCONF 8255 /* Revision ID */
#define _FS_TINY 0 /* 0:Normal or 1:Tiny */
#define _FS_READONLY 0 /* 0:Read/Write or 1:Read only */
#define _FS_MINIMIZE 0 /* 0 to 3 */
#define _USE_STRFUNC 1 /* 0:Disable or 1/2:Enable */
#define _USE_MKFS 1 /* 0:Disable or 1:Enable */
#define _USE_FORWARD 0 /* 0:Disable or 1:Enable */
#define _USE_FASTSEEK 0 /* 0:Disable or 1:Enable */
#define _CODE_PAGE 932
#define _USE_LFN 0 /* 0 to 3 */
#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */
#define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */
#define _FS_RPATH 0 /* 0 to 2 */
#define _VOLUMES 1
#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */
#define _MULTI_PARTITION 0 /* 0:Single partition or 1:Multiple partition */
#define _USE_ERASE 0 /* 0:Disable or 1:Enable */
#define _WORD_ACCESS 0 /* 0 or 1 */
#define _FS_REENTRANT 0 /* 0:Disable or 1:Enable */
#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */
#define _SYNC_t HANDLE
#define _FS_SHARE 0 /* 0:Disable or >=1:Enable */
#endif /* _FFCONFIG */
这样就基本完成了FATFS的移植。至于他的使用可另外查找他的手册。
下面是显示的效果