这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界» 论坛首页» 嵌入式开发» MCU» [推荐]51 flash文件系统DIY____概述(1)[推荐]

共1条 1/1 1 跳转至

[推荐]51 flash文件系统DIY____概述(1)[推荐]

菜鸟
2002-10-22 22:25:27 打赏
这些日子公司不太景气,自己学艺不精,只会用C语言写一点皮毛的东西, 想写一点东西去指望能在哪里发表,骗别人一点钱财,又自知文笔拙劣,不大 可能登大雅之堂。同时自己也于心不忍,那也是大家伙的血汗钱。于是就把这 点东西放到BBS上来家来共享。 高手看了就见笑了,但希望大家批评指正。 转载请保留作者网名 taowa.如不幸被哪位眼光低下的编辑发现,想让本文 现于纸端请 Email: taowa@263.net 单片机都用flash来存储断电需要保存的东西。少量数据的存储较为简单.当数据量比 较大,类型和长度都不同,又要经常更改时,存储起来就很麻烦。当然不可能给每一条记录都 分配最大的空间,那样的话空间浪费就很吓人.举个例子,有好多条不同类型的记录,长度在 100 Byte到2000 Byte的都有,如果把flash分块,就必须每块都分成2000 Byte大小,这样 在长度为100Byte的记录比较多时由于每条都要占用2000Byte,而实际上只使用了100Byte, 就浪费了1900 Byte,空间浪费就会很可观。这还只是空间浪费的情况,对于存储的信息的种 类很多时,这种简单分块的方式也使访问不同种类的数据时搞得人头大. 所以必须在flash中建立一个合适的空间管理机制,来管理flash的存储。我们这里讲 的文件系统就是干这个事情的。他把flash空间划分为较小的分块(sector)通过记录每个文 件占用的sector来达到空间管理的目的。flash分的sector越多空间利用率就越高。有时 候sector过多时,以几个块作为一个存储单位,文件系统中把它叫做簇(cluster),簇是文件 存储的最小单位.通常sector的值都是固定的,取决于不同的器件,簇的大小是可变的它是 sector大小的整数倍. 先不急介绍文件系统的详细内容,先说一说将要用到的器件.市面上的flash存储器有 很多,但最常见的是串行I2C器件和29系列的flash存储芯片.为了满足大容量存储的需要, 另外文件系统为了存储索引信息本身也需要占一点儿地方,所以flash的容量选的是容量较 大的芯片.串行和并行芯片选择无所谓,只不过串行芯片的存取速度比起并行芯片的存取速 度要慢得多。如果对速度有要求那就用并行的芯片,耐性好的话就用串行芯片啰,只不过我 买的时候24C256(32K) 竟然比29C040A(512K)要贵,那位奸商要了我25元,而W29C040只要 18块,嘿嘿!选什么你就看着办吧。 我这里以ATMEL 24C256和ATMEL 29C040A这两种芯片为例来说明. ATMEL 24C256是I2C的串行flash芯片,他的容量为32768 Byte(32K),支持字节写,页 写(页大小为64Byte),写入延时为10ms,CLOCK对于5V器件最高可达1MHz。 AT29C040A是并行的flash器件,读取时他就如同普通ROM一样,写入时只能以扇区 (sector)形式写入,即使只是改动了扇区中的一个字节,也要把整个扇区读出更改后然后再 全部写入。AT29C040A容量为524288Byte(512K)扇区大小为256字节,写入延时为10ms。选 并行芯片当然是扇区越小越好.这样能省不少的宝贵的单片机RAM. 要解决数据的存储问题首先要解决芯片的写入和读出问题。51单片机没有I2C总线, 需要单片机自身模拟主器件来访问I2C芯片。AT29C040A有软件数据保护时需要解锁才能写 入,还有这个东西容量太大,地址线有19根,51单片机只有16根地址线,所以需要用P1口或 外接一个锁存器来锁存高位地址,这个以后讲到再慢慢说。 先来说对I2C器件进行读写的问题。主器件(MCU)对I2C器件(flash)进行操作时,先要 送出起始条件,然后送出命令字、数据,最后送出停止条件。因为SCL的最高频率不能超过 1MHz,单片机有时操作太快所以要在一些操作中加入延时,由于每次写入时都要延时至少 10ms所以我们先编一个延时函数。由于延时函数很多地方将会用到我们把它放到一个公共 文件中。还有在编程序时通常以uchar代替unsigned char所以我们再新建一个公共的头文 件把常用的宏都定义到里面。 新建一个文件general.h,内容如下: #ifndef _GENERAL #define _GENERAL #include #define OSFREQ 11059200 /*单片机的晶振频率定义 */ #define uchar unsigned char #define uint unsigned int void delay(uint time); /*函数原型声明 */ #endif 然后我们来编写文件delay函数,要保证在不同晶振下延时函数延时近似相等我们定义 了宏OSFREQ,每次更换晶振时更改OSFREQ的宏定义,然后重新编译就可以了,不必到程序 中逐一更改delay的值。由于这里对延时的精度要求很低,所以这里的延时时间都是近似的. general.c 的内容: #include "general.h" /**********************************************************/ 延时函数.输入:uint time延时的毫秒数(近似) 输出:无 本函数可以重入 /**********************************************************/ void delay(uint time) { register uint i; register uchar j; for(i=0;i /***********************************************/ I2C总线延时函数 可以重入 /***********************************************/ void I2cDelay(void) { #if OSFREQ>33000000 _nop_(); #endif #if OSFREQ>48000000 /*一般51单片机的晶振最高也就50M*/ _nop_(); #endif } 今天已经写了不少了,妈妈等着我回去吃晚饭,我就先走了。明天有空的话我还会继 续。 2002.10.13 taowa



关键词: 推荐 flash 文件 系统 概述 存储 芯片

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册]