FAT32文件系统实现单片机MP3播放器 源代码要点.docx
- 文档编号:6177266
- 上传时间:2023-01-04
- 格式:DOCX
- 页数:19
- 大小:21.43KB
FAT32文件系统实现单片机MP3播放器 源代码要点.docx
《FAT32文件系统实现单片机MP3播放器 源代码要点.docx》由会员分享,可在线阅读,更多相关《FAT32文件系统实现单片机MP3播放器 源代码要点.docx(19页珍藏版)》请在冰豆网上搜索。
FAT32文件系统实现单片机MP3播放器源代码要点
#include
#include
/*
SD卡MP3播放器源代码
*/
sbitXDCS=P2^2;
sbitDREQ=P3^5;
sbitXRESET=P3^4;
sbitXCS=P2^5;
sbitCLK=P3^3;
sbitDATA=P2^3;
#defineVOL_VALUE0x0000
/*
分区记录结构
*/
structPartRecord
{
unsignedcharActive;//0x80表示此分区有效
unsignedcharStartHead;//分区的开始头
unsignedcharStartCylSect[2];//开始柱面与扇区
unsignedcharPartType;//分区类型
unsignedcharEndHead;//分区的结束头
unsignedcharEndCylSect[2];//结束柱面与扇区
unsignedcharStartLBA[4];//分区的第一个扇区
unsignedcharSize[4];//分区的大小
};
/*
分区扇区(绝对0扇区)定义如下
*/
structPartSector
{
unsignedcharPartCode[446];//MBR的引导程序
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];//FAT32为0offset:
19
unsignedcharBPB_Media[1];//存储介质offset:
21
unsignedcharBPB_FATSz16[2];//FAT32为0offset:
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];//FAT32特有offset:
42
unsignedcharBPB_RootClus[4];//根目录簇号offset:
44
unsignedcharFSInfo[2];//保留扇区FSINFO扇区数offset:
48
unsignedcharBPB_BkBootSec[2];//通常为6offset:
50
unsignedcharBPB_Reserved[12];//扩展用offset:
52
unsignedcharBS_DrvNum[1];//offset:
64
unsignedcharBS_Reserved1[1];//offset:
65
unsignedcharBS_BootSig[1];//offset:
66
unsignedcharBS_VolID[4];//offset:
67
unsignedcharBS_FilSysType[11];//offset:
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;// unsignedlongFileCurCluster;//文件当前簇号 unsignedlongFileNextCluster;//下一簇号 unsignedlongFileSize;// unsignedcharFileAttr;// unsignedshortFileCreateTime;// unsignedshortFileCreateDate;// unsignedshortFileMTime;//文件修改时间 unsignedshortFileMDate;//文件修改日期 unsignedlongFileSector;// unsignedlongFileOffset;// }; /* 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 { 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 { MMC_Init();//SD卡初始化 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所在的扇区号 arg->Total_Size=FAT32_Get_Total_Size();//FAT32_Get_Total_Size()可以返回磁盘的总容量,单位是兆 arg->FATsectors=lb2bb((bpb->BPB_FATSz32),4);//装入FAT表占用的扇区数到FATsectors中 arg->FirstDirClust=lb2bb((bpb->BPB_RootClus),4);//装入根目录簇号到FirstDirClust中 arg->BytesPerSector=lb2bb((bpb->BPB_BytesPerSec),2);//装入每扇区字节数到BytesPerSector中 arg->SectorsPerClust=lb2bb((bpb->BPB_SecPerClus),1);//装入每簇扇区数到SectorsPerClust中 arg->FirstFATSector=lb2bb((bpb->BPB_RsvdSecCnt),2)+arg->BPB_Sector_No;//装入第一个FAT表扇区号到FirstFATSector中 arg->RootDirCount=lb2bb((bpb->BPB_RootEntCnt),2);//装入根目录项数到RootDirCount中 arg->RootDirSectors=(arg->RootDirCount)*32>>9;//装入根目录占用的扇区数到RootDirSectors中 arg->FirstDirSector=(arg->FirstFATSector)+(bpb->BPB_NumFATs[0])*(arg->FATsectors);//装入第一个目录扇区到FirstDirSector中 arg->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 { pDir=((structdirentry*)(FAT32_Buffer+iDir)); if((pDir->deName)[0]! =0x00/*无效目录项*/&&(pDir->deName)[0]! =0xe5/*无效目录项*/&&(pDir->deName)[0]! =0x0f/*无效属性*/) { Printf_File_Name(pDir->deName); } } } } voidFAT32_CopyName(unsignedchar*Dname,unsignedchar*filename) { unsignedchari=0; for(;i<11;i++) { Dname[i]=filename[i]; } Dname[i]=0; } unsignedlongFAT32_EnterDir(char*path) { unsignedlongiDirSector; unsignedlongiCurSector=Init_Arg.FirstDirSector; unsignedlongiDir; structdirentry*pDir; unsignedcharDirName[12]; unsignedchardepth=0,i=0; while(path[i]! =0) { if(path[i]=='\\') { depth++; } i++; } if(depth==1) { returniCurSector;//如果是根目录,直接返回当前扇区号 } for(iDirSector=iCurSector;iDirSector<(Init_Arg.FirstDirSector)+(Init_Arg.SectorsPerClust);iDirSector++) { FAT32_ReadSector(iDirSector,FAT32_Buffer); for(iDir=0;iDir { pDir=((structdirentry*)(FAT32_Buffer+iDir)); if((pDir->deName)[0]! =0x00/*无效目录项*/&&(pDir->deName)[0]! =0xe5/*无效目录项*/&&(pDir->deName)[0]! =0x0f/*无效属性*/) { Printf_File_Name(pDir->deName); } } } } unsignedcharFAT32_CompareName(unsignedchar*sname,unsignedchar*dname) { unsignedchari,j=8; unsignedcharname_temp[12]; for(i=0;i<11;i++)name_temp[i]=0x20; name_temp[11]=0; i=0; while(sname[i]! ='.') { name_temp[i]=sname[i]; i++; } i++; while(sname[i]! =0) { name_temp[j++]=sname[i]; i++; } //Printf(name_temp,0); for(i=0;i<11;i++) { if(name_temp[i]! =dname[i])return0; } //Printf(name_temp,0); 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); for(i=0;i { if(filepath[i]=='\\') { depth++; index=i+1; } } iCurFileSec=FAT32_EnterDir(filepath); //Printf("iCurFileSec",iCurFileSec); for(iFileSec=iCurFileSec;iFileSec { FAT32_ReadSector(iFileSec,FAT32_Buffer); for(iFile=0;iFile
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- FAT32文件系统实现单片机MP3播放器 源代码要点 FAT32 文件系统 实现 单片机 MP3 播放 源代码 要点