📄 fat.c
字号:
#include "fat.h"
INT8U fname[20][8];
INT8U fext[20][3];
INT32U fclust[20];
INT8U fcount;
INT32U fsize[20];
INT32U NextCluster; //指向当前正在读取文件的簇号
INT32U SectorIndex=0; //正在读扇区
////////////////////////////////////////////////////////////////////////////////
//磁盘分区信息
////////////////////////////////////////////////////////////////////////////////
INT8U Partition_Active; // 0x80代表该分区为缺省分区
INT8U Partition_StartHead; // 该分区入口的磁头地址
INT16U Partition_StartCylSect; // 该分区入口的扇区地址和柱面地址
INT8U Partition_PartType; // 该分区类型
INT8U Partition_EndHead; // 该分区结束的扇区地址
INT16U Partition_EndCylSect; // 该分区结束的柱面地址
INT32U Partition_StartLBA; // 该分区内第一个扇区地址
INT32U Partition_Size; // 该分区所包含的扇区总数
////////////////////////////////////////////////////////////////////////////////
//fat32 BPB结构,包括扩展BPB
////////////////////////////////////////////////////////////////////////////////
INT8U BS_jmpBoot[3]; //jmp code
INT8U BS_OEMName[8]; //oem and os like dos5.0
INT16U BPB_BytesPerSec; //扇区字节数
INT8U BPB_SecPerClus; //每簇扇区数
INT16U BPB_RsvdSecCnt; //保留扇区数
INT8U BPB_NumFATs; //FAT数目
INT16U BPB_RootEntCnt; //根目录项数 0
INT16U BPB_TotSec16; //小扇区总数 0
INT8U BPB_Media; //媒体描述符
INT16U BPB_FATSz16; //每FAT扇区数fat32不用为0
INT16U BPB_SecPerTrk; //每道扇区数
INT16U BPB_NumHeads; //磁头数
INT32U BPB_HiddSec; //隐藏扇区数
INT32U BPB_TotSec32; //总扇区数
INT32U BPB_FATSz32; //每FAT扇区数fat32
INT16U BPB_ExtFlags; //fat32扩展标志
INT16U BPB_FSVer; //fat32特有,高位为fat32的主版本号,底位为次版本号
INT32U BPB_RootClus; //根目录簇号
INT16U BPB_FSInfo; //文件系统信息扇区号
INT16U BPB_BKBootSec; //引导扇区备份号
INT8U BPB_Reserved[12]; //保留空间
INT8U BS_drvNum; //物理驱动器号
INT8U BS_Reservd1; //保留
INT8U BS_BootSig; //扩展引导标签
INT32U BS_VolID; //分区序号
INT8U BS_VolLab[11]; //卷标
INT8U BS_FilSysType[8]; //系统ID
////////////////////////////////////////////////////////////////////////////////
//目录信息
////////////////////////////////////////////////////////////////////////////////
INT8U deName[8];
INT8U deExtension[3];
INT32U Clust; //当前目录的簇号
INT16U Nums; //仅FAT12—FAT16中的根目录区有效
INT32U Index; //当前的BLOCK中目录项索引
INT32U FileSize; //文件长度
////////////////////////////////////////////////////////////////////////////////
//文件信息
////////////////////////////////////////////////////////////////////////////////
INT8U DIR_Name[11]; //文件名,没有.
INT8U DIR_Attr; //文件属性,自低至高,只读、隐藏、系统、卷标、子目录、归档
INT8U DIR_NTRes; //系统保留
INT8U DIR_CrtTimeTenth; //创建时间的10毫秒位
INT16U DIR_CrtTime; //创建时间
INT16U DIR_CrtDate; //创建日期
INT16U DIR_LastAccDate; //最后访问日期
INT16U DIR_FstClusHI; //文件起始簇号高16位
INT16U DIR_WrtTime; //最近修改时间
INT16U DIR_WrtDate; //最近修改日期
INT16U DIR_FstClusLO; //文件起始簇号的低16位
INT32U DIR_FileSize; //文件长度
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
INT32U FAT1Sec; //FAT1表的位置
INT32U FAT2Sec;
INT32U FirstDataSector; //第一个根目录位置,区号为2
INT32U FirstDirSector;
////////////////////////////////////////////////////////////////////////////////
INT8U BUFFER[512];
INT8U MP3_BUFFER[512];
INT8U TEXT[512];
INT8U filetype[][3] ={ {"MP3"},{"WMA"},{"MID"},{"LRC"}};
INT32U FAT_MASK;
INT16U RootDirEnts; // 根目录总的项数(FAT12&FAT16)
INT8U Fat_Init(void)
{
uint32 j;
SD_ReadBlock(0,BUFFER);
for(j=0;j<512;j++)
{
TEXT[j]=BUFFER[j];
}
//read partion message
// 读MBR结构//struct bpb710 *bpb;
Partition_PartType=0X55;
// 读取分区表信息// 读引导扇区// 引导扇区号在PartInfo.prStartLBA中
Partition_PartType= BUFFER[450];
//分区信息 FAT32 0x0B
Partition_Size = BUFFER[458]+(BUFFER[459]<<8)+(BUFFER[460]<<16)+(BUFFER[461]<<24);
Partition_StartLBA = BUFFER[454]+(BUFFER[455]<<8)+(BUFFER[456]<<16)+(BUFFER[457]<<24);
//0xF9*512=127488
SD_ReadBlock(Partition_StartLBA,BUFFER); //FAT32 read BPB
BS_OEMName[0] = BUFFER[3];
BS_OEMName[1] = BUFFER[4];
BS_OEMName[2] = BUFFER[5];
BS_OEMName[3] = BUFFER[6];
BS_OEMName[4] = BUFFER[7];
BS_OEMName[5] = BUFFER[8];
BS_OEMName[6] = BUFFER[9];
BS_OEMName[7] = BUFFER[10];
BPB_BytesPerSec = BUFFER[11] |(BUFFER[12] << 8); //0x0200 //每个扇区字节数
BPB_SecPerClus = BUFFER[13]; //0x08 //每个簇的扇区数
BPB_RsvdSecCnt = BUFFER[14] |(BUFFER[15] << 8); //0x20 //保留扇区数
BPB_NumFATs = BUFFER[16]; //0x02 //FAT 表数目
BPB_RootEntCnt = BUFFER[17] | (BUFFER[18] << 8);
BPB_TotSec16 = BUFFER[19] | (BUFFER[20] << 8);
BPB_Media = BUFFER[21];
BPB_FATSz16 = BUFFER[22] | (BUFFER[23] << 8);
BPB_SecPerTrk = BUFFER[24] | (BUFFER[25] << 8);
BPB_NumHeads = BUFFER[26] | (BUFFER[27] << 8);
BPB_HiddSec = BUFFER[28] | (BUFFER[29] << 8) | (BUFFER[30] << 16) | (BUFFER[31] << 24);
BPB_TotSec32 = BUFFER[32] | (BUFFER[33] << 8) | (BUFFER[34] << 16) | (BUFFER[35] << 24);
BPB_FATSz32 = BUFFER[36] | (BUFFER[37] << 8) | (BUFFER[38] << 16) | (BUFFER[39] << 24);
BPB_ExtFlags = BUFFER[40] | (BUFFER[41] << 8);
BPB_FSVer = BUFFER[42] | (BUFFER[43] << 8);
BPB_RootClus = BUFFER[44] | (BUFFER[45] << 8) | (BUFFER[46] << 16) | (BUFFER[47] << 24);
BPB_FSInfo = BUFFER[48] | (BUFFER[49] << 8);
BPB_BKBootSec = BUFFER[50] | (BUFFER[51] << 8);
//BPB_Reserved = BUFFER[52];
BS_drvNum = BUFFER[64];
BS_Reservd1 = BUFFER[65];
BS_BootSig = BUFFER[66];
BS_VolID = BUFFER[67] | (BUFFER[68] << 8) | (BUFFER[69] << 16) | (BUFFER[70] << 24);
//BS_VolLab[0] = BUFFER[71];
//BS_FilSysType[0] = BUFFER[82];
FAT_MASK = FAT32_MASK; //0x0fffffff
Clust = BPB_RootClus;
FAT1Sec = BPB_RsvdSecCnt+Partition_StartLBA;
FAT2Sec = FAT1Sec+BPB_FATSz32;
FirstDataSector = FAT2Sec+BPB_FATSz32;
return 1;
}
INT8U IsMusicFile(INT8U *strName)
{
INT8U i;
for(i=0; i<3; i++)
{
if(filetype[MP3_TYPE][i]!= strName[i]) break;
}
if(i == 3) return 1; // 是MP3文件
for(i=0; i<3; i++)
{
if(filetype[WMA_TYPE][i]!= strName[i]) break;
}
if(i == 3) return 2; // 是WMA文件
/*
for(i=0;i<3;i++)
{
if(filetype[MID_TYPE][i]!=strName[i]) break;
}
if(i == 3) return 3; // 是MIDI文件
*/
return 0;
}
void GetFileClust(void)
{
INT8U i;
INT32U tem;
do{
SD_ReadBlock(FirstDataSector+Index/(BPB_BytesPerSec/32),BUFFER); // 重新读取目录表
tem=(Index*0x20)%BPB_BytesPerSec;
if((BUFFER[tem+11] & ATTR_LONG_FILENAME) != ATTR_LONG_FILENAME); // 是否是长文件名
{
if((BUFFER[tem] != 0xe5) && (BUFFER[tem] != 0x05)) //文件没有删除
{
if((BUFFER[tem+11]&ATTR_DIRECTORY) != ATTR_DIRECTORY) // is it a directory ?
{
for(i=0;i<8;i++)
{
deName[i]=BUFFER[tem+i];
}
for(i=0;i<3;i++)
{
deExtension[i]=BUFFER[tem+8+i];
}
if(IsMusicFile(&deExtension[0]))
{
Clust=(BUFFER[tem+20]<<16) | (BUFFER[tem+21]<<24) | (BUFFER[tem+26]) | (BUFFER[tem+27]<<8);
FileSize=(BUFFER[tem+28]) | (BUFFER[tem+29]<<8)|(BUFFER[tem+30]<<16)|(BUFFER[tem+31]<<24);
Index++;
break;
}
}
}
}
Index++;
if(BUFFER[tem] == 0) // 等所有文件都已经查询完了
{
Index=0;
break;
}
}
while(1);
}
INT32U ReadBlockforCluster(INT32U Sector,INT32U offset)
{
INT32U tmp;
SD_ReadBlock(Sector,BUFFER);
tmp=BUFFER[offset] |(BUFFER[offset+1]<<8) |(BUFFER[offset+2]<<16) |(BUFFER[offset+3]<<24);
return tmp;
}
INT32U fatNextCluster(INT32U cluster)
{
INT32U nextCluster=0;
INT32U fatOffset=0;
INT32U sector=0;
INT16U offset=0;
// if(Partition_PartType == PART_TYPE_FAT32) // 一个表项为 4bytes(32 bits)
//{
fatOffset = cluster << 2;
sector = FAT1Sec + (fatOffset>>9); // 计算FAT扇区号
offset = fatOffset % BPB_BytesPerSec; // 计算FAT扇区号中表项的偏移地址
nextCluster = ReadBlockforCluster(sector,offset); // 读取下一个簇号
// }
/*
else if(Partition_PartType == PART_TYPE_FAT16) // 一个表项为 2bytes(16 bits)
{
fatOffset = cluster << 1; // 计算FAT扇区号
//sector = FirstFATSector + (fatOffset / BPB_BytesPerSec);
offset = fatOffset % BPB_BytesPerSec; // 计算FAT扇区号中表项的偏移地址
nextCluster = ReadBlockforCluster(sector,offset);
}
*/
if (nextCluster >= (CLUST_EOFS & FAT_MASK)) // 是否文件的结束簇
{
nextCluster = CLUST_EOFE;
}
return nextCluster;
}
void GetMusicFile(void)
{
uint8 i;
fcount=0;
while(1)
{
GetFileClust();
if(Index==0) break;
for(i=0;i<8;i++)
{
fname[fcount][i]=deName[i];
}
for(i=0;i<3;i++)
{
if(deExtension[i]>=65) fext[fcount][i]=deExtension[i]+0x20;
else fext[fcount][i]=deExtension[i];
}
fclust[fcount]=Clust;
fsize[fcount]=FileSize;
fcount++;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -