




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
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. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年藏文化研究专业考试卷及答案简介
- 兽药残留分析技术进展资料
- 我的成长故事童年趣事与感悟14篇范文
- 在动物园的一天:记事作文9篇
- 员工信息及在职状况证明(7篇)
- 2025年铝压延加工材项目提案报告模板
- 2025年芳香保健师(中级)职业技能鉴定试题:实践操作
- 2025年初中化学九年级上册期中测试卷难易度分析
- 论网络利弊的议论文议论文(9篇)
- 品牌塑造案例分析
- 平阴县2023-2024学年度七年级第二学期期末学习诊断检测语文试题含答案
- 福建省厦门市2022-2023学年高一下学期期末考试语文试题(解析版)
- 在线网课知道智慧《人工智能(复旦)》单元测试考核答案
- 大学生职业生涯规划园艺专业
- 使用单位特种设备安全风险管控清单
- 乳腺结核课件
- 音乐与电影-《功夫》音乐赏析
- 小学科学湘科版六年级下册全册同步练习含答案
- 天津大洋宁夏隆德万头高端肉牛全产业链建设项目环境影响报告书
- 壮医药水蛭疗法
- 中药熏蒸的护理
评论
0/150
提交评论