ImageVerifierCode 换一换
格式:DOCX , 页数:20 ,大小:215.65KB ,
资源ID:17824130      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/17824130.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(单片机读取FLASHWord格式.docx)为本站会员(b****3)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

单片机读取FLASHWord格式.docx

1、每簇扇区数13RsvdSecCnt保留扇区数目14NumFATs此卷中FAT表数16RootEntCntFAT32为017TotSec1619Media存储介质21FATSz1622SecPerTrk磁道扇区数24NumHeads磁头数26HiddSec4FAT区前隐扇区数28TotSec32该卷总扇区数32FATSz32FAT表扇区数36ExtFlagsFAT32特有40FSVer42RootClus根目录簇号44FSInfo文件系统信息48BkBootSec通常为650Reserved12扩展用52DrvNum64Reserved165BootSig66VolID67FilSysType7

2、1FilSysType182DBR的实现代码:struct FAT32_DBR unsigned char BS_jmpBoot3; /跳转指令 offset: 0 unsigned char BS_OEMName8; / offset: 3 unsigned char BPB_BytesPerSec2;/每扇区字节数 offset: unsigned char BPB_SecPerClus1; /每簇扇区数 offset: unsigned char BPB_RsvdSecCnt2; /保留扇区数目 offset: unsigned char BPB_NumFATs1; /此卷中FAT表数

3、offset: unsigned char BPB_RootEntCnt2; /FAT32为0 offset: unsigned char BPB_TotSec162; unsigned char BPB_Media1; /存储介质 offset: unsigned char BPB_FATSz162; unsigned char BPB_SecPerTrk2; /磁道扇区数 offset: unsigned char BPB_NumHeads2; /磁头数 offset: unsigned char BPB_HiddSec4; /FAT区前隐扇区数 offset: unsigned char

4、 BPB_TotSec324; /该卷总扇区数 offset: unsigned char BPB_FATSz324; /一个FAT表扇区数 offset: unsigned char BPB_ExtFlags2; /FAT32特有 offset: unsigned char BPB_FSVer2; unsigned char BPB_RootClus4; /根目录簇号 offset: unsigned char FSInfo2; /保留扇区FSINFO扇区数offset: unsigned char BPB_BkBootSec2; /通常为6 offset: unsigned char BP

5、B_Reserved12; /扩展用 offset: unsigned char BS_DrvNum1; / offset: unsigned char BS_Reserved11; unsigned char BS_BootSig1; unsigned char BS_VolID4; unsigned char BS_FilSysType11; / offset: unsigned char BS_FilSysType18; /FAT32 offset:;在程序中我们采用以上的结构体指针对扇区数据指针进行转化,就可以直接读取数据中的某一字段,如要读取BPB_BytesPerSec,可以这样来

6、作: (struct FAT32_DBR *)pSector)- BPB_BytesPerSec 用如上语句就可以得到这一字段的首地址。心细的读者可能会发现读回来的字节拼在一起,与实际的数据并不吻合。例如BPB_BytesPerSec读出来的内容是“00 02”,在程序中我们把00作为int型变量的高字节,把02作为其低字节,那么这个变量的值为2,而实际的SD卡里的扇区大小为512个字节,这512与2之间相去甚远。是什么造成这种现象的呢?这就是大端模式与小端模式在作怪。上面我们合成int型变量的方法(00为高字节,02为低字节)为小端模式。而如果我们改用大端模式来进行合成的话,结果就会不同:将

7、02作高字节,而把00作低字节,变量值就成了0x0200(十进制的512),这样就和实际数据吻合了。可见FAT32中字节的排布是采用小端模式的。在我们程序中需要将它转为大端模式的表达方式。在笔者的程序有这样一个函数lb2bb,专门将小端模式转为大端模式,程序如下:unsigned long lb2bb(unsigned char *dat,unsigned char len) /小端转为大端 unsigned long temp=0; unsigned long fact=1; unsigned char i=0; for(i=0;iBPB_Sector_No =FAT32_FindBPB()

8、; /FAT32_FindBPB()可以返回BPB所在的扇区号Total_Size =FAT32_Get_Total_Size(); /FAT32_Get_Total_Size()可以返回磁盘的总容量,单位是兆FATsectors =lb2bb(bpb-BPB_FATSz32) ,4); /装入FAT表占用的扇区数到FATsectors中FirstDirClust =lb2bb(bpb-BPB_RootClus) ,4); /装入根目录簇号到FirstDirClust中BytesPerSector =lb2bb(bpb-BPB_BytesPerSec),2); /装入每扇区字节数到BytesP

9、erSector中SectorsPerClust =lb2bb(bpb-BPB_SecPerClus) ,1); /装入每簇扇区数到SectorsPerClust 中arg-FirstFATSector=lb2bb(bpb-BPB_RsvdSecCnt) ,2)+arg-BPB_Sector_No;/装入第一个FAT表扇区号到FirstFATSector 中RootDirCount =lb2bb(bpb-BPB_RootEntCnt) ,2); /装入根目录项数到RootDirCount中RootDirSectors =(arg-RootDirCount)*329; /装入根目录占用的扇区数到

10、RootDirSectors中FirstDirSector=(arg-FirstFATSector)+(bpb-BPB_NumFATs0)*(arg-FATsectors); /装入第一个目录扇区到FirstDirSector中FirstDataSector =(arg-FirstDirSector)+(arg-RootDirSectors);/装入第一个数据扇区到FirstDataSector中 3)FAT(文件分配表) FAT表是FAT32文件系统中用于磁盘数据(文件)索引和定位引进的一种链式结构。可以说FAT表是FAT32文件系统最有特色的一部分,它的链式存储机制也是FAT32的精华所在

11、,也正因为有了它才使得数据的存储可以不连续,使磁盘的功能发挥得更为出色。 FAT表到底在什么地方?它到底是什么样子的呢? 从第一步从BPB中提取参数中的FirstFATSector就可以知道FAT表所在的扇区号。其实每一个FAT表都有另一个与它一模一样的FAT存在,并且这两个FAT表是同步的,也就是说对一个FAT表的操作,同样地,也应该在另一个FAT表进行相同的操作,时刻保证它们内容的一致。这样是为了安全起见,当一个FAT因为一些原因而遭到破坏的时候,可以从另一个FAT表进行恢复。 FAT表的内容如下图所示: 上图就是一个实际的FAT表。前8个字节“F8 FF FF 0F FF FF FF F

12、F”为FAT32的FAT表头标记,用以表示此处是FAT表的开始。后面的数据每四个字节为一个簇项(从第2簇开始),用以标记此簇的下一个簇号。 拿我们创建的那个叫TEST.TXT(大小为20个字节)的文件来说,如果这个文件的开始簇为第2簇的话,那么就到FAT表里来查找,看文件是否有下一个簇(如果文件大小大于一个簇的容量,必须会有数据存储到下一个簇,但下一个簇与上一个簇不一定是连续的),可以看到“簇2”的内容为“FF FF FF 0F”,这样的标记就说明这个文件到第2簇就已经结束了,没有后继的簇,即此文件的大小是小于一个簇的容量的。 上面讲了很多,都是围绕簇这样一个词来讲的,簇又是什么?为什么要将它

13、引入到FAT32里来呢? 磁盘上最小可寻址存储单元称为扇区,通常每个扇区为512个字节。由于多数文件比扇区大得多,因此如果对一个文件分配最小的存储空间,将使存储器能存储更多数据,这个最小存储空间即称为簇。根据存储设备(磁盘、闪卡和硬盘)的容量,簇的大小可以不同以使存储空间得到最有效的应用。在早期的360KB磁盘上,簇大小为2个扇区(1,024字节);第一批的10MB硬盘的簇大小增加到8个扇区(4,096字节);现在的小型闪存设备上的典型簇大小是8KB或16KB。2GB以上的硬盘驱动器有32KB的簇。如果对于容量大的存储定义了比较小的簇的话,就会使FAT表的体积很大,从而造成数据的冗余和效率的下

14、降。 需要指出的是,簇作为FAT32进行数据存储的最小单位,内部扇区是不能进一步细分的,即使一个文件的数据写到一个簇中后,簇中还有容量的剩余(里部扇区没有写满),哪怕这个簇只写了一个字节,其它文件的数据也是不能接在后面继续数据的,而只能另外找没有被占用的簇。 我们按照初始化参数表中的SectorsPerClust可以知道一个簇中的扇区数,笔者的SD卡实测簇大小为4个扇区,按照上面的说法,TEST.TXT这样一个只有20个字节的文件,也会占用一个簇的容量,让我们在Windows里看看它的实际占用空间的情况。 从上图可以看到文件大小为20个字节,但占用空间却是2048个字节(一个簇的容量,4个扇区

15、)。 TEST.TXT容量只有20个字节,所以只占用了一个簇,可能FAT表中还看不出链式结构,现在我们再创建一个文件,使它占用26个簇,如下: 可以看到图中红色标记的就是文件所占用的26个簇。从第4簇开始,簇项4的内容为“05 00 00 00”(小端模式),说明下一个簇为第5簇,而簇项5的内容为“06 00 00 00”,说明下一个簇为第6簇依此类推,直到内容为“FF FF FF 0F”,说明无后继簇,文件数据到此结束。FAT表中的链式存储结构已经非常明显。把我们从FAT表中分析的结果与Windows的统计结束进行对比,说明我们的解理是正确的,如下图: 从上面可以看到,当数据结束于某一簇时,

16、FAT32就用“FF FF FF 0F”来对其进行标记。其实还有其实的标记以表达其它的簇属性,如“00 00 00 00 ”表示未分配的簇,“FF FF FF F7”表示坏簇等。给出一个簇号,计算出它的后继簇号,是实现FAT32的重点,实现如下:unsigned long FAT32_GetNextCluster(unsigned long LastCluster) unsigned long temp; struct FAT32_FAT *pFAT; struct FAT32_FAT_Item *pFAT_Item; temp=(LastCluster/128)+Init_Arg.First

17、FATSector);/计算给定簇号对应的簇项的扇区号 FAT32_ReadSector(temp,FAT32_Buffer); pFAT=(struct FAT32_FAT *)FAT32_Buffer; pFAT_Item=&(pFAT-Items)LastCluster%128);/在算出的扇区中提取簇项 return lb2bb(pFAT_Item,4);/返回下一簇号 那么FAT表有多大呢?FAT表中每四个字节表示一个簇,所以FAT表的大小由实际的簇数来决定。从这里也可以看出,如果簇过大,则FAT表比较小,但会造成空间的浪费,而如果簇过小,可以减小空间的浪费,但会使FAT表变得臃肿。

18、FAT表的大小也可以从BPB参数FATsectors读出。从上面的BPB图可以得知笔者的SD卡的FAT表大小为958个扇区(“BE030000”的大端表示)。如果这958个扇区每四个字节都表示一个簇项,则它可以表示(958*512/4)-2= 122622个簇(减去2是因为有8个字节的FAT表头标识。看看我们计算的是否正确呢,下面是Winhex计算出来的簇数:与Winhex计算的结果是吻合的,我们对FAT表与簇的理解是正确的。看完上面对FAT表的讲解中,你可能会问:一个文件数据的首簇号怎样来确定呢?只有知道了一个文件数据的首簇号才能继续查找下一簇数据的位置,直到数据结束。下面将要讲到的“根目录

19、区”就可以由一个文件的文件名来查到它的首簇。4)根目录区在FAT32中其实已经把文件的概念进行扩展,目录同样也是文件,从根目录的地位与其它目录是相同的,因此根目录也被看作是文件。既然是文件就会有文件名,根目录的名称就是磁盘的卷标。如笔者的SD卡在格式会时设置卷标为znmcu,则根目录的名称就为ZNMCU,如下图:每一个文件都对应一个描述它属性的结构,定义如下:FAT32文件目录项32个字节的定义字节偏移量字数量定义07文件名810扩展名属性字节0x00 (读写)0x01 (只读)0x02 (隐藏)0x04 (系统)0x08 (卷标)0x10 (子目录)0x20 (归档)系统保留创建时间的10毫

20、秒位1415文件创建时间1617文件创建日期1819文件最后访问日期2021文件起始簇号的高16 位2223文件的最近修改时间2425文件的最近修改日期2627文件起始簇号的低16 位2831表示文件的长度 根目录区所在扇区可从BPB参数FirstDirSector获取,从BPB图得FirstDirSector=FirstFATSector+BPB_NumFATs*FATsectors=2053。根目录区的初始大小为一个簇,实际的内容如下:图中的记录1描述根目录,前八个字节为文件名“ZNMCU ”(长度小于8的部分用空格符补齐),下面的三个字节为扩展名“ ”( 长度小于3的部分用空格符补齐),

21、08表示此文件为卷标,开始簇高字节为0000,低字节为0000,开始簇为0,文件长度为0。记录2描述TEST.TXT文件,文件名为“TEST ”,扩展名为“TXT”,20表示此文件为归档,开始簇为3(“00000003”),长度为20。记录3描述BIGTEST.TXT文件,文件名为“BIGTES1”,扩展名为“TXT”,开始簇为4,长度为5200字节(0000CB20)。可以看到FAT32中的文件名都以大写字母表示,长度不足的部分用空格符补齐,所以我们要读取的文件TEST.TXT就变成了“TEST .TXT”,这将有助于文件名的匹配,我们不用去处理不等长文件名所带来的麻烦。另外,还会发现长度过

22、长的部分会被1所替换,如果替换后有文件与之重名,则后面的数字将增加为2。文件目录项结构的实现如下:struct direntry unsigned char deName8; / 文件名 unsigned char deExtension3; / 扩展名 unsigned char deAttributes; / 文件属性 unsigned char deLowerCase; / 系统保留 unsigned char deCHundredth; / 创建时间的10 毫秒位 unsigned char deCTime2; / 文件创建时间 unsigned char deCDate2; / 文件

23、创建日期 unsigned char deADate2; / 文件最后访问日期 unsigned char deHighClust2; / 文件起始簇号的高16 位 unsigned char deMTime2; / 文件的最近修改时间 unsigned char deMDate2; / 文件的最近修改日期 unsigned char deLowCluster2;/文件起始簇号的低16 位 unsigned char deFileSize4; / 表示文件的长度我们最终要实现的是对TEST.TXT文件的读取,须要作到给定文件名后,可以得到相应文件的首簇。主要的思想就是对根目录区中(本实例只针对根目录中的文件进行

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1