?? fat.c
字號:
unsigned long DBR_Sector;//記錄DBR的扇區號
ulong Total_Size;//總容量
ulong FATsectors;//FAT表占用扇區數
ulong FirstDirClust;//根目錄所在簇
ulong BytesPerSector;//每個扇區的字節數
ulong SectorsPerClust;//每個簇的扇區數
ulong FirstFATSector;//第一個FAT表的扇區號
ulong FirstDirSector;//根目錄的扇區號
ulong FileFirstCluster;//次態操作文件起始簇號
ulong TargetDirClust;//目標文件夾所在簇
ulong TargetDirSector;//目標文件夾扇區號
uchar success;//搜索成功標志 0 FAIL 1 找到文件 2 找到目錄
//-------FAT32系統初始化-------------------------------------------
void FAT32_Init()
{
DBR_Sector=0;//記錄DBR的扇區號
Total_Size=0;//總容量
FATsectors=0;//FAT表占用扇區數
FirstDirClust=0;//根目錄所在簇
BytesPerSector=0;//每個扇區的字節數
SectorsPerClust=0;//每個簇的扇區數
FirstFATSector=0;//第一個FAT表的扇區號
FirstDirSector=0;//根目錄的扇區號
FileFirstCluster=0;//次態操作文件起始簇號
TargetDirClust=0;//目標文件夾所在簇
TargetDirSector=0;//目標文件夾扇區號
success=0;//文件搜索成功標志 0 FAIL 1 BMP 2BIN
FAT32_is_MBR();//讀取0扇區,檢測有沒有MBR(主引導記錄)
Search_DBR(); //讀DBR 在DBR中計算出重要參數供后續使用
}
//--------FAT32中讀扇區函數-----------------------------------------
void FAT32_ReadSector(ulong addr,uchar *buf)
{
SD_read_sector(addr,buf);
}
//-------FAT32中寫扇區函數 ------------------------------------------
void FAT32_WriteSector(ulong addr,uchar *buf)
{
SD_write_sector(addr,buf);
}
//---------小端模式轉大端 ----------------------------------------------
ulong LE2BE(uchar *dat,uchar len)// 指向字節序列的指針 字節序列中的字節數
{
ulong temp=0,fact=1;
uchar i=0;
for(i=0;i<len;i++)
{
temp+=dat[i]*fact;
fact*=256;
}
return temp;
}
//-----------------小寫轉大寫-------------------------------------------
char L2U(char c)
{
if(c>='a'&&c<='z') return c+'A'-'a';
else return c;
}
//----------讀取0扇區,檢測有沒有MBR(主引導記錄)-------------------------
//------------檢測到MBR --------------------------- --------------------
//------------未檢測到MBR 檢測到DBR 修改DBR_Sector --------------
void FAT32_is_MBR()
{
uchar dat[4],i;
FAT32_ReadSector(0,FAT32_Buffer);
if(FAT32_Buffer[0]!=0XEB)
{
if(FAT32_Buffer[446]==0x80) //判斷分區是否有效 這里只支持一個分區
{
for(i=0;i<4;i++)
{
dat[i]=FAT32_Buffer[454+i];
}
DBR_Sector=LE2BE(dat,4);
}
}
}
//-----------讀DBR 在DBR中計算出重要參數供后續使用-----------------------------
void Search_DBR()
{
uchar dat[4],i,dat1[4]={0xC3,0x03,0x00,0x00};
ulong RsvdSecCnt;//保留扇區數
ulong NumFATs;//FAT表數
FAT32_ReadSector(DBR_Sector,FAT32_Buffer);
if(FAT32_Buffer[0]==0XEB)
{
for(i=0;i<4;i++) dat[i]=FAT32_Buffer[32+i];
Total_Size=(ulong)(LE2BE(dat,4)/2048);//總容量 M
for(i=0;i<4;i++) dat[i]=FAT32_Buffer[36+i];
FATsectors=LE2BE(dat,4);//FAT表占用扇區數
for(i=0;i<4;i++) dat[i]=FAT32_Buffer[44+i];
FirstDirClust=LE2BE(dat,4);//第一個目標所在簇
for(i=0;i<2;i++) dat[i]=FAT32_Buffer[11+i];
BytesPerSector=LE2BE(dat,2);//每個扇區的字節數
dat[0]=FAT32_Buffer[13];
SectorsPerClust=LE2BE(dat,1);//每個簇的扇區數
for(i=0;i<2;i++) dat[i]=FAT32_Buffer[14+i];
RsvdSecCnt=LE2BE(dat,2);//保留扇區數
FirstFATSector=DBR_Sector+RsvdSecCnt;//第一個FAT表的扇區號
dat[0]=FAT32_Buffer[16];
NumFATs=LE2BE(dat,1);//FAT表數
FirstDirSector= FirstFATSector+NumFATs*FATsectors;//第一個目錄的扇區號
TargetDirClust=FirstDirClust;//目標文件夾所在簇
TargetDirSector=FirstDirSector;//目標文件夾扇區號
}
}
//-----------在指定目錄下(全部搜索)定位目標文件夾---------------------------------------------------------
void Search_TargetDir(uchar *Dir_name)
{
uchar i,Cluster_End=0;//根目錄結束標志
ulong Sector,temp=TargetDirSector;
success=0;
while(Cluster_End!=1)
{ for(i=0;i<SectorsPerClust;i++)
{
Sector=temp+i;
FAT32_ReadSector(Sector,FAT32_Buffer);//讀出根目錄扇區
Dir_First_Cluster(Dir_name); //尋找文件夾,定位首簇
if(success==2) break;
}
if(success==2) break;
temp=FAT32_GetNextCluster(TargetDirClust);//讀指定目錄的下1簇繼續搜索目錄
if(temp==0x0fffffff)
Cluster_End=1;//結束標志
else
temp=Cluster_To_Sector(temp);//讀根目錄的下1簇的扇區號
}
}
//-----------讀目標文件夾扇區(全部搜索)搜索目標文件---------------------------------------------------------
void Read_Target_Sector(uchar *File_name,uchar *Exten_name)
{
uchar i,Cluster_End=0;//根目錄結束標志
ulong Sector,temp=TargetDirSector;
while(Cluster_End!=1)
{ for(i=0;i<SectorsPerClust;i++)
{
Sector=temp+i;
FAT32_ReadSector(Sector,FAT32_Buffer);//讀出目標目錄第一個扇區
File_First_Cluster(File_name,Exten_name); //尋找文件,定位首簇
if(success==1) break;
}
if(success==1) break;
temp=FAT32_GetNextCluster(TargetDirClust);//讀目標目錄的下1簇號
if(temp==0x0fffffff)
Cluster_End=1;//結束標志
else
temp=Cluster_To_Sector(temp);//讀目標目錄的下1簇的扇區號
}
}
//------在指定目錄,讀指定文件類型的文件起始簇號,1扇區16條文件記錄 每條記錄32的字節----------------
void File_First_Cluster(uchar *File_name,uchar *Exten_name)//僅支持8位文件名
{
uchar dat[4];
uint i;
uchar j=0;
for(i=0;i<512;i+=32)
{
if(
FAT32_Buffer[i] == File_name[0]&&
FAT32_Buffer[i+1] == File_name[1]&&
FAT32_Buffer[i+2] == File_name[2]&&
FAT32_Buffer[i+3] == File_name[3]&&
FAT32_Buffer[i+4] == File_name[4]&&
FAT32_Buffer[i+5] == File_name[5]&&
FAT32_Buffer[i+6] == File_name[6]&&
FAT32_Buffer[i+7] == File_name[7]&&
FAT32_Buffer[i+8] == Exten_name[0]&&
FAT32_Buffer[i+9] == Exten_name[1]&&
FAT32_Buffer[i+10]== Exten_name[2]
)
{
dat[j++]=FAT32_Buffer[i+26];
dat[j++]=FAT32_Buffer[i+27];
dat[j++]=FAT32_Buffer[i+20];
dat[j++]=FAT32_Buffer[i+21];
FileFirstCluster=LE2BE(dat,4);
success=1; //找到目標文件
break;
}
}
}
void Dir_First_Cluster(uchar *Dir_name) //在指定目錄下尋找指定文件夾,定位首簇
{ //僅支持8位文件名
uchar dat[4];
uint i;
uchar j=0;
for(i=0;i<512;i+=32)
{
if(
FAT32_Buffer[i] == Dir_name[0]&&
FAT32_Buffer[i+1] == Dir_name[1]&&
FAT32_Buffer[i+2] == Dir_name[2]&&
FAT32_Buffer[i+3] == Dir_name[3]&&
FAT32_Buffer[i+4] == Dir_name[4]&&
FAT32_Buffer[i+5] == Dir_name[5]&&
FAT32_Buffer[i+6] == Dir_name[6]&&
FAT32_Buffer[i+7] == Dir_name[7]&&
FAT32_Buffer[i+8] == ' '&& //無擴展名
FAT32_Buffer[i+9] == ' '&&
FAT32_Buffer[i+10]== ' '&&
FAT32_Buffer[i+11]== 16 //屬性為目錄
)
{
dat[j++]=FAT32_Buffer[i+26];
dat[j++]=FAT32_Buffer[i+27];
dat[j++]=FAT32_Buffer[i+20];
dat[j++]=FAT32_Buffer[i+21];
TargetDirClust=LE2BE(dat,4);//目標文件夾所在簇
TargetDirSector=Cluster_To_Sector(TargetDirClust);//目標文件夾扇區號
success=2; //找到目標文件夾
break;
}
}
}
//-------------尋找后繼簇---------------------------------------------------------------
ulong FAT32_GetNextCluster(ulong LastCluster)//當前簇 返回下一簇的簇號
{
ulong temp;
uchar dat[4],i;
temp=((LastCluster/128)+FirstFATSector);
FAT32_ReadSector(temp,FAT32_Buffer);
for(i=0;i<4;i++) dat[i]=FAT32_Buffer[(LastCluster%128)*4+i];
temp=LE2BE(dat,4);//FAT表占用扇區數
return temp;
}
//--------------簇號轉為扇區號 第一扇區-------------------------------------------------------
ulong Cluster_To_Sector(ulong Cluster)
{
ulong temp;
temp=(Cluster-FirstDirClust)*SectorsPerClust+FirstDirSector;
return temp;
}
//----路徑處理函數 根據路徑搜索并定位葉子目錄-----------------------------------------------
void PathProcess(uchar *Path)
{
uchar i=0,j=0,t=0,temp=0,flag=0;
uchar Dir_name[8];
TargetDirSector=FirstDirSector;
for(t=0;t<8;t++) Dir_name[t]=' ';
while(Path[temp]!='\0') temp++;
for(i=0;i<temp;i++)
{
if(flag==1&&Path[i]!='/'&&Path[i]!='\0')
{
Dir_name[j++]=Path[i];
}
if(Path[i]=='/') flag=0;
if(flag==0)
{
for(t=0;t<8;t++)
{
if(Dir_name[t]!=' ') Search_TargetDir(Dir_name);break;
}
for(t=0;t<8;t++) Dir_name[t]=' ';
j=0;
}
if(Path[i]=='/'&&Path[i+1]!='\0') flag=1;
}
}
//-----------讀目標文件夾扇區(全部搜索)搜索指定文件類型的所有文件---------------------------------------------------------
void Read_Target_Sector_All_File_Search(uchar *Exten_name)
{
uchar i,Cluster_End=0;//根目錄結束標志
ulong Sector,temp=TargetDirSector;
while(Cluster_End!=1)
{ for(i=0;i<SectorsPerClust;i++)
{
Sector=temp+i;
FAT32_ReadSector(Sector,FAT32_Buffer);//讀出目標目錄第一個扇區
All_File_Search(Exten_name); //將指定擴展名的文件名記錄下來 并送顯
}
temp=FAT32_GetNextCluster(TargetDirClust);//讀目標目錄的下1簇號
if(temp==0x0fffffff)
Cluster_End=1;//結束標志
else
temp=Cluster_To_Sector(temp);//讀目標目錄的下1簇的扇區號
}
}
//-----------在指定目錄下搜索指定類型的文件--------------------------------------------------------------
void All_File_Search(uchar *Exten_name)
{
uchar File_Name[11];//文件名
uchar dat[4];
uint i;
uchar j=0,k=0;
File_Name[8]=0x0d; //加入回車 方便換行
File_Name[9]=0x0a;
File_Name[10]='\0';
for(i=0;i<512;i+=32)
{
if(
FAT32_Buffer[i+8] == Exten_name[0]&&
FAT32_Buffer[i+9] == Exten_name[1]&&
FAT32_Buffer[i+10]== Exten_name[2]
)
{
for(k=0;k<8;k++)
{
File_Name[k]=FAT32_Buffer[i+k]; //將指定擴展名的文件名記錄下來 并送顯
}
/* File_Name[0]=FAT32_Buffer[0];
File_Name[1]=FAT32_Buffer[1];
File_Name[2]=FAT32_Buffer[2];
File_Name[3]=FAT32_Buffer[3];
File_Name[4]=FAT32_Buffer[4];
File_Name[5]=FAT32_Buffer[5];
File_Name[6]=FAT32_Buffer[6];
File_Name[7]=FAT32_Buffer[7]; */
P0=0;
dat[j++]=FAT32_Buffer[i+26];
dat[j++]=FAT32_Buffer[i+27];
dat[j++]=FAT32_Buffer[i+20];
dat[j++]=FAT32_Buffer[i+21];
//FileFirstCluster=LE2BE(dat,4);
// SHOW_HZ_Asc_xy(500,500,File_Name); //指定位子顯示漢字或ASCLL
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -