FAT32文件系统实现单片机MP3播放器 源代码要点Word格式文档下载.docx
《FAT32文件系统实现单片机MP3播放器 源代码要点Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《FAT32文件系统实现单片机MP3播放器 源代码要点Word格式文档下载.docx(19页珍藏版)》请在冰豆网上搜索。
structPartRecordPart[4];
//4个分区记录
unsignedcharBootSectSig0;
unsignedcharBootSectSig1;
structFAT32_FAT_Item
unsignedcharItem[4];
structFAT32_FAT
structFAT32_FAT_ItemItems[128];
FAT32中对BPB的定义如下一共占用90个字节
structFAT32_BPB
unsignedcharBS_jmpBoot[3];
//跳转指令offset:
0
unsignedcharBS_OEMName[8];
//offset:
3
unsignedcharBPB_BytesPerSec[2];
//每扇区字节数offset:
11
unsignedcharBPB_SecPerClus[1];
//每簇扇区数offset:
13
unsignedcharBPB_RsvdSecCnt[2];
//保留扇区数目offset:
14
unsignedcharBPB_NumFATs[1];
//此卷中FAT表数offset:
16
unsignedcharBPB_RootEntCnt[2];
//FAT32为0offset:
17
unsignedcharBPB_TotSec16[2];
19
unsignedcharBPB_Media[1];
//存储介质offset:
21
unsignedcharBPB_FATSz16[2];
22
unsignedcharBPB_SecPerTrk[2];
//磁道扇区数offset:
24
unsignedcharBPB_NumHeads[2];
//磁头数offset:
26
unsignedcharBPB_HiddSec[4];
//FAT区前隐扇区数offset:
28
unsignedcharBPB_TotSec32[4];
//该卷总扇区数offset:
32
unsignedcharBPB_FATSz32[4];
//一个FAT表扇区数offset:
36
unsignedcharBPB_ExtFlags[2];
//FAT32特有offset:
40
unsignedcharBPB_FSVer[2];
42
unsignedcharBPB_RootClus[4];
//根目录簇号offset:
44
unsignedcharFSInfo[2];
//保留扇区FSINFO扇区数offset:
48
unsignedcharBPB_BkBootSec[2];
//通常为6offset:
50
unsignedcharBPB_Reserved[12];
//扩展用offset:
52
unsignedcharBS_DrvNum[1];
64
unsignedcharBS_Reserved1[1];
65
unsignedcharBS_BootSig[1];
66
unsignedcharBS_VolID[4];
67
unsignedcharBS_FilSysType[11];
71
unsignedcharBS_FilSysType1[8];
//"
FAT32"
offset:
82
//Structureofadosdirectoryentry.一个dos目录结构的入口
structdirentry
unsignedchardeName[8];
//filename,blankfilled(文件名)
unsignedchardeExtension[3];
//extension,blankfilled(扩展)
unsignedchardeAttributes;
//fileattributes(文件属性)
unsignedchardeLowerCase;
//NTVFATlowercaseflags(settozero)(系统保留)
unsignedchardeCHundredth;
//hundredthofsecondsinCTime(创建时间的10毫秒位)
unsignedchardeCTime[2];
//createtime(文件创建时间)
unsignedchardeCDate[2];
//createdate(文件创建日期)
unsignedchardeADate[2];
//accessdate(文件最后访问日期)
unsignedchardeHighClust[2];
//highunsignedcharsofclusternumber(文件起始簇号的高16位)
unsignedchardeMTime[2];
//lastupdatetime(文件的最近修改的时间)
unsignedchardeMDate[2];
//lastupdatedate(文件的最近修改日期)
unsignedchardeLowCluster[2];
//startingclusteroffile(文件起始簇号的低16位)
unsignedchardeFileSize[4];
//sizeoffileinunsignedchars(表示文件的长度)
//Stuctures结构
structFileInfoStruct
unsignedcharFileName[12];
//文件名
unsignedlongFileStartCluster;
//<
filestartingclusterforlastfileaccessed(文件首簇号)
unsignedlongFileCurCluster;
//文件当前簇号
unsignedlongFileNextCluster;
//下一簇号
unsignedlongFileSize;
//<
filesizeforlastfileaccessed(文件大小)
unsignedcharFileAttr;
fileattr(属性)forlastfileaccessed(文件属性)
unsignedshortFileCreateTime;
filecreationtimeforlastfileaccessed(文件建立时间)
unsignedshortFileCreateDate;
filecreationdateforlastfileaccessed(文件建立日期)
unsignedshortFileMTime;
//文件修改时间
unsignedshortFileMDate;
//文件修改日期
unsignedlongFileSector;
//<
filerecordplace(文件当前扇区)
unsignedlongFileOffset;
filerecordoffset(文件偏移量)
FAT32初始化时初始参数装入如下结构体中
structFAT32_Init_Arg
unsignedcharBPB_Sector_No;
//BPB所在扇区号
unsignedlongTotal_Size;
//磁盘的总容量
unsignedlongFirstDirClust;
//根目录的开始簇
unsignedlongFirstDataSector;
//文件数据开始扇区号
unsignedintBytesPerSector;
//每个扇区的字节数
unsignedintFATsectors;
//FAT表所占扇区数
unsignedintSectorsPerClust;
//每簇的扇区数
unsignedlongFirstFATSector;
//第一个FAT表所在扇区
unsignedlongFirstDirSector;
//第一个目录所在扇区
unsignedlongRootDirSectors;
//根目录所占扇区数
unsignedlongRootDirCount;
//根目录下的目录与文件数
//#defineFIND_BPB_UP_RANGE2000//BPB不一定在0扇区,对0~FINE_BPB_UP_RANGE扇区进行扫描
unsignedcharxdataFAT32_Buffer[512];
//扇区数据读写缓冲区
structFAT32_Init_ArgInit_Arg;
//初始化参数结构体实体
structFileInfoStructFileInfo;
//文件信息结构体实体
unsignedchar*FAT32_ReadSector(unsignedlongLBA,unsignedchar*buf)//FAT32中读取扇区的函数
MMC_get_data_LBA(LBA,512,buf);
returnbuf;
}
unsignedcharFAT32_WriteSector(unsignedlongLBA,unsignedchar*buf)//FAT32中写扇区的函数
returnMMC_write_sector(LBA,buf);
unsignedlonglb2bb(unsignedchar*dat,unsignedcharlen)//小端转为大端
unsignedlongtemp=0;
unsignedlongfact=1;
unsignedchari=0;
for(i=0;
i<
len;
i++)
{
temp+=dat[i]*fact;
fact*=256;
}
returntemp;
unsignedlongFAT32_FindBPB()//寻找BPB所在的扇区号
MMC_Init();
//SD卡初始化
FAT32_ReadSector(0,FAT32_Buffer);
if(FAT32_Buffer[0]!
=0xeb)
returnlb2bb(((((structPartSector*)(FAT32_Buffer))->
Part[0]).StartLBA),4);
else
return0;
unsignedlongFAT32_Get_Total_Size()//存储器的总容量,单位为M
FAT32_ReadSector(Init_Arg.BPB_Sector_No,FAT32_Buffer);
return((float)(lb2bb((((structFAT32_BPB*)(FAT32_Buffer))->
BPB_TotSec32),4)))*0.0004883;
voidFAT32_Init(structFAT32_Init_Arg*arg)
structFAT32_BPB*bpb;
bpb=(structFAT32_BPB*)(FAT32_Buffer);
//将数据缓冲区指针转为structFAT32_BPB型指针
arg->
BPB_Sector_No=FAT32_FindBPB();
//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);
//装入每扇区字节数到BytesPerSector中
SectorsPerClust=lb2bb((bpb->
BPB_SecPerClus),1);
//装入每簇扇区数到SectorsPerClust中
FirstFATSector=lb2bb((bpb->
BPB_RsvdSecCnt),2)+arg->
BPB_Sector_No;
//装入第一个FAT表扇区号到FirstFATSector中
RootDirCount=lb2bb((bpb->
BPB_RootEntCnt),2);
//装入根目录项数到RootDirCount中
RootDirSectors=(arg->
RootDirCount)*32>
>
9;
//装入根目录占用的扇区数到RootDirSectors中
FirstDirSector=(arg->
FirstFATSector)+(bpb->
BPB_NumFATs[0])*(arg->
FATsectors);
//装入第一个目录扇区到FirstDirSector中
FirstDataSector=(arg->
FirstDirSector)+(arg->
RootDirSectors);
//装入第一个数据扇区到FirstDataSector中
send_s("
FATchushihuachengong"
);
//FAT初始化成功
voidFAT32_EnterRootDir()
unsignedlongiRootDirSector;
unsignedlongiDir;
structdirentry*pDir;
for(iRootDirSector=(Init_Arg.FirstDirSector);
iRootDirSector<
(Init_Arg.FirstDirSector)+(Init_Arg.SectorsPerClust);
iRootDirSector++)
FAT32_ReadSector(iRootDirSector,FAT32_Buffer);
for(iDir=0;
iDir<
Init_Arg.BytesPerSector;
iDir+=sizeof(structdirentry))
pDir=((structdirentry*)(FAT32_Buffer+iDir));
if((pDir->
deName)[0]!
=0x00/*无效目录项*/&
&
(pDir->
=0xe5/*无效目录项*/&
=0x0f/*无效属性*/)
Printf_File_Name(pDir->
deName);
voidFAT32_CopyName(unsignedchar*Dname,unsignedchar*filename)
for(;
11;
Dname[i]=filename[i];
Dname[i]=0;
unsignedlongFAT32_EnterDir(char*path)
unsignedlongiDirSector;
unsignedlongiCurSector=Init_Arg.FirstDirSector;
unsignedcharDirName[12];
unsignedchardepth=0,i=0;
while(path[i]!
=0)
if(path[i]=='
\\'
)
{
depth++;
i++;
if(depth==1)
returniCurSector;
//如果是根目录,直接返回当前扇区号
for(iDirSector=iCurSector;
iDirSector<
iDirSector++)
FAT32_ReadSector(iDirSector,FAT32_Buffer);
unsignedcharFAT32_CompareName(unsignedchar*sname,unsignedchar*dname)
unsignedchari,j=8;
unsignedcharname_temp[12];
i++)name_temp[i]=0x20;
name_temp[11]=0;
i=0;
while(sname[i]!
='
.'
)
name_temp[i]=sname[i];
name_temp[j++]=sname[i];
//Printf(name_temp,0);
if(name_temp[i]!
=dname[i])return0;
return1;
unsignedlongFAT32_GetNextCluster(unsignedlongLastCluster)//给出一个簇号,计算出它的后继簇号的函数
unsignedlongtemp;
structFAT32_FAT*pFAT;
structFAT32_FAT_Item*pFAT_Item;
temp=((LastCluster/128)+Init_Arg.FirstFATSector);
//计算给定簇号对应的簇项的扇区号
FAT32_ReadSector(temp,FAT32_Buffer);
pFAT=(structFAT32_FAT*)FAT32_Buffer;
pFAT_Item=&
((pFAT->
Items)[LastCluster%128]);
//在算出的扇区中提取簇项
returnlb2bb(pFAT_Item,4);
//返回下一簇号
我们最终要实现的是对文件的读取,须要作到给定文件名后,可以得到相应文件的首簇。
主要是思想就是对根目录区中的记录进行扫描,对记录中的文件名进行匹配。
具体的实现如下函数
structFileInfoStruct*FAT32_OpenFile(char*filepath)
unsignedchardepth=0;
unsignedchari,index;
unsignedlongiFileSec,iCurFileSec,iFile;
structdirentry*pFile;
unsignedcharlen=strlen(filepath);
if(filepath[i]=='
index=i+1;
iCurFileSec=FAT32_EnterDir(filepath);
//Printf("
iCurFileSec"
iCurFileSec);
for(iFileSec=iCurFileSec;
iFileSec<
iCurFileSec+(Init_Arg.SectorsPerClust);
iFileSec++)
FAT32_ReadSector(iFileSec,FAT32_Buffer);
for(iFile=0;
iFile<
iFile+=size