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

📄 fat.c

📁 FAT32文件系统源码
💻 C
字号:
#include "fat.h"

unsigned char xdata  FAT32_Buffer[512]; //扇区数据读写缓冲区xdata
struct FAT32_Init_Arg Init_Arg;	       //初始化参数结构体实体
struct FileInfoStruct FileInfo;   

/*********************
FAT32中读取扇区的函数
返回对缓冲区的首地址buf
*********************/
unsigned char * FAT32_ReadSector(unsigned long LBA,unsigned char *buf)
{
 MMC_get_data_LBA(LBA,512,buf);
 return buf;
}
/**********************
FAT32中写扇区的函数
返回0:写扇区成功
返回非0:写扇区失败
**********************/
unsigned char FAT32_WriteSector(unsigned long LBA,unsigned char *buf)
{
 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=fact<<8;
 }
  return temp;
}
/***************************
查找BPB所在扇区号,这里固定为0扇区
***************************/
unsigned long  FAT32_FindBPB()  //寻找BPB所在的扇区号
{
 FAT32_ReadSector(0,FAT32_Buffer);
 return lb2bb(((((struct PartSector *)(FAT32_Buffer))->Part[0]).StartLBA),4); 
}
/***********************
存储器的总容量,单位为M
返回为Float型
************************/
unsigned long FAT32_Get_Total_Size()//
{
 FAT32_ReadSector(Init_Arg.BPB_Sector_No,FAT32_Buffer);
 return ((float)(lb2bb((((struct FAT32_BPB *)(FAT32_Buffer))->BPB_TotSec32),4)))*0.0004883;
}
/*****************************
文件系统初始化
将BPB段的给类信息装入到BPB结构体当中
******************************/
void FAT32_Init(struct FAT32_Init_Arg *arg)
{
 struct FAT32_BPB *bpb=(struct FAT32_BPB *)(FAT32_Buffer);             //将数据缓冲区指针转为struct FAT32_BPB 型指针
 arg->BPB_Sector_No   =FAT32_FindBPB();                                             //FAT32_FindBPB()可以返回BPB所在的扇区号
 arg->Total_Size      =FAT32_Get_Total_Size();                                        //FAT32_Get_Total_Size()可以返回磁盘的总容量,单位是兆
 arg->FATsectors      =lb2bb((bpb->BPB_FATSz32)    ,4);                       //装入FAT表占用的扇区数到FATsectors中
 arg->FirstDirClust   =lb2bb((bpb->BPB_RootClus)   ,4);                        //装入根目录簇号到FirstDirClust中
 arg->BytesPerSector  =lb2bb((bpb->BPB_BytesPerSec),2);                   //装入每扇区字节数到BytesPerSector中
 arg->SectorsPerClust =lb2bb((bpb->BPB_SecPerClus) ,1);                   //装入每簇扇区数到SectorsPerClust 中
 arg->FirstFATSector  =lb2bb((bpb->BPB_RsvdSecCnt) ,2)+arg->BPB_Sector_No;//装入第一个FAT表扇区号到FirstFATSector 中
 arg->RootDirCount    =lb2bb((bpb->BPB_RootEntCnt) ,2);                   //装入根目录项数到RootDirCount中
 arg->RootDirSectors  =(arg->RootDirCount)*32>>9;                           //装入根目录占用的扇区数到RootDirSectors中
 arg->FirstDirSector  =(arg->FirstFATSector)+(bpb->BPB_NumFATs[0])*(arg->FATsectors); //装入第一个目录扇区到FirstDirSector中
 arg->FirstDataSector =(arg->FirstDirSector)+(arg->RootDirSectors); //装入第一个数据扇区到FirstDataSector中
}

/*************************
根文件下目录打印函数
最多可打印一个蔟内的目录
如果一个族的大小为8个扇区,则最多可打印128个目录
*************************/
void FAT32_EnterRootDir()
{
 unsigned long iRootDirSector;
 unsigned long iDir;
 unsigned short y=33;
 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);/*在此可更换其他显示器件的打印字符串函数*/
	pDir->deName[11]=0;
	ClearScreen(0,240,y,16,Black);
	LCD_PutString(0,y,pDir->deName,White,Black);
    y=y+20;
	if(y>=288)
	 {y=33;
 	  //ClearScreen(0,240,0,320,Black);
	  //button(0,0,"K1",Green);
      //button(0,288,"K1",Green);
	 }
   }
  }
 }
}

/************************
文件名复制函数
*Dname:目的字符串
*filename:源字符串
************************/
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 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);
 /*开始进行比较,相同则返回1,不同则返回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((unsigned char*)pFAT_Item,4);
}
/********
目录名比较函数,用以查找目录确定簇号
*********/
unsigned char FAT32_CompareDir(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++;
 }
 for(i=0;i<11;i++)
 {
  if(name_temp[i]!=dname[i]) return 0;
 }
  //Printf(name_temp,0);
 return 1;
}
unsigned long FAT32_EnterDir(char *path)
{
  unsigned long iDirSector;
 unsigned long iCurSector=Init_Arg.FirstDirSector;
 unsigned long iDir;
 unsigned short y=32;
 struct direntry *pDir;
 unsigned char DirName[12],find_flag=0;
 unsigned char depth=0,index=0;
 unsigned char i=0;
 while(path[i]!=0)
 {
  if(path[i]=='\\')
  { 
   depth++;
   index=i+1;
  }
  i++; 
 }
 if(depth==1)
 {
  return iCurSector;    //如果是根目录,直接返回当前扇区号
 }
 //if(depth--)
 if(depth==2)
 {
 while(!find_flag)
 {for(iCurSector;iCurSector<(Init_Arg.FirstDirSector)+(Init_Arg.SectorsPerClust);iCurSector++)
  {FAT32_ReadSector(iCurSector,FAT32_Buffer);
   for(iDir=0;iDir<Init_Arg.BytesPerSector;iDir+=sizeof(struct direntry))
   {
   pDir=((struct direntry *)(FAT32_Buffer+iDir));
    if(FAT32_CompareDir(path+1,pDir->deName))//index/path+1
    {
        FileInfo.FileSize=lb2bb(pDir->deFileSize,4);
	strcpy(FileInfo.FileName,path+1);
	FileInfo.FileStartCluster=lb2bb(pDir->deLowCluster,2)+lb2bb(pDir->deHighClust,2)*65536;
	FileInfo.FileCurCluster=FileInfo.FileStartCluster;
	FileInfo.FileNextCluster=FAT32_GetNextCluster(FileInfo.FileCurCluster);
	FileInfo.FileOffset=0;
        find_flag=1;
        break;
    }
   }
  }
 }
 iCurSector=(FileInfo.FileStartCluster-2)*Init_Arg.SectorsPerClust+Init_Arg.FirstDataSector;
 for(iDirSector=iCurSector;iDirSector<iCurSector+(Init_Arg.SectorsPerClust);iDirSector++)
 {
  FAT32_ReadSector(iDirSector,FAT32_Buffer);//iDirSector
  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);
	pDir->deName[11]=0;
	ClearScreen(0,240,y,16,Black);
	LCD_PutString(0,y,pDir->deName,White,Black);
    y=y+20;
	if(y>=288)
	 {y=32;
 	  //ClearScreen(0,240,0,320,Black);
	 }
   }
  }
 }
}
}
struct FileInfoStruct * FAT32_OpenFile(char *filepath)
{
 unsigned char depth=0;
 unsigned char i=0,index,len=0;
 unsigned long iFileSec,iCurFileSec,iFile;
 struct direntry *pFile;
 while(filepath[i]!='\0')
 {i++;
  len++;
 }
 //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_ReadFileToBMP(struct FileInfoStruct *pstru,unsigned int x0,unsigned int xlong,unsigned int y0,unsigned int ylong)
{
 unsigned long Sub=pstru->FileSize-pstru->FileOffset;
 unsigned long iSectorInCluster=0;
 unsigned long i=0;
 unsigned int x=x0,y=y0;
 while(pstru->FileNextCluster!=0x0fffffff)  //如果FAT中的簇项为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<256;i++)                    //然后写到液晶屏,可以显示256个像素,每个像素16位即2个字节
	   {   
   	   LCD_SetPos(x,x,y,y);
   	   Write_Data(FAT32_Buffer[2*i+1],FAT32_Buffer[2*i]);	 
	   x++;
	   if(x==(x0+xlong))                         //检测是否写到屏的边缘 240x320
	     {
	     y++;
	     x=x0;
	     if(y>=(y0+ylong))
	       {//y=y0;
		    goto loop;
		   }

	     }
	   }
  }
  pstru->FileCurCluster=pstru->FileNextCluster;  
  pstru->FileNextCluster=FAT32_GetNextCluster(pstru->FileCurCluster);   //这里是FAT簇链的传递
 }
 iSectorInCluster=0;
 while(iSectorInCluster<4)   //处理不足一簇,而足扇区的数据
 {
  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<256;i++)                    //然后写到液晶屏,可以显示256个像素,每个像素16位即2个字节
	   {   
   	    LCD_SetPos(x,x,y,y);
   	   Write_Data(FAT32_Buffer[2*i+1],FAT32_Buffer[2*i]);	 
	   x++;
	   if(x==(x0+xlong))                         //检测是否写到屏的边缘 240x320
	     {
	     y++;
	     x=x0;
	     if(y>=(y0+ylong))
	       {//y=y0;
		    goto loop;
		   }

	     }
	    }
  }
  loop: y=0;
}

void FAT32_ReadFile(struct FileInfoStruct *pstru)
{
 unsigned long Sub=pstru->FileSize-pstru->FileOffset;
 unsigned long iSectorInCluster=0;
 unsigned long i=0;
 unsigned short x=0,y=32;
 while(pstru->FileNextCluster!=0x0fffffff)  //如果FAT中的簇项为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++)
   {
    //ClearScreen(0,240,y,16,Black);
	LCD_PutChar(x,y,FAT32_Buffer[i],Black,White);
	x=x+8;
	if(x==240)
	  {x=0;
	   y=y+16;
	   if(y>=288)
	    {y=32;
		 //ClearScreen(0,240,0,320,White);
		 //button(0,0,"K1",Green);
         //button(0,288,"K1",Green);
		}
	   }
	send(FAT32_Buffer[i]);   //将数据发送到终端上显示
    
   }
  }
  pstru->FileCurCluster=pstru->FileNextCluster;  
  pstru->FileNextCluster=FAT32_GetNextCluster(pstru->FileCurCluster);   //这里是FAT簇链的传递
 }
 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++)
  {
   //ClearScreen(0,240,y,16,Black);
   LCD_PutChar(x,y,FAT32_Buffer[i],Black,White);
	x=x+8;
	if(x==240)
	  {x=0;
	   y=y+16;
	   if(y>=288)
	    {y=32;
		 //ClearScreen(0,240,0,320,White);
		 //button(0,0,"K1",Green);
         //button(0,288,"K1",Green);
		}
	   }
   send(FAT32_Buffer[i]);
  }
 }
 FAT32_ReadSector((((pstru->FileCurCluster)-2)*(Init_Arg.SectorsPerClust))+Init_Arg.FirstDataSector+(iSectorInCluster),FAT32_Buffer); //读取最后一个扇区
 for(i=0;i<Sub;i++)    //Sub为最后剩余的字节数
 {
  //ClearScreen(0,240,y,16,Black);
  LCD_PutChar(x,y,FAT32_Buffer[i],Black,White);
	x=x+8;
	if(x==240)
	  {x=0;
	   y=y+16;
	   if(y>=288)
	    {y=32;
		 //ClearScreen(0,240,0,320,White);
		 //button(0,0,"K1",Green);
         //button(0,288,"K1",Green);
		}
	   }
  send(FAT32_Buffer[i]);
 }	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -