1、文件: FAT.H/微控设计网原创 www.M 作者: debug版主typedef unsigned char uint8;typedef unsigned int uint16;typedef unsigned long uint32;#pragma pack(1)typedef structuint8 BS_jmpBoot3;uint8 BS_OEMName8;uint16 BPB_BytesPerSec;uint8 BPB_SecPerClus;uint16 BPB_RsvdSecCnt;uint8 BPB_NumFATs;uint16 BPB_RootEntCnt;uint16 BP
2、B_TotSec16;uint8 BPB_Media;uint16 BPB_FATSz16;uint16 BPB_SecPerTrk;uint16 BPB_NumHeads;uint32 BPB_HiddSec;uint32 BPB_TotSec32;uint8 BS_DrvNum;uint8 BS_Reservedl;uint8 BS_BootSig;uint32 BS_VolID;uint8 BS_VolLab11;uint8 BS_FilSysType8;uint8 ExecutableCode448;uint8 ExecutableMarker2; FAT_BPB;typedef st
3、ructuint8 NAME8;uint8 TYPE3; FILE_NAME;typedef structuint16 Start;uint32 Size; FILE_POSIT;typedef structFILE_NAME FileName;uint8 FileAttrib;uint8 UnUsed10;uint8 FileUpdateTime2;uint8 FileUpdateData2;FILE_POSIT FilePosit; DIR;typedef structuint16 ClusID;uint16 SecOfClus;uint16 ByteOfSec; DATA_POSIT;#
4、pragma pack()/*/读一个扇区void ReadBlock(uint32 LBA);/*/写一个扇区void WriteBlock(uint32 LBA);/*void CopyBytes(void* S, void* D, uint16 size);/*uint8 IsEqual(void* A, void* B, uint8 Size);/*void EmptyBytes(void* D, uint16 size);/*/读取 BPB数据结构void ReadBPB(void);/*/获取根目录开始扇区号uint32 DirStartSec(void);/*/获取数据区开始扇区
5、号uint32 DataStartSec(void);/*/目录项占用的扇区数uint16 GetDirSecCount(void);/*/获取一个簇的开始扇区uint32 ClusConvLBA(uint16 ClusID);/*/读取文件分配表的指定项uint16 ReadFAT(uint16 Index);/*/写文件分配表的指定项void WriteFAT(uint16 Index, uint16 Value);/*/获取根目录中可以使用的一项uint16 GetEmptyDIR(void);/*/获得和文件名对应的目录项uint8 GetFileID(uint8 Name11, DI
6、R* ID);/*/获取一个空的 FAT项uint16 GetNextFAT(void);/*/读取根目录的指定项void ReadDIR(uint16 Index, DIR* Value);/*/写根目录的指定项void WriteDIR(uint16 Index, DIR* Value);/*/创建一个空文件void CreateFile(uint8* FileName11, uint32 Size);/*/复制文件分配表,使其和备份一致void CopyFAT(void);/*/操作文件的数据void OperateFile(uint8 Write ,uint8 Name11, uint
7、32 Start, uint32 Length, void* Data);/-文件:FAT.C/微控设计网原创 www.M 作者: debug版主#include #include “FAT16.h“uint8 BUFFER512;uint16 BPB_BytesPerSec;uint8 BPB_SecPerClus;uint16 BPB_RsvdSecCnt;uint8 BPB_NumFATs;uint16 BPB_RootEntCnt;uint16 BPB_TotSec16;uint16 BPB_FATSz16;uint32 BPB_HiddSec;/*/读一个扇区void ReadBlo
8、ck(uint32 LBA)/*return;/*/写一个扇区void WriteBlock(uint32 LBA)/*return;/*void CopyBytes(void* S, void* D, uint16 size)/*uint8 *s = S, *d = D;uint16 i;for(i = 0; i BPB_BytesPerSec;BPB_SecPerClus = BPB-BPB_SecPerClus;BPB_RsvdSecCnt = BPB-BPB_RsvdSecCnt;BPB_NumFATs = BPB-BPB_NumFATs;BPB_RootEntCnt = BPB-BP
9、B_RootEntCnt;BPB_TotSec16 = BPB-BPB_TotSec16;BPB_FATSz16 = BPB-BPB_FATSz16;BPB_HiddSec = BPB-BPB_HiddSec;/*/获取根目录开始扇区号uint32 DirStartSec(void)/*return BPB_RsvdSecCnt + BPB_NumFATs * BPB_FATSz16;/*/获取数据区开始扇区号uint32 DataStartSec(void)/*return (uint32)(DirStartSec() + BPB_RootEntCnt * 32 / BPB_BytesPer
10、Sec);/*/目录项占用的扇区数uint16 GetDirSecCount(void)/*return BPB_RootEntCnt * 32 / 512;/*/获取一个簇的开始扇区uint32 ClusConvLBA(uint16 ClusID)/*return DataStartSec() + BPB_SecPerClus * (ClusID - 2);/*/读取文件分配表的指定项uint16 ReadFAT(uint16 Index)/*uint16 *RAM = (uint16*)BUFFER;ReadBlock(BPB_RsvdSecCnt + Index / 256);retur
11、n RAMIndex % 256;/*/写文件分配表的指定项void WriteFAT(uint16 Index, uint16 Value)/*uint16 *RAM = (uint16*)BUFFER;uint32 SecID;SecID = BPB_RsvdSecCnt + Index / 256;ReadBlock(SecID);RAMIndex % 256 = Value;WriteBlock(SecID);/*/获取根目录中可以使用的一项uint16 GetEmptyDIR()/*uint16 DirSecCut, DirStart, i, m, ID = 0;DirSecCut
12、= GetDirSecCount();DirStart = DirStartSec();for(i = 0; i FileName, 11)*ID = *(DIR*)return 1; /找到对应的目录项,返回 1.return 0; /没有找到对应的目录项,返回 0./*/获取一个空的 FAT项uint16 GetNextFAT(void)/*=*uint16 FAT_Count, i;FAT_Count = BPB_FATSz16 * 256; /FAT表总项数for(i = 0; i FAT_Count; i+)if(ReadFAT(i) = 0)return i;return 0;/*
13、/读取根目录的指定项void ReadDIR(uint16 Index, DIR* Value)/*uint32 DirStart = DirStartSec();ReadBlock(DirStart + Index / 16);CopyBytes(/*/写根目录的指定项void WriteDIR(uint16 Index, DIR* Value)/*uint32 LBA = DirStartSec() + Index / 16;ReadBlock(LBA);CopyBytes(Value, WriteBlock(LBA);/*/创建一个空文件void CreateFile(uint8* Fi
14、leName11, uint32 Size)/*uint16 ClusID, ClusNum, ClusNext, i;DIR FileDir;ClusNum = Size / (BPB_SecPerClus * 512) + 1;EmptyBytes(CopyBytes(FileName, FileDir.FilePosit.Size = Size;FileDir.FilePosit.Start = GetNextFAT();ClusID = FileDir.FilePosit.Start;for(i = 0; i ClusNum - 1; i+)WriteFAT(ClusID, 0xfff
15、f);ClusNext = GetNextFAT();WriteFAT(ClusID, ClusNext);ClusID = ClusNext;WriteFAT(ClusID, 0xffff);WriteDIR(GetEmptyDIR(), /*/复制文件分配表,使其和备份一致void CopyFAT(void)/*uint16 FATSz16, RsvdSecCnt, i;FATSz16 = BPB_FATSz16;RsvdSecCnt = BPB_RsvdSecCnt;for(i = 0; i FATSz16; i+)ReadBlock(RsvdSecCnt + i);WriteBlock
16、(RsvdSecCnt + FATSz16 + i);/*/操作文件的数据void OperateFile(uint8 Write ,uint8 Name11, uint32 Start, uint32 Length, void* Data)/*uint8 *data = Data;uint16 BytePerClus, SecPerClus, ClusNum, ClusID, m;uint32 LBA, i;DIR FileDir;SecPerClus = BPB_SecPerClus;BytePerClus = BPB_SecPerClus * 512; / 每簇的字节数GetFileID
17、(Name, /计算开始位置所在簇的簇号ClusNum = Start / BytePerClus;ClusID = FileDir.FilePosit.Start;for(i = 0; i ClusNum; i+)ClusID = ReadFAT(ClusID);/计算开始位置所在扇区簇内偏移i = (Start % BytePerClus) / 512;/计算开始位置扇区内偏移m = (Start % BytePerClus) % 512;LBA = ClusConvLBA(ClusID) + m;if(Write)ReadBlock(LBA);elseReadBlock(LBA+);go
18、to Start;while(1)ClusID = ReadFAT(ClusID); /下一簇簇号LBA = ClusConvLBA(ClusID);for(i = 0; i SecPerClus; i+)if(Write)ReadBlock(LBA);elseReadBlock(LBA+);for(m = 0; m 512; m+)Start:if(Write)BUFFERm = *data+;else*data+ = BUFFERm;/如果读取完成就退出if(-Length = 0)if(Write)WriteBlock(LBA); /回写扇区return;if(Write)WriteBlock(LBA+); /回写扇区,指针下移/-