stm32 Fatfs 读写SD卡_第1页
stm32 Fatfs 读写SD卡_第2页
stm32 Fatfs 读写SD卡_第3页
stm32 Fatfs 读写SD卡_第4页
stm32 Fatfs 读写SD卡_第5页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、stm32 Fatfs 读写SD卡读写SD是嵌入式系统中一个比较基础的功能,在很多应用中都可以用得上SD卡。折腾了几天,总算移植成功了 最新版Fatfs(Fatfs R0.09) ,成功读写SD卡下文件。    FatFs (/fsw/ff/00index_e.html)是一个通用的文件系统模块,用于在小型嵌入式系统中实现FAT文件系统。 FatFs 的编写遵循ANSI C,因此不依赖于硬件平台。它可以嵌入到便宜的微控制器中,如 8051, PIC, AVR, SH, Z80, H8, ARM 等等,不需要做任何修改。 1. S

2、D卡/TF卡 硬件接口 SD卡有两种操作接口,SDIO和SPI。 使用SDIO口的速度比较快,SPI的速度比较慢 。     SD卡引脚描述如下:                          SD卡SPI接法如下:  我使用的是正点原子的开发板,所以采用的是SPI接口的模式。     TF卡SDIO 模式和SPI模式 引脚定义:&#

3、160;        可以发现Micro SD卡只有8个引脚是因为比SD卡少了一个Vss。使用TF转SD的卡套套在Micro SD卡上,这样一来大小就和SD卡一样大,这时候卡套上的9个引脚就和SD卡一样了,你可以完全当做SD卡来操作。 2. SD卡底层驱动 SD卡的操作比较复杂,需要多看看一些文档 。 这里附上SD底层驱动代码,代码说明详见注释 Sd卡SPi操作底层代码 : sdcard.c  sdcard.h3. Fatfs 移植 FatFs 软件包中相关文件:

4、         ffconf.h     FatFs 模块配置文件        ff.h            FatFs 和应用模块公用的包含文件        ff.c           &

5、#160;FatFs 模块        diskio.h     FatFs and disk I/O 模块公用的包含文件        integer.h   数据类型定义        option      可选的外部功能      

6、;  diskio.c     FatFs 与disk I/O 模块接口层文件(不属于 FatFs 需要由用户提供) FatFs 配置,文件系统的配置项都在 ffconf.h 文件之中:         (1) _FS_TINY :这个选项在R0.07 版本之中开始出现,在之前的版本都是以独立的文件出现,现在通过一个宏来修改使用起来更方便;        (

7、2) _FS_MINIMIZE、_FS_READONLY、_USE_STRFUNC、_USE_MKFS、_USE_FORWARD 这些宏是用来对文件系统进行裁剪        (3) _CODE_PAGE :本选项用于设置语言码的类型        (4) _USE_LFN :取值为03,主要用于长文件名的支持及缓冲区的动态分配:              

8、  0:不支持长文件名;                1:支持长文件名存储的静态分配,一般是存储在BSS 段;                2:支持长文件名存储的动态分配,存储在栈上;                3:支持长文件名存储的动态分配,存储在堆上。 &#

9、160;      (5) _MAX_LFN :可存储长文件的最大长度,其值一般为(12255),但是缓冲区一般占(_MAX_LFN + 1) * 2 bytes;        (6) _LFN_UNICODE :为1 时才支持unicode 码;        (7) _FS_RPATH :R0.08a 版本改动配置项,取值范围02:   &#

10、160;            0:去除相对路径支持和函数;                1:开启相对路径并且开启f_chdrive()和f_chdir()两个函数;            

11、0;   2:在1 的基础上添加f_getcwd()函数。        (8) _VOLUMES :支持的逻辑设备数目;        (9) _MAX_SS :扇区缓冲的最大值,其值一般为512;        (10) _MULTI_PARTITION:定义为1 时,支持磁盘多个分区;   &

12、#160;    (11) _USE_ERASE :R0.08a 新加入的配置项,设置为1 时,支持扇区擦除;        (12) _WORD_ACCESS :如果定义为1,则可以使用word 访问;        (13) _FS_REENTRANT :定义为1 时,文件系统支持重入,但是需要加上跟操作系统信号量相关的几个函数,函数在syscall.c 文件中;  

13、60;     (14) _FS_SHARE :文件支持的共享数目。 Fatfs 开源文件系统 从R0.07e 之后 版本开始就不再提供底层接口文件 diskio.c 模板,这里附上根据以上SD卡底层驱动对应的 diskio.c 源码: 001#include "common.h"002/*-*/003/* Inidialize a Drive             

14、0;                                      */004 005DSTATUS disk_initialize (006    BYTE 

15、;drv                /* Physical drive nmuber (0.) */007)008009    u8 state;010 011    if(drv)012    013        retu

16、rn STA_NOINIT;  /仅支持磁盘0的操作014    015 016    state = SD_Init();017    if(state = STA_NODISK)018    019        return STA_NODISK;020    0

17、21    else if(state != 0)022    023        return STA_NOINIT;  /其他错误:初始化失败024    025    else026    027      &#

18、160; return 0;           /初始化成功028    029030 031 032 033/*-*/034/* Return Disk Status                   &

19、#160;                                */035 036DSTATUS disk_status (037    BYTE drv     

20、60;  /* Physical drive nmuber (0.) */038)039040    if(drv)041    042        return STA_NOINIT;  /仅支持磁盘0操作043    044 045    /检查SD卡是否插入046  &#

21、160; if(!SD_DET()047    048        return STA_NODISK;049    050    return 0;051052 053 054 055/*-*/056/* Read Sector(s)        

22、60;                                               */057 058DRESUL

23、T disk_read (059    BYTE drv,       /* Physical drive nmuber (0.) */060    BYTE *buff,     /* Data buffer to store read data */061    DWORD sector,   

24、/* Sector address (LBA) */062    BYTE count      /* Number of sectors to read (1.255) */063)064065    u8 res=0;066    if (drv | !count)067       068   

25、;     return RES_PARERR;  /仅支持单磁盘操作,count不能等于0,否则返回参数错误069    070    if(!SD_DET()071    072        return RES_NOTRDY;  /没有检测到SD卡,报NOT READY错误073&

26、#160;   074 075     076     077    if(count=1)            /1个sector的读操作     078       

27、0;                                           079      &

28、#160; res = SD_ReadSingleBlock(sector, buff);     080                                    &

29、#160;              081    else                    /多个sector的读操作    082   &#

30、160;                                               083  

31、;      res = SD_ReadMultiBlock(sector, buff, count);084                                    

32、;               085    /*086    do                         &

33、#160;087                                             088   &

34、#160;    if(SD_ReadSingleBlock(sector, buff)!=0)089                                      &

35、#160;      090            res = 1;                          091   

36、;         break;                            092           &#

37、160;                                 093        buff+=512;      &

38、#160;                     094    while(-count);                     &#

39、160;                  095    */096    /处理返回值,将SPI_SD_driver.c的返回值转成ff.c的返回值097    if(res = 0x00)098    099    

40、    return RES_OK;100    101    else102    103        return RES_ERROR;104    105106 107 108 109/*-*/110/* Write Sector(s)  &

41、#160;                                                 &

42、#160;  */111 112#if _READONLY = 0113DRESULT disk_write (114    BYTE drv,           /* Physical drive nmuber (0.) */115    const BYTE *buff,   /* Data to be written *

43、/116    DWORD sector,       /* Sector address (LBA) */117    BYTE count          /* Number of sectors to write (1.255) */118)119120    u8 res;121

44、 122    if (drv | !count)123       124        return RES_PARERR;  /仅支持单磁盘操作,count不能等于0,否则返回参数错误125    126    if(!SD_DET()127  

45、0; 128        return RES_NOTRDY;  /没有检测到SD卡,报NOT READY错误129    130 131    / 读写操作132    if(count = 1)133    134       

46、60;res = SD_WriteSingleBlock(sector, buff);135    136    else137    138        res = SD_WriteMultiBlock(sector, buff, count);139    140    / 返回值转换141  

47、;  if(res = 0)142    143        return RES_OK;144    145    else146    147        return RES_ERROR;148   

48、 149150#endif /* _READONLY */151 152 153 154/*-*/155/* Miscellaneous Functions                                 

49、0;             */156 157DRESULT disk_ioctl (158    BYTE drv,       /* Physical drive nmuber (0.) */159    BYTE ctrl,     

50、0;/* Control code */160    void *buff      /* Buffer to send/receive control data */161)162163    DRESULT res;164 165 166    if (drv)167       168 

51、60;      return RES_PARERR;  /仅支持单磁盘操作,否则返回参数错误169    170     171    /FATFS目前版本仅需处理CTRL_SYNC,GET_SECTOR_COUNT,GET_BLOCK_SIZ三个命令172    switch(ctrl)173   

52、60;174    case CTRL_SYNC:175        SD_CS_ENABLE();176        if(SD_WaitReady()=0)177        178          

53、;  res = RES_OK;179        180        else181        182            res = RES_ERROR;183    

54、;    184        SD_CS_DISABLE();185        break;186         187    case GET_BLOCK_SIZE:188      

55、60; *(WORD*)buff = 512;189        res = RES_OK;190        break;191 192    case GET_SECTOR_COUNT:193        *(DWORD*)buff = SD_GetCapacity();194&

56、#160;       res = RES_OK;195        break;196    default:197        res = RES_PARERR;198        break;199   &#

57、160;200 201    return res;202203 204/*-*/205/* User defined function to give a current time to fatfs module          */206/* 31-25: Year(0-127 org.1980), 24-21: Month(1-12), 20-16: Day(1-31) */    

58、60;                                                 

59、60;                                                 

60、60;                                                 

61、60;                                                 

62、60;                            207/* 15-11: Hour(0-23), 10-5: Minute(0-59), 4-0: Second(0-29 *2) */          &

63、#160;                                                 &

64、#160;                                                 &

65、#160;                                                 &

66、#160;                                                 &

67、#160;                            208DWORD get_fattime (void)209210  return 0;211这里的结构函数为Fatfs提供和SD卡的通信接口。 在 最新版本的Fatfs中还加入了对中文文件名的支持,需要修改 &#

68、160;ffconf.h        #define _CODE_PAGE    936   /- Simplified Chinese GBK (DBCS, OEM, Windows) 同时应该添加  option/cc936.c文件。但是这个文件有700多K占相当大的ROM, 像stm32F103RBT6这种小FLASH的MCU根本不行 ,加入当前工程文件中代码将增加160KB 左右。 配置好Stm32的串口和SPI等IO口设置后,就可以使用Fatfs做一些文件操作了。

69、 4. Fatfs 文件操作 文件分配表FAT(File AllocationTable)用来记录文件所在位置的表格.它对于硬盘的使用是非常重要的,假若丢失文件分配表,那么硬盘上的数据就会因无法定位而不能使用了。  Fatfs 文件系统减轻了操作SD卡的工作量,调用其提供的函数就可以方便的操作文件,读写删改等。这里提供一个main.c 示例:001#include "common.h"002#include <string.h>003 004FRESULT scan_files (char* path);005&

70、#160;006#define  F_PUTS         1       /测试向文件写入字符串007#define  F_READ         1       /测试从文件中读出数据008#define  F_UNLINK    

71、0;  0       /测试删除文件009#define  SCAN_FILES     1       /测试目录扫描010 011FATFS fs;012FRESULT res;013FIL file;                 

72、;     014UINT br;015BYTE buffer4096;              /以上变量作为全局变量 可以避免一些Bug016 017int main(void)018019    u16 i,n;   020     021&

73、#160;022    /stm32 初始化    023    RCC_Configuration();024    NVIC_Configuration();      025    USART_Configuration();026    SPI_Configuration();027

74、0;   GPIO_Configuration();028 029 030    /fatfs 操作031 032    f_mount(0, &fs);033 034    /如果data.txt存在,则打开;否则,创建一个新文件035    res = f_open(&file, "0:/data.txt",FA_OP

75、EN_ALWAYS|FA_READ|FA_WRITE );036 037    if(res!=FR_OK)038    039        printf("rn f_open() fail . rn");040    else041        printf("rn f_o

76、pen() success . rn");042    043 044#if F_READ045 046    while(1)                              &

77、#160;     /使用f_read读文件047        res = f_read(&file, buffer, 1, &br);     /一次读一个字节知道读完全部文件信息048 049        if (res = FR_OK )050    &

78、#160;   051            printf("%s",buffer);052        else053            printf("rn f_read() fail . rn");

79、  054        055 056        if(f_eof(&file) break;057    058 059    /*if( f_gets(buffer,sizeof(buffer),&file) != NULL)   /使用f_gets读文件  ,存

80、在 Bugs 待调试060    061        printf("%s",buffer);062    else063        printf("rn f_gets() fail . rn");  064     */065 066#end

81、if067 068#if F_PUTS069 070    /将指针指向文件末071    /res = f_lseek(&file,(&file)->fsize);072    res = f_lseek(&file,file.fsize);   073 074    n = f_puts("rn hello dog .rn"

82、, &file) ;  /向文件末写入字符串075                           076    if(n<1)  /判断写是否成功       

83、                077                                 

84、60;                       078        printf("rn f_puts() fail . rn");           

85、                                 079    else080        printf("rn f_pu

86、ts() success . rn");081    082  083#endif084 085#if F_UNLINK086 087    res = f_unlink("test.jpg");    /前提SD下存在一个test.jpg088 089    if(res!=FR_OK)090    091 

87、;       printf("rn f_unlink() fail . rn");092    else093        printf("rn f_unlink() success . rn");094    095 096#endif097 098#if SCAN_FILES099 100&

88、#160;   printf("rn the directory files : rn");101    scan_files("/");          /扫描根目录102 103#endif104 105    f_close(&file);106    f_mount(0,

89、 NULL);107 108    while(1);109110 111 112FRESULT scan_files (113    char* path        /* Start node to be scanned (also used as work area) */114)115116    FRESULT res;117    FILINFO fno;118    DIR dir;119    int i;120    char *fn;   /* This function is assuming non-Unicode cfg. */121#if _USE_LFN122    static char lfn_MAX_LF

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论