贡献我的FAT32文件系统代码以及相关资料,里面还有我的代码库,大家可以拾掇一下

2020-01-26 12:53发布

经过一个多星期的努力,把以前写的文件系统的功能拓展了一下,也只是完成了核心的任意读写的功能

现在把代码献给大家,希望大家喜欢

介绍介绍功能:
fread和fwrite是核心的功能(个人这个认为的)另外还有fseek,可以读写任意目录下的文件(创建和删除文件的功能我还没写)的任意字节

其实网上很多代码都有这些功能,那么这个代码有哪些不同?(感觉我好像在推销产品 = = )(让菜鸟自夸一下,勿喷哈~)

1. 每个文件内部花了16个字节去维护了一个簇链,如果有一个好几M的文件在物理分布上是连续的,那么,如果你是一直顺序读这个文件,会很流畅,不需要

去读FAT表,也就是速度会快一点,(而且fread本来是基于缓存的,但是我留出了一种更高效的用法,详细内容见代码里面的注释)

2. 个人认为内存开销还是比较小的,可以很容易移植到另的平台上(废话文件系统都应该这样。。。)

3. 我认为最大的优点就是,能支持同时多文件操作,等下会演示,当然,在51单片机上这样做效率会偏低,不过总会有应用场合的,比如说,你在处理一个文件的同时,在要利用字库文件等各种辅助的系统文件。刚才说到效率偏低,因为是利用了以时间换空间的原理,我也留出了修改的接口,在比较大的RAM上想提高效率,或者你只想处理一个文件(这种情况下没什么必要改,因为处理方式本身对效率影响不大,我认为从算法分析的角度上讲,影响速度的主要是硬件驱动的问题),都可以对代码进行一些修改

也有最明显的缺点
    因为我是菜鸟级的,所以文件系统模块的代码特别长,超过2K行了。。。我先在这里说明了,所以看到代码以后就不要喷我了。。。

下面演示我测试的内容:
MUC用的是STC12C5A60S2,存储器是SD卡
因为还没有增加创建文件的功能,所以我先在电脑上新建了两个文件,hello.txt,new.txt
然后在程序里同时打开文件,写入数据,最后同时读取写入的内容:
然后这个是串口读到的信息:

DATE :Feb 02 2012 TIME :13:32:43

SD init success!

fat_fs init success!

I'm going to open file 1.

file1 open succeed.

I'm going to open file 2.

file2 open succeed.

fwrite write 13 bytes to file1
fwrite write 19 bytes to file1file2 is closed.

file open succeed.

fread read 13 bytes to file1

fread read 19 bytes to file2

now the contents of buffer :hello~ourdev~my name is Pony279~

最后把卡放到PC上看看:



为了证明这个是多文件操作,我就贴上测试的代码
void main()
{
        u16 xdata temp;

        Debug_Init();

        //初始化
        //初始化动态内存
        init_mempool(mem_pool, MEM_POOL_SIZE);
        SPI_Init();
        while(SD_Init())
        {
                DB_Delay_ms(1000);
        };

        DB_SendString("SD init success! ");
       
        if(FileSysInit())
        {
                DB_SendString(" fat_fs init failed! ");
                while(1);
        }
        else
        {
                DB_SendString(" fat_fs init success! ");
        }

        DB_SendString(" I'm going to open file 1. ");
        p_file1 = fopen(name1, FILE_READ | FILE_WRITE);
        if(p_file1 == NULL)
        {
                DB_SendString(" open file error! ");
                while(1);        //错误,不要进行下去了
        }
        else
        {
                DB_SendString(" file1 open succeed. ");
        }

        DB_SendString(" I'm going to open file 2. ");
        p_file2 = fopen(name2, FILE_READ | FILE_WRITE);
        if(p_file2 == NULL)
        {
                DB_SendString(" open file error! ");
                while(1);        //错误,不要进行下去了
        }
        else
        {
                DB_SendString(" file2 open succeed. ");
        }

        temp = fwrite(p_file1, str1, StringLength(str1));
        DB_SendString(" fwrite write ");
        DB_SendDec(temp);
        DB_SendString(" bytes to file1");

        temp = fwrite(p_file2, str2, StringLength(str2));
        DB_SendString(" fwrite write ");
        DB_SendDec(temp);
        DB_SendString(" bytes to file1");

        if(fclose(p_file2) == 0)
        {
                DB_SendString("file2 is closed. ");
                p_file2 = NULL;
        }
        else
        {
                DB_SendString("fclose error! ");
                while(1);
        }

        p_file2 = fopen(name2, FILE_READ | FILE_WRITE);
        if(p_file2 == NULL)
        {
                DB_SendString(" open file error! ");
                while(1);        //错误,不要进行下去了
        }
        else
        {
                DB_SendString(" file open succeed. ");
        }

        fseek(p_file1, 0, SEEK_SET);        //重新定位到文件开始
        temp = fread(p_file1, buffer, StringLength(str1) + 5);
        DB_SendString(" fread read ");
        DB_SendDec(temp);
        DB_SendString(" bytes to file1 ");

        temp = fread(p_file2, buffer + temp, StringLength(str2) + 5);
        DB_SendString(" fread read ");
        DB_SendDec(temp);
        DB_SendString(" bytes to file2 ");

        DB_SendString(" now the contents of buffer :");
        DB_SendString(buffer);

        //不再使用文件后一定要关闭文件特别是对于写入过的文件
        fclose(p_file1);
        fclose(p_file2);

        while(1);
}



最后上传工程代码:
(呃。。。这个工程是专门用来开发各种驱动的,所以有我的现在用的代码库在里面,很多东西,所以编译的时候要参考这个帖子的四楼:
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=5090488&bbs_page_no=1&search_mode=3&search_text=Pony279&bbs_id=9999

声明:文件系统部分的代码欢迎用于各种用途,但使用时请注明出处。其它模块的代码,只供学习交流,禁止用于商业(因为有些代码不是我写的。。。)
点击此处下载 ourdev_715583BLXRME.zip(文件大小:240K) (原文件名:Test-20120202.zip)
代码里面都有注释希望大家喜欢

补充内容 (2012-3-25 15:14):
文件写功能的应用,请看这里
http://www.ourdev.cn/thread-5451505-1-1.html
需要注意的时,那个帖子的代码和这里的代码有些不同,和原来的不兼容了。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
44条回答
Pony279
1楼-- · 2020-01-29 22:47
本帖最后由 Pony279 于 2012-4-16 23:40 编辑
xuancqu 发表于 2012-4-16 23:05
请问楼主,你的系统能不能再根目录下新建文件夹啊,我找了很多资料,新建文件基本上实现了,但是新建文件夹 ...


没有做这个功能,不过不难实现的,参考FAT文件系统原理的资料,基本上都是有介绍这个的,其实和新建文件差不了多少的,
前64个字节本质上也就是前2个目录项,软件里调整一下就行,多实验几次再用winhex对比就知道了。

建文件功能都实现了你还问这个问题。。。让我有点诧异
xuancqu
2楼-- · 2020-01-30 00:52
Pony279 发表于 2012-4-16 23:34
没有做这个功能,不过不难实现的,参考FAT文件系统原理的资料,基本上都是有介绍这个的,其实和新建文件 ...

我对比了一下,还是没有搞清楚子目录里前64字节是怎么定义的...而且确实资料不好找
简翟
3楼-- · 2020-01-30 03:27
mark.
hamipeter
4楼-- · 2020-01-30 08:01
不错啊,赞一个
shunda
5楼-- · 2020-01-30 10:31
 精彩回答 2  元偷偷看……
简翟
6楼-- · 2020-01-30 16:01
你好,我想用60s2实现播放wav,用它自带的PWM播放!不知道要怎么改?

一周热门 更多>