⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fat.c

📁 STM32_电子相框.rar
💻 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 + -