📄 fat32.h
字号:
#include <sd.h>
#include <ctype.h>
/*
分区记录结构如下
*/
struct PartRecord
{
unsigned char Active; //0x80表示此分区有效
unsigned char StartHead; //分区的开始头
unsigned char StartCylSect[2];//开始柱面与扇区
unsigned char PartType; //分区类型
unsigned char EndHead; //分区的结束头
unsigned char EndCylSect[2]; //结束柱面与扇区
unsigned char StartLBA[4]; //分区的第一个扇区
unsigned char Size[4]; //分区的大小
};
/*
分区扇区(绝对0扇区)定义如下
*/
struct PartSector
{
unsigned char PartCode[446]; //MBR的引导程序
struct PartRecord Part[4]; //4个分区记录
unsigned char BootSectSig0;
unsigned char BootSectSig1;
};
struct FAT32_FAT_Item
{
unsigned char Item[4];
};
struct FAT32_FAT
{
struct FAT32_FAT_Item Items[128];
};
/*
FAT32中对BPB的定义如下 一共占用90个字节
*/
struct FAT32_BPB
{
unsigned char BS_jmpBoot[3]; //跳转指令 offset: 0
unsigned char BS_OEMName[8]; // offset: 3
unsigned char BPB_BytesPerSec[2];//每扇区字节数 offset:11
unsigned char BPB_SecPerClus[1]; //每簇扇区数 offset:13
unsigned char BPB_RsvdSecCnt[2]; //保留扇区数目 offset:14
unsigned char BPB_NumFATs[1]; //此卷中FAT表数 offset:16
unsigned char BPB_RootEntCnt[2]; //FAT32为0 offset:17
unsigned char BPB_TotSec16[2]; //FAT32为0 offset:19
unsigned char BPB_Media[1]; //存储介质 offset:21
unsigned char BPB_FATSz16[2]; //FAT32为0 offset:22
unsigned char BPB_SecPerTrk[2]; //磁道扇区数 offset:24
unsigned char BPB_NumHeads[2]; //磁头数 offset:26
unsigned char BPB_HiddSec[4]; //FAT区前隐扇区数 offset:28
unsigned char BPB_TotSec32[4]; //该卷总扇区数 offset:32
unsigned char BPB_FATSz32[4]; //一个FAT表扇区数 offset:36
unsigned char BPB_ExtFlags[2]; //FAT32特有 offset:40
unsigned char BPB_FSVer[2]; //FAT32特有 offset:42
unsigned char BPB_RootClus[4]; //根目录簇号 offset:44
unsigned char FSInfo[2]; //保留扇区FSINFO扇区数offset:48
unsigned char BPB_BkBootSec[2]; //通常为6 offset:50
unsigned char BPB_Reserved[12]; //扩展用 offset:52
unsigned char BS_DrvNum[1]; // offset:64
unsigned char BS_Reserved1[1]; // offset:65
unsigned char BS_BootSig[1]; // offset:66
unsigned char BS_VolID[4]; // offset:67
unsigned char BS_FilSysType[11]; // offset:71
unsigned char BS_FilSysType1[8]; //"FAT32 " offset:82
};
// Structure of a dos directory entry.
struct direntry
{
unsigned char deName[8]; // filename, blank filled
unsigned char deExtension[3]; // extension, blank filled
unsigned char deAttributes; // file attributes
unsigned char deLowerCase; // NT VFAT lower case flags (set to zero)
unsigned char deCHundredth; // hundredth of seconds in CTime
unsigned char deCTime[2]; // create time
unsigned char deCDate[2]; // create date
unsigned char deADate[2]; // access date
unsigned char deHighClust[2]; // high unsigned chars of cluster number
unsigned char deMTime[2]; // last update time
unsigned char deMDate[2]; // last update date
unsigned char deLowCluster[2]; // starting cluster of file
unsigned char deFileSize[4]; // size of file in unsigned chars
};
// Stuctures
struct FileInfoStruct
{
unsigned char FileName[12];
unsigned long FileStartCluster; //< file starting cluster for last file accessed
unsigned long FileCurCluster;
unsigned long FileNextCluster;
unsigned long FileSize; //< file size for last file accessed
unsigned char FileAttr; //< file attr for last file accessed
unsigned short FileCreateTime; //< file creation time for last file accessed
unsigned short FileCreateDate; //< file creation date for last file accessed
unsigned short FileMTime;
unsigned short FileMDate;
unsigned long FileSector; //<file record place
unsigned int FileOffset; //<file record offset
};
/*
FAT32初始化时初始参数装入如下结构体中
*/
struct FAT32_Init_Arg
{
unsigned char BPB_Sector_No;
unsigned long Total_Size;
unsigned long FirstDirClust; //first directory cluster
unsigned long FirstDataSector; // The first sector number of data
unsigned int BytesPerSector; // unsigned chars per sector
unsigned int FATsectors; // The amount sector a FAT occupied
unsigned int SectorsPerClust; // Sector per cluster
unsigned long FirstFATSector; // The first FAT sector
unsigned long FirstDirSector; // The first Dir sector
unsigned long RootDirSectors; // The sector number a Root dir occupied
unsigned long RootDirCount; // The count of directory in root dir
};
//#define FIND_BPB_UP_RANGE 2000 //BPB不一定在0扇区,对0~FINE_BPB_UP_RANGE扇区进行扫描
unsigned char xdata FAT32_Buffer[512]; //扇区数据读写缓冲区
struct FAT32_Init_Arg Init_Arg; //初始化参数结构体实体
struct FileInfoStruct FileInfo; //文件信息结构体实体
unsigned char * FAT32_ReadSector(unsigned long LBA,unsigned char *buf) //FAT32中读取扇区的函数
{
MMC_get_data_LBA(LBA,512,buf);
return buf;
}
unsigned char FAT32_WriteSector(unsigned long LBA,unsigned char *buf)//FAT32中写扇区的函数
{
return MMC_write_sector(LBA,buf);
}
unsigned long lb2bb(unsigned char *dat,unsigned char len) //小端转为大端
{
unsigned long temp=0;
unsigned long fact=1;
unsigned char i=0;
for(i=0;i<len;i++)
{
temp+=dat[i]*fact;
fact*=256;
}
return temp;
}
unsigned long FAT32_FindBPB() //寻找BPB所在的扇区号
{
/*
unsigned long Range=0;
while(Range<FIND_BPB_UP_RANGE)
{
FAT32_ReadSector(Range,FAT32_Buffer);
if(FAT32_Buffer[0]==0xeb && FAT32_Buffer[2]==0x90)
break;
Range++;
}
return Range;*/
FAT32_ReadSector(0,FAT32_Buffer);
return lb2bb(((((struct PartSector *)(FAT32_Buffer))->Part[0]).StartLBA),4);
}
unsigned long FAT32_Get_Total_Size() //存储器的总容量,单位为M
{
FAT32_ReadSector(Init_Arg.BPB_Sector_No,FAT32_Buffer);
return ((float)(lb2bb((((struct FAT32_BPB *)(FAT32_Buffer))->BPB_TotSec32),4)))*0.0004883;
}
void FAT32_Init(struct FAT32_Init_Arg *arg)
{
struct FAT32_BPB *bpb=(struct FAT32_BPB *)(FAT32_Buffer);
arg->BPB_Sector_No =FAT32_FindBPB();
arg->Total_Size =FAT32_Get_Total_Size();
arg->FATsectors =lb2bb((bpb->BPB_FATSz32) ,4);
arg->FirstDirClust =lb2bb((bpb->BPB_RootClus) ,4);
arg->BytesPerSector =lb2bb((bpb->BPB_BytesPerSec),2); //每扇区字节数
arg->SectorsPerClust =lb2bb((bpb->BPB_SecPerClus) ,1); //每簇扇区数
arg->FirstFATSector =lb2bb((bpb->BPB_RsvdSecCnt) ,2)+arg->BPB_Sector_No;//第一个FAT表扇区
arg->RootDirCount =lb2bb((bpb->BPB_RootEntCnt) ,2); //根目录项数
arg->RootDirSectors =(arg->RootDirCount)*32>>9; //根目录占用的扇区数
arg->FirstDirSector =(arg->FirstFATSector)+(bpb->BPB_NumFATs[0])*(arg->FATsectors);//第一个目录扇区
arg->FirstDataSector =(arg->FirstDirSector)+(arg->RootDirSectors); //第一个数据扇区
}
void FAT32_EnterRootDir()
{
unsigned long iRootDirSector;
unsigned long iDir;
struct direntry *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(struct direntry))
{
pDir=((struct direntry *)(FAT32_Buffer+iDir));
if((pDir->deName)[0]!=0x00 /*无效目录项*/ && (pDir->deName)[0]!=0xe5 /*无效目录项*/ && (pDir->deName)[0]!=0x0f /*无效属性*/)
{
Printf_File_Name(pDir->deName);
}
}
}
}
void FAT32_CopyName(unsigned char *Dname,unsigned char *filename)
{
unsigned char i=0;
for(;i<11;i++)
{
Dname[i]=filename[i];
}
Dname[i]=0;
}
unsigned long FAT32_EnterDir(char *path)
{
unsigned long iDirSector;
unsigned long iCurSector=Init_Arg.FirstDirSector;
unsigned long iDir;
struct direntry *pDir;
unsigned char DirName[12];
unsigned char depth=0,i=0;
while(path[i]!=0)
{
if(path[i]=='\\')
{
depth++;
}
i++;
}
if(depth==1)
{
return iCurSector; //如果是根目录,直接返回当前扇区号
}
for(iDirSector=iCurSector;iDirSector<(Init_Arg.FirstDirSector)+(Init_Arg.SectorsPerClust);iDirSector++)
{
FAT32_ReadSector(iDirSector,FAT32_Buffer);
for(iDir=0;iDir<Init_Arg.BytesPerSector;iDir+=sizeof(struct direntry))
{
pDir=((struct direntry *)(FAT32_Buffer+iDir));
if((pDir->deName)[0]!=0x00 /*无效目录项*/ && (pDir->deName)[0]!=0xe5 /*无效目录项*/ && (pDir->deName)[0]!=0x0f /*无效属性*/)
{
Printf_File_Name(pDir->deName);
}
}
}
}
unsigned char FAT32_CompareName(unsigned char *sname,unsigned char *dname)
{
unsigned char i,j=8;
unsigned char name_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]) return 0;
}
//Printf(name_temp,0);
return 1;
}
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.FirstFATSector);
FAT32_ReadSector(temp,FAT32_Buffer);
pFAT=(struct FAT32_FAT *)FAT32_Buffer;
pFAT_Item=&((pFAT->Items)[LastCluster%128]);
return lb2bb(pFAT_Item,4);
}
struct FileInfoStruct * FAT32_OpenFile(char *filepath)
{
unsigned char depth=0;
unsigned char i,index;
unsigned long iFileSec,iCurFileSec,iFile;
struct direntry *pFile;
unsigned char len=strlen(filepath);
for(i=0;i<len;i++)
{
if(filepath[i]=='\\')
{
depth++;
index=i+1;
}
}
iCurFileSec=FAT32_EnterDir(filepath)/*Init_Arg.FirstDirSector*/;
Printf("iCurFileSec",iCurFileSec);
for(iFileSec=iCurFileSec;iFileSec<iCurFileSec+(Init_Arg.SectorsPerClust);iFileSec++)
{
FAT32_ReadSector(iFileSec,FAT32_Buffer);
for(iFile=0;iFile<Init_Arg.BytesPerSector;iFile+=sizeof(struct direntry))
{
pFile=((struct direntry *)(FAT32_Buffer+iFile));
if(FAT32_CompareName(filepath+index,pFile->deName))
{
//PutHex(pFile->deFileSize[0]);
//PutHex(pFile->deFileSize[1]);
//PutHex(pFile->deFileSize[2]);
//PutHex(pFile->deFileSize[3]);
FileInfo.FileSize=lb2bb(pFile->deFileSize,4);
strcpy(FileInfo.FileName,filepath+index);
FileInfo.FileStartCluster=lb2bb(pFile->deLowCluster,2)+lb2bb(pFile->deHighClust,2)*65536;
FileInfo.FileCurCluster=FileInfo.FileStartCluster;
FileInfo.FileNextCluster=FAT32_GetNextCluster(FileInfo.FileCurCluster);
FileInfo.FileOffset=0;
Printf("FileStartCluster",FileInfo.FileStartCluster);
return &FileInfo;
}
}
}
}
void FAT32_ReadFileToMp3(struct FileInfoStruct *pstru,unsigned long len)
{
unsigned long Sub=pstru->FileSize-pstru->FileOffset;
unsigned long iSectorInCluster=0;
unsigned long i=0;
while(pstru->FileNextCluster!=0x0fffffff)
{
for(iSectorInCluster=0;iSectorInCluster<Init_Arg.SectorsPerClust;iSectorInCluster++)
{
FAT32_ReadSector((((pstru->FileCurCluster)-2)*(Init_Arg.SectorsPerClust))+Init_Arg.FirstDataSector+(iSectorInCluster),FAT32_Buffer);
pstru->FileOffset+=Init_Arg.BytesPerSector;
Sub=pstru->FileSize-pstru->FileOffset;
for(i=0;i<Init_Arg.BytesPerSector;i++)
{
send(FAT32_Buffer[i]);
}
}
pstru->FileCurCluster=pstru->FileNextCluster;
pstru->FileNextCluster=FAT32_GetNextCluster(pstru->FileCurCluster);
}
iSectorInCluster=0;
while(Sub>=Init_Arg.BytesPerSector)
{
FAT32_ReadSector((((pstru->FileCurCluster)-2)*(Init_Arg.SectorsPerClust))+Init_Arg.FirstDataSector+(iSectorInCluster++),FAT32_Buffer);
pstru->FileOffset+=Init_Arg.BytesPerSector;
Sub=pstru->FileSize-pstru->FileOffset;
for(i=0;i<Init_Arg.BytesPerSector;i++)
{
send(FAT32_Buffer[i]);
}
}
FAT32_ReadSector((((pstru->FileCurCluster)-2)*(Init_Arg.SectorsPerClust))+Init_Arg.FirstDataSector+(iSectorInCluster),FAT32_Buffer);
for(i=0;i<Sub;i++)
{
send(FAT32_Buffer[i]);
}
Printf("FileNextCluster",pstru->FileNextCluster);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -