STM32笔记SD卡的读写和FatFS文件系统

【STM32笔记SD卡的读写和FatFS文件系统】因为要用 , 学习了一下SPI操作SD卡 , 同时移植了一个免费开源的FAT文件系统:FatFS 。感觉挺好 , 在单片机上实现了读写文件的操作 , 接下来就可以解释我的G代码咯!
我的SD卡底层操作参考了网上几种常见的代码 , 但又对其结构做了一定的优化 , 至少看起来用起来比较方便 。既可以作为文件系统的diskio使用 , 也可以直接使用底层函数 , 把SD卡作为一块flash读写 。
FatFs文件系统体积蛮小 , 6-7K足矣 , 对于128Kflash的STM32来说很合适 , 代价不大 。同时可移植性很高 , 最少只需要4个函数修改既可以实现文件系统的移植 。相关文件系统的介绍请看这里 。
这里给一套比较完整的参考资料 , 包括fatfs文件系统的原版资料、几个重要的手册和网上下载的代码 。
http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=3210864&bbs_page_no=1&bbs_id=3020

下面是我的代码:

其中底层的SPI总线对SD卡的操作在SPI_SD_driver.c/h中 , 而FATFS的移植文件diskio.c中对磁盘的操作函数中将调用底层的操作函数 。下面是一些底层操作函数:
u8 SPI_ReadWriteByte(u8 TxData);//SPI总线读写一个字节
u8 SD_WaitReady(void);//等待SD卡就绪
u8 SD_SendCommand(u8 cmd, u32 arg, u8 crc);//SD卡发送一个命令
u8 SD_SendCommand_NoDeassert(u8 cmd, u32 arg, u8 crc);//SD卡发送一个命令 , 不断线
u8 SD_Init(void);//SD卡初始化

u8 SD_ReceiveData(u8 *data, u16 len, u8 release);//SD卡读数据
u8 SD_GetCID(u8 *cid_data);//读SD卡CID
u8 SD_GetCSD(u8 *csd_data);//读SD卡CSD
u32 SD_GetCapacity(void);//取SD卡容量

u8 SD_ReadSingleBlock(u32 sector, u8 *buffer);//读一个sector
u8 SD_WriteSingleBlock(u32 sector,constu8 *buffer);//写一个sector
u8 SD_ReadMultiBlock(u32 sector, u8 *buffer, u8 count);//读多个sector
u8 SD_WriteMultiBlock(u32 sector,constu8 *data, u8 count);//写多个sector

这是diskio.c中的一段代码 , 在disk初始化中 , 我们调用了SPI_SD_driver.c中的SD卡初始化函数 。
DSTATUS disk_initialize (
BYTE drv/* Physical drive nmuber (0..) */
)
{
u8 state;

if(drv)
{
returnSTA_NOINIT;//仅支持磁盘0的操作
}

state = SD_Init();
if(state == STA_NODISK)
{
returnSTA_NODISK;
}
elseif(state !=0)
{
returnSTA_NOINIT;//其他错误:初始化失败
}
else
{
return0;//初始化成功
}
}

总之FATFS文件系统具有很高的可移植性 , 经测试 , 在STM32的18MSPI时钟下 , 读文件的速度在每秒300K以上 , 写文件也有100多K的速 度 , 应该说基本满足了嵌入式工程应用中 , 对磁盘读写的速度要求 。如果进一步优化SD卡读写代码 , 速度应该还会有一定提高 , 同时还要注意的是FLASH自身 读写速度没有ram那么快 , 通过更换SD卡发现读写速度和卡本身有直接的关系 , 所以应该尽量选择速度较快的卡 。

    推荐阅读