📄 fat16.c
字号:
/* 取文件系统信息 */
/* 操作正确返回:0 */
uchar GetFATInfo(uchar *data)
{
uchar s,*p,i;
uint w;
/* 读硬盘信息 主要取:FAT类型(450)、首扇区地址即DBR地址(454,455,456,457)
总扇区数,根据这个可以算出硬盘大小(458,459,460,461) */
s=sd_read_block(0,data); /* MBR */
if(s!=0)return(s);
p=data;
p+=450;
if(*p!=6)
{ /* 判断文件系统(FAT16-6,FAT32-B) */
return(1);
}
p+=4; /* 取DBR地址 */
DBRSectors=*p++;
DBRSectors+=((ulong)*p++)<<8;
DBRSectors+=((ulong)*p++)<<16;
DBRSectors+=((ulong)*p++)<<24;
TotalSectors=*p++; /* 取总扇区数 */
TotalSectors+=((ulong)*p++)<<8;
TotalSectors+=((ulong)*p++)<<16;
TotalSectors+=((ulong)*p)<<24;
/* 读硬盘信息 主要取:每扇区字节数(11,12)一般为512所以不管、每簇扇区数(13)、
DBR到FAT1的扇区数(14,15)、每个FAT占的扇区数(22,23) */
s=sd_read_block(DBRSectors,data); /* DBR */
if(s!=0)return(s);
p=data;
p+=13;
SecPerClus=*p++; /* 每簇扇区数 */
w=*p++;
w+=(uint)*p<<8;
FATSectors=DBRSectors+w; /* FAT1地址 */
p+=7;
w=*p++;
w+=(uint)*p<<8;
FDTSectors=FATSectors+w*2; /* FDT地址 */
DATASectors=FDTSectors+32; /* DATA地址 */
return(0);
}
#if SeekFile_EN
/* 查找文件 */
/* 找到文件返回0,找不到文件返回0x55,操作错误返回其它数据(不定) */
uchar List(uchar *data)
{
uchar s,i,k,suffix[3],*p,over;
while(1)
{
over=0;
for(k=0;k<Item[list]/(SecPerClus*16);k++)
{
s=sd_read_block(FATSectors+Clus[list-1]/256,data); /* 取下一簇 */
if(s!=0)return(s);
p=data;
p=p+(Clus[list-1]%256)*2;
Clus[list-1]=*p++;
Clus[list-1]+=((uint)*p)<<8;
if(Clus[list-1]>0xfff7)Item[list]=0,over=1;
}
if(over)break;
for(i=(Item[list]%(SecPerClus*16))/16;i<SecPerClus;i++)
{
s=sd_read_block(DATASectors+((ulong)Clus[list-1]-2)*SecPerClus+i,data);
if(s!=0)return(s);
for(k=Item[list]%16;k<16;k++)
{
over=0;
Item[list]++;
p=data;
p+=k*32;
if(*p!=0xe5 && *p!='.')
{
for(s=0;s<3;s++)suffix[s]=*(p+8+s);
if(suffix[0]=='M' && suffix[1]=='P' && suffix[2]=='3')
{ /* MP3文件 */
StartClus=*(p+26);
StartClus+=(uint)*(p+27)<<8;
for(s=0;s<list;s++)Item[s]--;
return(0);
}
else if(*(p+11)==0x10)
{ /* 子目录* */
if(list<3) /* 最高3层 */
{
list++;
Clus[list-1]=*(p+26);
Clus[list-1]+=(uint)*(p+27)<<8;
FileLength=*(p+28);
FileLength+=(ulong)*(p+29)<<8;
FileLength+=(ulong)*(p+30)<<16;
FileLength+=(ulong)*(p+31)<<24;
s=List(data);
if(s==0)return(0);
list--;
over=1;
}
}
}
if(over)break;
}
if(over)break;
}
}
return(0x55);
}
uchar SeekFile(uchar *data)
{
uchar s,i,k,suffix[3],*p,over;
while(Item[0]<512)
{ /* 根目录下有512项 */
i=Item[0]/16;
s=sd_read_block(FDTSectors+i,data);
if(s!=0)return(s);
for(i=Item[0]%16;i<16;i++)
{
over=0;
Item[0]++;
p=data;
p+=i*32;
if(*p!=0xe5)
{
for(s=0;s<3;s++)suffix[s]=*(p+8+s);
if(suffix[0]=='M' && suffix[1]=='P' && suffix[2]=='3')
{ /* MP3文件 */
StartClus=*(p+26);
StartClus+=(uint)*(p+27)<<8;
FileLength=*(p+28);
FileLength+=(ulong)*(p+29)<<8;
FileLength+=(ulong)*(p+30)<<16;
FileLength+=(ulong)*(p+31)<<24;
return(0);
}
else if(*(p+11)==0x10)
{ /* 子目录1 */
if(*p!='A'||*(p+1)!='D'||*(p+2)!='V'||*(p+3)!='E'||*(p+4)!='R'||*(p+5)!='T')
{
list=1;
Clus[list-1]=*(p+26);
Clus[list-1]+=(uint)*(p+27)<<8;
s=List(data);
if(s==0)return(0);
list=0;
over=1;
}
}
}
if(over)break;
}
}
return(0x55);
}
#endif
#if SeekAdvert_EN
/*----------------------------------------------------------*/
/* 查找文件Advert */
/* 找到文件返回0,否则返回0x55,操作出错返回其它数字 */
uchar SeekAdvert(uchar *data,uchar *sub,uchar *adv)
{
uchar s,i,k,suffix[3],*p;
uint term=0,c;
while(term<512)
{ /* 根目录下有512项 */
i=term/16;
s=sd_read_block(FDTSectors+i,data);
if(s!=0)return(s);
for(i=term%16;i<16;i++)
{
term++;
p=data;
p+=i*32;
if(*(p+11)==0x10)
{ /* 子目录1 */
if(*p=='A'&&*(p+1)=='D'&&*(p+2)=='V'&&*(p+3)=='E'&&*(p+4)=='R'&&*(p+5)=='T'&& *(p+6)==*sub && *(p+7)==*(sub+1))
{
c=*(p+26);
c+=(uint)*(p+27)<<8;
term=0;
while(1)
{
for(i=0;i<SecPerClus;i++)
{
s=sd_read_block(DATASectors+((ulong)c-2)*SecPerClus+i,data);
if(s!=0)return(s);
for(k=term%16;k<16;k++)
{
term++;
p=data;
p+=k*32;
if(*p!=0xe5)
{
for(s=0;s<3;s++)suffix[s]=*(p+8+s);
if(suffix[0]=='M' && suffix[1]=='P' && suffix[2]=='3')
{
if(*p==*adv && *(p+1)==*(adv+1) && *(p+2)==*(adv+2))
{
StartClus=*(p+26);
StartClus+=(uint)*(p+27)<<8;
FileLength=*(p+28);
FileLength+=(ulong)*(p+29)<<8;
FileLength+=(ulong)*(p+30)<<16;
FileLength+=(ulong)*(p+31)<<24;
return(0);
}
}
}
}
}
s=sd_read_block(FATSectors+c/256,data); /* 取下一簇 */
if(s!=0)return(s);
p=data;
p=p+(c%256)*2;
c=*p++;
c+=((uint)*p)<<8;
if(c>0xfff7)return(0x55);
}
}
}
}
}
return(0x55);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -