STM32移植FATFS

移植步骤

A、获取FATFS源代码

说明

可到官网下载:http://elm-chan.org/fsw/ff/00index_e.html

B、解压FATFS源代码包

说明

解压会得到两个文件夹:doc(文档)和src(源码)

C、建立STM32工程,在工程项目中添加两个目录:sd和fatfs

说明

sd存放sd卡底层驱动代码

fatfs存放源码包解压得到的src目录中所有.c和.h文件

提示

建议重定义printf函数至串口,方便调试

D、对diskio.c文件中以下六个函数进行编辑(移植)

函数定义

DSTATUS disk_initialize (BYTE);//SD卡的初始化

DSTATUS disk_status (BYTE);//获取SD卡的状态,这里可以不用管

DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE);//从SD卡读取数据

DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE);//将数据写入SD卡,若该文件系统为只读文件系统则不用实现该函数

DRESULT disk_ioctl (BYTE, BYTE, void*);//获取SD卡文件系统相关信息

DWORD get_fattime(void); // 获取时间???

提示

函数编辑的参考代码在文档最末列出

E、总结:按照以上步骤前期的移植过程就完成,后续根据实际情况进行综合调试

F、参考代码

----------------------------------------------------------------------------------------------------------------------------

DSTATUS disk_initialize (

BYTE pdrv /* Physical drive nmuber to identify the drive */

)

{

DSTATUS stat;

int result;

 

switch (pdrv){

case 0 :

stat = sd_init();

// sd_init函数就是sd初始化函数,由sd底层驱动提供

// disk_initialize函数就是接口,保证FATFS的可移植性

if(stat==0)

return RES_OK;

else

return STA_NOINIT;

case 1 :

return RES_OK;

case 2 :

return RES_OK;

case 3 :

return RES_OK;

default:

return STA_NOINIT;

}

return STA_NOINIT;

}

----------------------------------------------------------------------------------------------------------------------------

DRESULT disk_read (

BYTE pdrv, /* Physical drive nmuber to identify the drive */

BYTE *buff, /* Data buffer to store read data */

DWORD sector, /* Start sector in LBA */

UINT count /* Number of sectors to read */

)

{

int status;

if( !count ){ // arguments validate

return RES_PARERR;

}

switch (pdrv){

case 0:

status = SD_ReadDisk(buff,sector,count);

// SD_ReadDisk函数是sd卡底层驱动函数

if(status == 0)

return RES_OK;

else

return RES_ERROR;

case 1:

if(count==1)

return RES_OK;

else

return RES_OK;

default:

return RES_ERROR;

}

return RES_PARERR;

}

----------------------------------------------------------------------------------------------------------------------------

DRESULT disk_write (

BYTE pdrv, /* Physical drive nmuber to identify the drive */

const BYTE *buff, /* Data to be written */

DWORD sector, /* Start sector in LBA */

UINT count /* Number of sectors to write */

)

{

int status;

if( !count ){ // ´«²ÎÑéÖ¤

return RES_PARERR;

}

switch(pdrv){

case 0:

status = SD_WriteDisk((u8 *)buff,sector,count);

if(status == 0)

return RES_OK;

else

return RES_ERROR;

case 1:

if(count==1)

return RES_OK;

else

return RES_OK;

default:

return RES_ERROR;

}

return RES_PARERR;

}

----------------------------------------------------------------------------------------------------------------------------

// 改函数是一个杂类函数,常规性功能都可通过该函数进行实现(要移植)

DRESULT disk_ioctl (

                BYTE drv,                /* Physical drive nmuber (0..) */

                BYTE ctrl,                /* Control code */

                void *buff                /* Buffer to send/receive control data */

        )

        {

                if (drv==0)

                {   

                        MSD0_GetCardInfo(&SD0_CardInfo);

                        switch (ctrl)

                        {

                                case CTRL_SYNC :

                                        return RES_OK;

                                case GET_SECTOR_COUNT :

                                      *(DWORD*)buff = SD0_CardInfo.Capacity/SD0_CardInfo.BlockSize;

                                return RES_OK;

                                case GET_BLOCK_SIZE :

                                        *(WORD*)buff = SD0_CardInfo.BlockSize;

                                return RES_OK;        

                                case CTRL_POWER :

                                        break;

                                case CTRL_LOCK :

                                        break;

                                case CTRL_EJECT :

                                        break;

                        /* MMC/SDC command */

                                case MMC_GET_TYPE :

                                        break;

                                case MMC_GET_CSD :

                                        break;

                                case MMC_GET_CID :

                                        break;

                                case MMC_GET_OCR :

                                        break;

                                case MMC_GET_SDSTAT :

                                        break;        

                        }

            }else if(drv==1){

                        switch (ctrl)

                        {

                                case CTRL_SYNC :

                                        return RES_OK;

                                case GET_SECTOR_COUNT :

                                return RES_OK;

                                case GET_SECTOR_SIZE :

                                        return RES_OK;

                              case GET_BLOCK_SIZE :

                                return RES_OK;        

                                case CTRL_POWER :

                                        break;

                                case CTRL_LOCK :

                                        break;

                                case CTRL_EJECT :

                                        break;

                        /* MMC/SDC command */

                                case MMC_GET_TYPE :

                                        break;

                                case MMC_GET_CSD :

                                        break;

                                case MMC_GET_CID :

                                        break;

                                case MMC_GET_OCR :

                                        break;

                                case MMC_GET_SDSTAT :

                                        break;        

                        }         

                }

                else{                                 

                        return RES_PARERR;  

                }

                return RES_PARERR;

        }

----------------------------------------------------------------------------------------------------------------------------

// 空函数,没有改空函数会报错,调试有必要实现时,再做详细了解

DWORD get_fattime(void){

return 0;

}

----------------------------------------------------------------------------------------------------------------------------

// 获取SD卡状态,该函数这里参考代码未实现,实现方式参考上面的代码

DSTATUS disk_status (

BYTE pdrv /* Physical drive nmuber to identify the drive */

)

{

DSTATUS stat;

int result;

 

switch (pdrv) {

case DEV_RAM :

// result = RAM_disk_status();

 

// translate the reslut code here

 

return stat;

 

case DEV_MMC :

// result = MMC_disk_status();

 

// translate the reslut code here

 

return stat;

 

case DEV_USB :

// result = USB_disk_status();

 

// translate the reslut code here

 

return stat;

}

return STA_NOINIT;

}

----------------------------------------------------------------------------------------------------------------------------

常用函数

FATFS fs ;

DIR dirs ;

FILINFO finfo ;

FIL fil ;

FRESULT res ;

 

unsigned char rbuffer[512] ;

unsigned char wbuffer[]="xxxxx" ;

 

unsigned int br ;

unsigned int bw ;

 

disk_initialize(0);

// 初始化磁盘,调用Fatfs文件系统内 diskio.c 文件 ;

f_mount(0,&fs);

// 为设备创建一个挂载点,0为本地设备号(Logical drive number),&fs为本地设备的挂载点(Pointer to the work area);

f_mount(0,NULL);

// 卸载已经创建的挂载点,在操作完成后一定要卸载相应的挂载点;

f_mkdir("/xxx");

// 在根目录上创建一个名为‘xxx’的文件夹,'/'代表根目录,该操作的输入函数是字符串或者字符串数组;

f_opendir(&dirs,"/xxx");

// 打开在根目录上的‘xxx’文件夹,并将信息保存在dirs指向的地方;

f_readdir(&dirs,&finfo);

// 读取dirs指向的文件夹的信息,将相应的信息保存在finfo指向结构体;

f_open(&fil,"/xxx/xx.txt", --------------);

FA_READ // 读文件预指令,用f_read(); 函数读取;

FA_WRITE // 写文件预指令,用f_write();函数写入;

FA_OPEN_EXISTING // 打开文件条件属性,如果该文件不存在则打开失败(此属性为默认属性);

FA_OPEN_ALWAYS // 打开文件条件属性,如果该文件不存在则创建同名文件;

FA_CREATE_NEW // 创建文件属性,创建对应文件名的新文件;

FA_CREATE_ALWAYS // 创建文件属性,创建对应文件名的新文件,如相同文件名的文件存在则覆盖原文件;

// 常用方式 FA_CREATE_NEW , FA_OPEN_EXISTING | FA_WRITE , FA_OPEN_EXISTING | FA_READ

f_write(&fil,wbuffer,sizeof(wbuffer),&bw); // 在mdk测试下有一些问题,在博客里可以看到

f_read (&fil,rbuffer,sizeof(rbuffer),&br); //

f_close(&fil); // 关闭文件,每次打开都必须关闭文件

你可能感兴趣的:(STM32)