原创 SD卡的读写和FatFS文件系统

2010-8-9 14:13 5120 11 12 分类: MCU/ 嵌入式
因为要用,学习了一下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

  下面是我的代码:
https://static.assets-stash.eet-china.com/album/old-resources/2008/12/25/32461526-eae2-4c27-ad83-4bf2cd0eb5b0.rar
  其中底层的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, const u8 *buffer);           //写一个sector
u8 SD_ReadMultiBlock(u32 sector, u8 *buffer, u8 count);       //读多个sector
u8 SD_WriteMultiBlock(u32 sector, const u8 *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)
    {
        return STA_NOINIT;  //仅支持磁盘0的操作
    }

    state = SD_Init();
    if(state == STA_NODISK)
    {
        return STA_NODISK;
    }
    else if(state != 0)
    {
        return STA_NOINIT;  //其他错误:初始化失败
    }
    else
    {
        return 0;           //初始化成功
    }
}
  
  总之FATFS文件系统具有很高的可移植性,经测试,在STM32的18MSPI时钟下,读文件的速度在每秒300K以上,写文件也有100多K的速度,应该说基本满足了嵌入式工程应用中,对磁盘读写的速度要求。如果进一步优化SD卡读写代码,速度应该还会有一定提高,同时还要注意的是FLASH自身读写速度没有ram那么快,通过更换SD卡发现读写速度和卡本身有直接的关系,所以应该尽量选择速度较快的卡。
PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户1370325 2011-6-1 10:54

你的代码,咋编译不过去 Core\cortexm3_macro.s(19): error: A1163E: Unknown opcode RSEG , expecting opcode or Macro Core\cortexm3_macro.s(52): error: A1355U: A Label was found which was in no AREA
相关推荐阅读
用户89529 2010-09-25 17:03
stm32 malloc:动态分配内存函数
函数原型:void *malloc(unsigned size)头文件:#include<stdlib.h>是否是标准函数:是函数功能:动态分配一块内存空间,size为指定的分配空间的大小...
用户89529 2010-08-09 14:11
转一篇比较详细介绍FatFs文件系统移植的文章
FatFs文件系统的移植    因为需要,又不想自己写,所以就移植了一个文件系统。    说下我的硬件和开发工具:接成 TRUE IDE 模式下的CF卡(也就是相当于一块硬盘了),三星S3C2440的...
用户89529 2010-08-05 11:53
关于STM32的systick定时器的详细说明
我不得不说意法半导体确实有点风骚!甚至有点变态。我对ST文档 STM32F10XXX参考手册的编辑水平真是不敢恭维。手册中好多说明都是含糊不清,甚至将好多对初学者来说很重要的地方都一笔带过,让人着实摸...
用户89529 2010-05-11 19:40
stm32 fsmc数据地址线的关系
      stm32的fsmc接口设置的资料很少,所以现在对各个寄存器的具体应用还不是很明白,最近写了一个程序是把以前8位数据线读写sram的程序,改为16位数据线。有了一个小小的发现,现在把它写出...
用户89529 2010-05-07 11:59
stm32关于BOOT0和BOOT1
BOOT0和BOOT1STM32三种启动模式对应的存储介质均是芯片内置的,它们是:1)用户闪存 = 芯片内置的Flash。2)SRAM = 芯片内置的RAM区,就是内存啦。3)系统存储器 = 芯片内部...
EE直播间
更多
我要评论
1
11
关闭 站长推荐上一条 /3 下一条