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

📄 fat.c

📁 SD卡调试所用的资料
💻 C
📖 第 1 页 / 共 4 页
字号:
 - 隶属模块:FAT文件系统模块
 - 函数属性:内部
 - 参数说明:dName:指向文件目录项的文件名字段的指针
             pName:指向转换完成后的文件名
 - 返回说明:无
 - 注:此函数配合上面的FilenameMatch函数,就可以实现对文件名通配匹配
 ***********************************************************************/

void FAT32_toFileName(char *dName,char *pName)
{
 char i=7,j=0,k=0;
 while(dName[i--]==' ');
 for(j=0;j<i+2;j++) pName[j]=L2U(dName[j]);
 pName[j++]='.';
 i=10;
 while(dName[i--]==' ');
 k=j+i-6;
 i=0;
 for(;j<k;j++) pName[j]=dName[8+(i++)];
 pName[j]=0; 
}

/***********************************************************************
 - 功能描述:将字符串中的小写字符都转为大写字符
 - 隶属模块:FAT文件系统模块
 - 函数属性:内部
 - 参数说明:str:指向待转换的字符串
 - 返回说明:无
 - 注:短文件名的情况下,文件名中的字符其实都是大写字符,为了方便,将文件
       名都转为大写
 ***********************************************************************/

void Str2Up(char *str)
{
 unsigned char len=strlen(str),i;
 for(i=0;i<len;i++)
 {
  str[i]=L2U(str[i]); 
 } 
}

/**************************************************************************
 - 功能描述:进入一个目录
 - 隶属模块:FAT文件系统模块
 - 函数属性:外部,使用户使用
 - 参数说明:path:目录的路径 形如:"\\dir1\\dir2\\" ,最后一定是以\\结束 
 - 返回说明:返回目录的开始簇号,如果进入目录失败,比如目录不存在,则返回0
 - 注:此函数由后面的FAT32_Open_File等函数调用,用来实现打开任意目录下的文件
       不建议用户调用
 **************************************************************************/

UINT32 FAT32_Enter_Dir(INT8 *path)
{
 UINT32 Cur_Clust,sec_temp,iSec,iDir,Old_Clust;
 UINT8 i=1,counter=0,flag=0;
 struct direntry *pDir;
 INT8 name[20];

 Cur_Clust=pArg->FirstDirClust;
 if(path[1]==0 && path[0]=='\\') return Cur_Clust;
 else
 {
  while(path[i]!=0)
  {
   if(path[i]=='\\')
   {
    for(;counter<8;counter++)
	{
	 name[counter]=' ';
	}
	name[counter]=0;
	counter=0;
	
	do
	{
	 sec_temp=(SOC(Cur_Clust));
	 for(iSec=sec_temp;iSec<sec_temp+pArg->SectorsPerClust;iSec++)
	 {
	  FAT32_ReadSector(iSec,FAT32_Buffer);
	  for(iDir=0;iDir<pArg->BytesPerSector;iDir+=sizeof(struct direntry))
      {
       pDir=((struct direntry *)(FAT32_Buffer+iDir));
	   if(Compare_Dir_Name(pDir->deName,name))
	   {
	    flag=1;
		Cur_Clust=LE2BE(pDir->deLowCluster,2)+LE2BE(pDir->deHighClust,2)*65536;
		iDir=pArg->BytesPerSector;
		iSec=sec_temp+pArg->SectorsPerClust;
	   } 
	  }
	 }
	 Old_Clust=Cur_Clust;
	}while(!flag && (Cur_Clust=FAT32_GetNextCluster(Cur_Clust))!=0x0fffffff);
	if(!flag) 
	{
	 temp_dir_cluster=Old_Clust;
	 strcpy(temp_dir_name,name);
	 flag=0;
	 return 0;
	}
	flag=0; 
   }
   else
   {
    name[counter++]=(L2U(path[i]));
   }
   i++;
  }
 }
 name[counter]=0; 
 flag=1;
 temp_dir_cluster=Cur_Clust;
 strcpy(temp_dir_name,name);
 return Cur_Clust;
}

/**************************************************************************
 - 功能描述:打开一个文件(支持文件名通配,如 A*.txt 或 *.*)
 - 隶属模块:FAT文件系统模块
 - 函数属性:外部,使用户使用
 - 参数说明:pfi: FileInfoStruct类型的结构体指针,用来装载文件的参数信息
              比如文件的大小、文件的名称、文件的开始簇等等,以备后面使用
             filepath: 文件的路径,支持任意层目录 比如
              "\\dir1\\dir2\\dir3\\....\\test.txt"
			 item:在文件名中有通配符*或?的情况下,实现与之匹配的文件并非
			 一个,item就是打开的文件的项数,比如符合通配条件的文件有6个,
			 如果item=3,那么此函数就会打开这6个文件中按顺序排号为3的那个
			 文件(item编号从0开始)
 - 返回说明:0:成功 1:文件不存在 2:目录不存在
 - 注:打开文件不成功有很多原因,比如文件不存在、文件的某一级目录不存在
       通配情况下满足条件的文件项数小于item的值等等
	   通常情况下,文件名中没有通配符,item的值我们取0就可以了
 **************************************************************************/

UINT8 FAT32_Open_File(struct FileInfoStruct *pfi,INT8 *filepath,unsigned long item)
{
 UINT32 Cur_Clust,sec_temp,iSec,iFile,iItem=0;
 UINT8 flag=0,index=0,i=0;
 struct direntry *pFile;
 INT8 temp_file_name[13];
 while(filepath[i]!=0)
 {
  if(filepath[i]=='\\') index=i;
  i++;
 }

 if(Cur_Clust=FAT32_Enter_Dir(filepath))
 {
  Str2Up(temp_dir_name);
 do
 { 
  sec_temp=SOC(Cur_Clust);
  for(iSec=sec_temp;iSec<sec_temp+pArg->SectorsPerClust;iSec++)
  {	
   FAT32_ReadSector(iSec,FAT32_Buffer);
   for(iFile=0;iFile<pArg->BytesPerSector;iFile+=sizeof(struct direntry))
   {
    pFile=((struct direntry *)(FAT32_Buffer+iFile));
	FAT32_toFileName(pFile->deName,temp_file_name);
	if(FilenameMatch(temp_dir_name,temp_file_name) && pFile->deName[0]!=0xe5 && pFile->deAttributes&0x20) //匹配文件名
	{
	 if(item==iItem)
	 {	 
	 flag=1;
     Cur_Clust=LE2BE(pFile->deLowCluster,2)+LE2BE(pFile->deHighClust,2)*65536;

     pfi->FileSize=LE2BE(pFile->deFileSize,4);
	 strcpy(pfi->FileName,temp_file_name);
	 pfi->FileStartCluster=LE2BE(pFile->deLowCluster,2)+LE2BE(pFile->deHighClust,2)*65536;
	 pfi->FileCurCluster=pfi->FileStartCluster;
	 pfi->FileCurSector=SOC(pfi->FileStartCluster);
	 pfi->FileCurPos=0;
	 pfi->FileCurOffset=0;
	 pfi->Rec_Sec=iSec;
	 pfi->nRec=iFile;

	 pfi->FileAttr=pFile->deAttributes;
	 sec_temp=LE2BE(pFile->deCTime,2);
	 (pfi->FileCreateTime).sec=(sec_temp&0x001f)*2;
	 (pfi->FileCreateTime).min=((sec_temp>>5)&0x003f);
	 (pfi->FileCreateTime).hour=((sec_temp>>11)&0x001f);
	 sec_temp=LE2BE(pFile->deCDate,2);
	 (pfi->FileCreateDate).day=((sec_temp)&0x001f);
	 (pfi->FileCreateDate).month=((sec_temp>>5)&0x000f);
	 (pfi->FileCreateDate).year=((sec_temp>>9)&0x007f)+1980;

	 sec_temp=LE2BE(pFile->deMTime,2);
	 (pfi->FileMTime).sec=(sec_temp&0x001f)*2;
	 (pfi->FileMTime).min=((sec_temp>>5)&0x003f);
	 (pfi->FileMTime).hour=((sec_temp>>11)&0x001f);
	 sec_temp=LE2BE(pFile->deMDate,2);
	 (pfi->FileMDate).day=((sec_temp)&0x001f);
	 (pfi->FileMDate).month=((sec_temp>>5)&0x000f);
	 (pfi->FileMDate).year=((sec_temp>>9)&0x007f)+1980;

	 sec_temp=LE2BE(pFile->deADate,2);
	 (pfi->FileADate).day=((sec_temp)&0x001f);
	 (pfi->FileADate).month=((sec_temp>>5)&0x000f);
	 (pfi->FileADate).year=((sec_temp>>9)&0x007f)+1980;
	    
	 iFile=pArg->BytesPerSector;
	 iSec=sec_temp+pArg->SectorsPerClust;
	 }
	 else
	 {
	  iItem++;
	 }
	} 
   }
  }
 }while(!flag && (Cur_Clust=FAT32_GetNextCluster(Cur_Clust))!=0x0fffffff);
 if(!flag) 
 {
  return 1;
 }
 return 0;
 }
 else
 {
  return 2; 
 }
}

/**************************************************************************
 - 功能描述:文件定位
 - 隶属模块:FAT文件系统模块
 - 函数属性:外部,使用户使用
 - 参数说明:pfi:FileInfoStruct类型的结构体指针,用于装载文件参数信息,文件
             定位后,pfi所指向的结构体中的相关参数就被更新了,比如文件的当前
             扇区,文件当前扇区中的位置,文件的当前偏移量等等,以备后面使用
             offset:要定位的偏移量,如果offset大于文件的大小,则定位到文件的
             末尾
 - 返回说明:文件定位成功返回0,否则为1
 - 注:此函数被下面的FAT32_Read_File调用,用于实现从指定位置读取数据,不建议
       用户直接调用些函数
 **************************************************************************/

UINT8 FAT32_Seek_File(struct FileInfoStruct *pfi,UINT32 offset)
{
 UINT32 i,temp;

if(offset<=pfi->FileSize)
{ 
 if(offset==pfi->FileCurOffset)
 {
  pfi->FileCurPos%=pArg->BytesPerSector;
  return 1;  
 }
 if(offset<pfi->FileCurOffset) 
 {
  pfi->FileCurCluster=pfi->FileStartCluster;
  pfi->FileCurSector=SOC(pfi->FileCurCluster);
  pfi->FileCurPos=0;
  pfi->FileCurOffset=0;
 } 
 if((offset-pfi->FileCurOffset)>=(pArg->BytesPerSector-pfi->FileCurPos))	 //目标偏移量与文件当前偏移量所差的字节数不小于文件在当前扇区中的位置到扇区末尾的字节数
 {
  pfi->FileCurOffset+=(pArg->BytesPerSector-pfi->FileCurPos);
  pfi->FileCurPos=0;
  if(pfi->FileCurSector-SOC(pfi->FileCurCluster)==(pArg->SectorsPerClust-1))
  {
   pfi->FileCurCluster=FAT32_GetNextCluster(pfi->FileCurCluster);
   pfi->FileCurSector=SOC(pfi->FileCurCluster);
  }
  else
  {
   pfi->FileCurSector++; 
  }
 }
 else
 {
  pfi->FileCurPos=(pfi->FileCurPos+offset-pfi->FileCurOffset)%pArg->BytesPerSector;
  pfi->FileCurOffset=offset;
  return 1;
 }
 temp=SOC(pfi->FileCurCluster);
 if((offset-(pfi->FileCurOffset))/pArg->BytesPerSector+(pfi->FileCurSector-temp)>(pArg->SectorsPerClust-1))
 {
  pfi->FileCurOffset+=(((pArg->SectorsPerClust)-(pfi->FileCurSector-(SOC(pfi->FileCurCluster))))*pArg->BytesPerSector);
  pfi->FileCurCluster=FAT32_GetNextCluster(pfi->FileCurCluster);
  pfi->FileCurSector=SOC(pfi->FileCurCluster);
  pfi->FileCurPos=0;
 }
 else
 {
  pfi->FileCurSector+=(offset-pfi->FileCurOffset)/pArg->BytesPerSector;
  pfi->FileCurPos=(offset-pfi->FileCurOffset)%pArg->BytesPerSector;
  pfi->FileCurOffset=offset;
  return 1;
 }

 temp=(offset-pfi->FileCurOffset)/(pArg->BytesPerSector*pArg->SectorsPerClust);
 for(i=0;i<temp;i++)
 {
  pfi->FileCurCluster=FAT32_GetNextCluster(pfi->FileCurCluster);
 }
 pfi->FileCurOffset+=(temp*(pArg->BytesPerSector*pArg->SectorsPerClust));
 pfi->FileCurSector=(SOC(pfi->FileCurCluster))+(offset-pfi->FileCurOffset)/pArg->BytesPerSector;
 pfi->FileCurPos=((offset-pfi->FileCurOffset))%pArg->BytesPerSector;
 pfi->FileCurOffset=offset;
}
else
{
 return 1;
}
 return 0;
}

/**************************************************************************
 - 功能描述:从文件的某一个位置处,读取一定长度的数据,放入数据缓冲区中
 - 隶属模块:FAT文件系统模块
 - 函数属性:外部,使用户使用
 - 参数说明:pfi:FileInfoStruct类型的结构体指针,用于装载文件参数信息,文件
             读取的过程中,此结构体中的相关参数会更新,比如文件的当前偏移量、
             文件的当前扇区,文件的当前簇等等
             offset:要定位的偏移量,要小于文件的大小 
             len:要读取的数据的长度,如果len+offset大于文件的大小,则实际读
             取的数据量是从offset开始到文件结束
             pbuf:数据缓冲区
 - 返回说明:读取到的实际的数据长度,如果读取失败,比如指定的偏移量大于了文件
             大小,则返回0
 - 注:在读取一个文件的数据前,必须先将该文件用FAT32_Open_File打开
 **************************************************************************/

UINT32 FAT32_Read_File(struct FileInfoStruct *pfi,UINT32 offset,UINT32 len,UINT8 *pbuf)
{
 UINT32 i,j,k,temp;
 UINT32 counter=0;
 if(offset<pfi->FileSize)
 {
  if(offset+len>pfi->FileSize) len=pfi->FileSize-offset;
  FAT32_Seek_File(pfi,offset);
  
  FAT32_ReadSector(pfi->FileCurSector,FAT32_Buffer);
  for(i=pfi->FileCurPos;i<pArg->BytesPerSector;i++)
  {
   if(counter>=len) 
   {
     return len;
   }
   pbuf[counter]=FAT32_Buffer[i];
   counter++;
   pfi->FileCurPos++;
   pfi->FileCurOffset++;
  }
  if(pfi->FileCurSector-(SOC(pfi->FileCurCluster))!=(pArg->SectorsPerClust-1))
  {
   for(j=pfi->FileCurSector+1;j<(SOC(pfi->FileCurCluster))+pArg->SectorsPerClust;j++)
   {
    FAT32_ReadSector(j,FAT32_Buffer);
    pfi->FileCurSector=j;
    for(i=0;i<pArg->BytesPerSector;i++)
    {
     if(counter>=len)
     {
       return len;
     }
     pbuf[counter]=FAT32_Buffer[i];
     counter++;
     pfi->FileCurPos++;
     pfi->FileCurOffset++;
    }
   }
  } 
  temp=(len-counter)/(pArg->BytesPerSector*pArg->SectorsPerClust);
  for(k=0;k<temp;k++)
  {
   pfi->FileCurCluster=FAT32_GetNextCluster(pfi->FileCurCluster);
   for(j=(SOC(pfi->FileCurCluster));j<(SOC(pfi->FileCurCluster))+pArg->SectorsPerClust;j++)
   {
    FAT32_ReadSector(j,FAT32_Buffer);
    pfi->FileCurSector=j;
    for(i=0;i<pArg->BytesPerSector;i++)
    {
     if(counter>=len)  
 	 {
       return len;
     }
     pbuf[counter]=FAT32_Buffer[i];
     counter++;
     pfi->FileCurOffset++;
	 pfi->FileCurPos++;
	 pfi->FileCurPos%=pArg->BytesPerSector;
    } 
   }    
  }
  pfi->FileCurCluster=FAT32_GetNextCluster(pfi->FileCurCluster);
  temp=(SOC(pfi->FileCurCluster))+((len-counter)/pArg->BytesPerSector);
  pfi->FileCurSector=(SOC(pfi->FileCurCluster));
  for(j=(SOC(pfi->FileCurCluster));j<temp;j++)
  {
   FAT32_ReadSector(j,FAT32_Buffer);
   pfi->FileCurSector=j;
   for(i=0;i<pArg->BytesPerSector;i++)
   {
    if(counter>=len) 
    {
      return len;
    }
    pbuf[counter]=FAT32_Buffer[i];
    counter++;
    pfi->FileCurPos++;
    pfi->FileCurPos%=pArg->BytesPerSector;
    pfi->FileCurOffset++;
   }   
  }
  pfi->FileCurSector=j;
  FAT32_ReadSector(pfi->FileCurSector,FAT32_Buffer);
  temp=len-counter;
  for(i=0;i<temp;i++)
  {
   if(counter>=len) 
   {
     return len;
   }
   pbuf[counter]=FAT32_Buffer[i];
   counter++;
   pfi->FileCurPos++;
   pfi->FileCurPos%=pArg->BytesPerSector;

⌨️ 快捷键说明

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