【青风带你学stm32f051系列教程】第15课 文件系统操作SD卡

作者: 青风
上传时间为: 2013-03-05 07:35 PM

很多单片机系统都需要大容量存储设备,以存储数据。目前常用的有U盘,FLASH芯片,SD卡等。他们各有优点,综合比较,最适合单片机系统的莫过于SD卡了,它不仅容量可以做到很大(32Gb以上),而且支持SPI接口,方便移动,有几种体积的尺寸可供选择(标准的SD卡尺寸,以及TF卡尺寸),能满足不同应用的要求。只需要4个IO口,就可以外扩一个最大达32GB以上的外部存储器,容量选择尺度很大,更换也很方便,而且方便移动,编程也比较简单,是单片机大容量外部存储器的首选。

FATFS是一个专为小型嵌入式系统调计的通用文件系统模块。FATFS是用ANSI C(标准C语言)相兼容的语法书写,并且完全地实现了与磁盘IO层分离,因此它是与硬件无关的。它完全不需要任何修改就能被集成到低成本的微控器(MCU)中,与WINDOWS FAT相兼容的文件系统。与平台无关,便于移植。对代码存储器的大小和运行时所需RAM的大小及其它硬件性能要求很低,所以FATFS可以很好地运用在低成本的嵌入式系统中。

移植的版本为:FatFs_vR0.08a,本节是在上一节直接操作SD卡的基础上进行的,下面就从软硬件两个方面入手详细分析如何移植FATFA文件系统。

硬件准备:

如下图所示:

端口配置:

开发板中采用了较为小的msd卡作为存储卡,这是由于msd卡的使用较为广泛,有取代SD卡的趋势。通信方式采用SPI接口方式,连接如下:

硬件连接:

PB15-----SD_CS sd卡片选管脚

PB14------SD_OUT sd卡MISO端口

PB13------SD_DIN sd卡MOSI端口

PB12------SD_SCK sd卡sck管脚

软件准备:

下面我们来看看FATFS的移植过程,首先要介绍下FATFS的基本结构:

我们下载FATFS_VR0.08版本如下所示:

这个文件包里包含了这个几个文件:

00readme.txt :这个文件主要是对其他的几个文件功能进行说明,以及整个FATFS的版本信息。这个文件可有可无。

下面4个函数是主要的使用函数:

diskio.c:底层磁盘的操作函数,这些函数需要用户自己实现

ff.c独立于底层介质操作文件的函数,完全由ANSI C编写

integer.h 一些数值类型的定义

ffconf.h fatfs调用的基本配置

我们看看其文件结构图:

这个文件系统是分层而成的,对于用户层,我们只需要修改接口文件就可以直接和硬件相结合,

如下图所示:

我们需要修改的只有diskio.c和ffconf.h 函数,这两个函数和硬件对接就OK了,而文件夹option内提供了一些文字函数,比如说CC936支持汉字。

我们把上面文件夹内容移植入KEIL建立工程树如下,我们需要加入工程树的文件为ff.c , diskio.c 这两个函数:

我们主要需要编写diskio.c函数,在原来文件加入SD卡的操作函数,如下面所示:

[c]

DSTATUS disk_initialize ( BYTE drv /* Physical drive nmuber (0..) */ ) { SD_Error res = SD_RESPONSE_FAILURE; res = SD_Init(); //用户直接初始化SD return ((DSTATUS)res); DSTATUS disk_status ( BYTE drv /* Physical drive nmuber (0) */ ) { if (drv) return STA_NOINIT; /* Supports only single drive */ return 0; //返回磁盘状态 } 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_ReadBlock(buff, sector << 9, 512);//读扇区 return RES_OK; } #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) */ ) { SD_WriteBlock((BYTE *)buff, sector << 9,512);//写扇区 return RES_OK; } #endif /* _READONLY */

[/c]

上面加入的函数在SD.H函数中编写,上一节内容里面已经讲过,所示在函数的头文件里,我们需要加入#include "sd.h",如下所示:

[c]</pre> #include "diskio.h" #include "stm32f0xx.h" #include "ffconf.h" #include "sd.h"

[/c]

同时我们进入到ffconf.h文件中,在这个文件中,我们需要加入支持中文字符,修改

[c]</pre> #define _CODE_PAGE 936 <pre> [/c]

936为汉字码,修改的同时我们在工程中加入cc936.c函数。

那么这时FATFS系统文件基本移植完成,那么我们使用的时候就可以不管硬件问题,直接调用FATFS接口函数:

应用层程序接口如下:

f_mount - 注册和取消工作区

f_open - 打开或者创建文件

f_close -关闭一个文件

f_read - 从文件中读取数据

f_write -向 文件中写入数据

f_lseek - 移动文件读指针(RP),扩展文件大小

f_truncate - 缩减文件大小

f_sync - 清空缓存数据,实现数据同步

f_opendir - 打开一个目录

f_readdir - 列举目录中的条目(包括文件和子目录)。

f_getfree - 获取可用簇

f_stat - 获取文件属性

f_mkdir - 创建文件

f_unlink - 删除文件或者目录

f_chmod - 更改属性

f_utime -更改时间戳

f_rename - 重命名或者移动一个文件或目录

f_mkfs - 格式化磁盘

f_forward - 将文件数据直接送入数据流中

f_chdir - 改变当前所在目录

f_chdrive - 改变当前所在驱动器

f_gets -读字符串

f_putc - 写一个字符

f_puts - 写字符串

f_printf - 写入一个格式化字符串

磁盘I/O接口:

disk_initialize - 磁盘初始化

disk_status - 获取磁盘属性

disk_read - 读扇区

disk_write - 写扇区

disk_ioctl - 独立的磁盘控制资源

get_fattime - 获取时间

这些接口命令在ff.c函数中被定义了。也就是说这里面用户可以不用改变其中内容,它与硬件层没有关系,是独立的文件系统,也就是说只有移植过来就可以了。这些函数基本上就可以完成SD卡的相关操作,可以在主函数里进行使用,如下程序所示:

[c]

LCD_init(); // 液晶显示器初始化 LCD_Clear(ORANGE); // 全屏显示白色 POINT_COLOR =BLACK; // 定义笔的颜色为黑色 BACK_COLOR = WHITE ; // 定义笔的背景色为白色 /*-------------------------- SD Init ----------------------------- */ disk_initialize(0); LCD_ShowString(20,20, "mmc/sd 演示"); res = f_mount(0, &fs); if(res == FR_OK) LCD_ShowString(20,40, "mmc/sd 初始化成功 "); else LCD_ShowString(20,40, "mmc/sd 初始化失败");

res=f_open(&fsrc,"12-29.txt",FA_CREATE_ALWAYS | FA_WRITE); if (res == FR_OK) LCD_ShowString(20,60, "文件创建成功 "); else LCD_ShowString(20,60, "文件创建失败");

res = f_write(&fsrc, &w_buffer, countof(w_buffer), &bw);

if (res == FR_OK) LCD_ShowString(20,80, "SD卡写成功 "); else LCD_ShowString(20,80, "SD卡写失败");

res=f_close(&fsrc); if (res == FR_OK) LCD_ShowString(20,100, "文本关闭成功 "); else LCD_ShowString(20,100, "文本关闭失败");

res=f_open(&fsrc,"12-29.TXT",FA_READ); if (res == FR_OK) LCD_ShowString(20,120, "打开文本成功 "); else LCD_ShowString(20,120, "打开文本失败"); res = f_read(&fsrc, &buffer, 1024, &br); if (res == FR_OK) { LCD_ShowString(20,140, "文件读取成功"); LCD_ShowString(20,160, buffer); } else LCD_ShowString(20,140, "读文件失败 ");

[/c]

所以这样看来,SD卡的FATFS文件的移植和使用还是很简单的,不过要详细理解文件系统的编写机制还需要读者多多研究了。

实验下载现象:

MINISD卡插入后的测试结果在触摸屏TFT上显示如下所示:

全部评论 ()

创建讨论帖子

登录 后参与评论
系统提示