网上关于小型嵌入式的文件体系有许多~当然要数 FATFS 很是知名 一来细巧,二来免费。当然了国产的振南的znFAT 相同开源好用并且极端的省资源~!十分合适51单片。更重要的是国语的支撑,呵呵!这次在STM32上为SD卡移植文件体系仍是十分简略顺畅的,这多亏了ST 官方供给的驱动,而我自己不必着手编写SD卡的指令省了许多时刻并且官方做的驱动尽管功率一般可是极端谨慎我很是敬服。
FATFS的官方网站是
http://elm-chan.org/fsw/ff/00index_e.html
znFAT的官方网站是
http://www.znmcu.cn/softshow.asp?id=47
SD卡能够用SPI驱动 也能够直接用 SDIO 驱动 STM32 256KB FLASH 以上的片子悉数都有SDIO,咱们当然要用高速方便的SDIO 方法了!至于 SDIO 又有 1位 4位 8 位的之分 我想不来8位SDIO 是怎么回事?SD卡上最多只能接4位嘛~网上有人说4位的SDIO 不好用多半是固件版别太老的原因了。呵呵这儿仍是要靠库~STM32真合适懒人用。
网上关于的FATFS 的文章许多 不过都太老旧,许多东西现已不适用了 。我主张阁下到官方去下载最新的版别 现在是最新是R0.08b ,运用最新的版别优点是许多网上许多要改来改去的当地只需你运用了新版别那便是彻底能够躲避的。别的STM32 的SDIO驱动也必定要用最新的,老版别问题许多不少人的失利就在这。我这次用的是V3.3的库没有任何改动就能够了,现在最新的好像在3.4以上了。好了说说移植 ffconf.h是装备的头文件 简略的修正宏就能够了,英文注释的很彻底并且网上也有翻译我不多说了自己看http://www.openrtos.cn/fatfs首要在这儿进行功用裁剪写写我的装备。
#define _FS_TINY 0 /* 0:Normal or 1:Tiny 完好的FATFS 精简版的是Tiny */
#define _FS_READONLY 0 /* 0:Read/Write or 1:Read only 能读能写*/
#define _FS_MINIMIZE 1 /* 0 to 3 简略的裁剪f_mkdir, f_chmod..这些功用没法用的*/
/* The _FS_MINIMIZE option defines minimization level to remove some functions.
/
/ 0: Full function.
/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename
/ are removed.
/ 2: f_opendir and f_readdir are removed in addition to 1.
/ 3: f_lseek is removed in addition to 2. */
#define _USE_STRFUNC 0 /* 0:Disable or 1/2:Enable是否运用字符串文件接口 */
/* To enable string functions, set _USE_STRFUNC to 1 or 2. */
#define _USE_MKFS 0 /* 0:Disable or 1:Enable 制造文件体系我在PC上一般现已格式化好了*/
/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */
#define _USE_FORWARD 0 /* 0:Disable or 1:Enable 发文件流?*/
/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */
#define _USE_FASTSEEK 0 /* 0:Disable or 1:Enable 查找*/
/* To enable fast seek feature, set _USE_FASTSEEK to 1. */
#define _CODE_PAGE 1 / /1 – ASCII only (Valid for non LFN cfg.)
#define _USE_LFN 0 /* 0 to 3 */
#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) 这些都是长文件名或是汉字文件支撑很费资源所以不敞开这些*/
#define _FS_SHARE 0 /* 0:Disable or >=1:Enable 不运用相对路径*/
#define _FS_SHARE 0 /* 0:Disable or >=1:Enable 文件同享多任务的操作体系会用到的*/
#define _FS_REENTRANT 0 /* 0:Disable or 1:Enable 这些是啥用?同步什么呢?默许就好了*/
#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */
#define _SYNC_t HANDLE /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */
integer.h首要界说了文件的类型 若是最新的能够不必修正。
好了 说说最要害的I/O module 我自己树立一个文件diskio.c新的版别要自己树立函数文件官方连个模板都没供给作者好像不怎么照料新人呢~
都说要移植5个函数 其实两个就足以了。
/*———————————————————————–*/
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2011 */
/*———————————————————————–*/
/* 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 "diskio.h"
#include "stm32f10x.h"
#include "stm32_eval_sdio_sd.h"
#define BLOCK_SIZE 512 /* Block Size in Bytes */
/*———————————————————————–*/
/* Inidialize a Drive */
DSTATUS disk_initialize (
BYTE drv /* Physical drive nmuber (0..) */
)
{
SD_Error Status;
/* Supports only single driveFATFS支撑多个设备 所以有个设备号drive nmuber当然了我就一个SD卡所以只要零号 */
if (drv)
{
return STA_NOINIT;
}
/*————————– SD Init —————————– */
Status = SD_Init();
if (Status!=SD_OK )
{
return STA_NOINIT;
}
else
{
return RES_OK;
}
}
/*———————————————————————–*/
/* Return Disk Status */
DSTATUS disk_status (
BYTE drv /* Physical drive nmuber (0..) */
)
{
return RES_OK; //懒的管了 有空写写 能够加个
}
/*———————————————————————–*/
/* 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) 读取的扇区数*/
)
{
// SD_Error Status;
if (count > 1)
{
SD_ReadMultiBlocks(buff, sector*BLOCK_SIZE, BLOCK_SIZE, count); //扇区地址*512便是实践地址 默许一个扇区便是512个字节
}
else
{
SD_ReadBlock(buff, sector*BLOCK_SIZE, BLOCK_SIZE);
}
return RES_OK;
}
/*———————————————————————–*/
/* 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) */
)
{
if (count > 1)
{
SD_WriteMultiBlocks((uint8_t *)buff, sector*BLOCK_SIZE, BLOCK_SIZE, count);
/*这儿我们看到了有个地址转化 由于DMA只是支撑4字节指针的所以在函数内部仍是有个转化的这儿最好优化一下能进步功率*/
}
else
{
SD_WriteBlock((uint8_t *)buff,sector*BLOCK_SIZE, BLOCK_SIZE);
}
return RES_OK;
}
#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 若是用到擦除函数这个函数必定要补完的有空再写写吧我这简略的回来就好了*/
)
{
return RES_OK;
}
/*———————————————————————–*/
/* Get current time */
/*———————————————————————–*/
DWORD get_fattime(void)
{
return ((2011UL-1980) << 25) // Year = 2011
| (3UL << 21) // Month = Mar
| (26UL << 16) // Day = 26
| (13U << 11) // Hour = 13
| (19U << 5) // Min =19
| (0U >> 1) // Sec = 0
;
}
终究无优化编译后 :Program Size: Code=10904 RO-data=336 RW-data=56 ZI-data=2304
RO是程序中的指令和常量
RW是程序中的已初始化变量
ZI是程序中的未初始化的变量
我觉得这个巨细关于STM32103FZE来说彻底能够承受。