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

📄 fat.c

📁 M16-Mp3.rar
💻 C
字号:

//---------------------------- 文件系统程序 -----------------------------
//
//文件系统:简易FAT32
//代码作者:廖华明(师兄)
//时间:2009.7.8
//
//------------------------------------------------------------------------

#include"fat.h"

uint32 SearchFile_Clust;
uint32 Music_Dir;

uint32 fclust[20];
uint8  fcount;
uint32 fsize[20];

uint32  NextCluster;   		 	//指向当前正在读取文件的簇号
uint32  SectorIndex=0;   		//正在读扇区

uint32	Partition_StartLBA;				// 该分区内第一个扇区地址

uint16	BPB_BytesPerSec; 				//扇区字节数
uint8	BPB_SecPerClus;					//每簇扇区数
uint16	BPB_RsvdSecCnt; 				//保留扇区数
uint8	BPB_NumFATs;					//FAT数目
uint16	BPB_RootEntCnt; 				//根目录项数 0
uint16	BPB_TotSec16; 					//小扇区总数 0
uint8	BPB_Media;						//媒体描述符
uint16	BPB_FATSz16; 					//每FAT扇区数fat32不用为0
uint16	BPB_SecPerTrk; 					//每道扇区数
uint16	BPB_NumHeads; 					//磁头数
uint32	BPB_HiddSec; 					//隐藏扇区数
uint32	BPB_TotSec32; 					//总扇区数   
uint32	BPB_FATSz32;					//每FAT扇区数fat32
uint16	BPB_ExtFlags;					//fat32扩展标志
uint16  BPB_FSVer;						//fat32特有,高位为fat32的主版本号,底位为次版本号
uint32	BPB_RootClus;					//根目录簇号
uint16	BPB_FSInfo;						//文件系统信息扇区号
uint16	BPB_BKBootSec;					//引导扇区备份号

uint8  	deName[8];
uint8  	deExtension[3];
uint32  Clust; 							//当前目录的簇号
uint16 	Nums;   						//仅FAT12—FAT16中的根目录区有效
uint32 	Index;  						//当前的BLOCK中目录项索引
uint32 	FileSize; 						//文件长度

uint32  FAT1Sec;						//FAT1表的位置
uint32  FAT2Sec;
uint32  FirstDataSector;				//第一个根目录位置,区号为2
uint32  FirstDirSector;

uint8   Fat_Buffer[512]; 


uint32  FAT_MASK;
uint16  RootDirEnts;         // 根目录总的项数(FAT12&FAT16)


uint8 Fat_Init(void)
{   
	
	uint32 temp;
	
	SD_ReadBlock(0,Fat_Buffer);		

    Partition_StartLBA = (Fat_Buffer[454]|(Fat_Buffer[455]<<8)|((uint32)Fat_Buffer[456]<<16)|((uint32)Fat_Buffer[457]<<24));		
		
	SD_ReadBlock(Partition_StartLBA,Fat_Buffer);     				//FAT32 read BPB

	BPB_BytesPerSec	= Fat_Buffer[11] |(Fat_Buffer[12] << 8);			//0x0200			//每个扇区字节数
	BPB_SecPerClus	= Fat_Buffer[13];								//0x08      		//每个簇的扇区数
	BPB_RsvdSecCnt  = Fat_Buffer[14] |(Fat_Buffer[15] << 8);			//0x20 				//保留扇区数
	BPB_NumFATs     = Fat_Buffer[16];								//0x02 				//FAT 表数目
	BPB_RootEntCnt	= Fat_Buffer[17] | (Fat_Buffer[18] << 8);
	BPB_TotSec16    = Fat_Buffer[19] | (Fat_Buffer[20] << 8);
	BPB_Media		= Fat_Buffer[21];
	BPB_FATSz16		= Fat_Buffer[22] | (Fat_Buffer[23] << 8); 
    BPB_SecPerTrk	= Fat_Buffer[24] | (Fat_Buffer[25] << 8);
    BPB_NumHeads	= Fat_Buffer[26] | (Fat_Buffer[27] << 8); 
    BPB_HiddSec 	= Fat_Buffer[28] | (Fat_Buffer[29] << 8) | ((uint32)Fat_Buffer[30] << 16) | ((uint32)Fat_Buffer[31] << 24);  
    BPB_TotSec32	= Fat_Buffer[32] | (Fat_Buffer[33] << 8) | ((uint32)Fat_Buffer[34] << 16) | ((uint32)Fat_Buffer[35] << 24);  
	BPB_FATSz32 	= Fat_Buffer[36] | (Fat_Buffer[37] << 8) | ((uint32)Fat_Buffer[38] << 16) | ((uint32)Fat_Buffer[39] << 24);
    BPB_ExtFlags	= Fat_Buffer[40] | (Fat_Buffer[41] << 8);  
    BPB_FSVer	    = Fat_Buffer[42] | (Fat_Buffer[43] << 8);
    BPB_RootClus	= Fat_Buffer[44] | (Fat_Buffer[45] << 8) | ((uint32)Fat_Buffer[46] << 16) | ((uint32)Fat_Buffer[47] << 24);
    BPB_FSInfo 	    = Fat_Buffer[48] | (Fat_Buffer[49] << 8); 
    BPB_BKBootSec   = Fat_Buffer[50] | (Fat_Buffer[51] << 8); 						
 
	FAT_MASK		= FAT32_MASK;	//0x0fffffff
	Clust 			= BPB_RootClus;
    FAT1Sec			= BPB_RsvdSecCnt+Partition_StartLBA;
	FAT2Sec			= FAT1Sec+BPB_FATSz32;
	FirstDataSector	= FAT2Sec+BPB_FATSz32;
  	return 1;	
}




uint8 FileExt_Compare(uint8 *strExt1,uint8 *strExt2)
{
    uint8 i;
	
    for(i=0; i<3; i++)
    {
        if(strExt1[i]!= strExt2[i]) break;
    }
    if(i == 3)    return 1; 
	    
	return 0; 
}	
	

uint8 FileName_Compare(uint8 *strName1,uint8 *strName2)
{
    uint8 i;
	
    for(i=0; i<4; i++)
    {
        if(strName1[i]!= strName2[i]) break;
    }
    if(i == 4)    return 1; 
	    
	return 0; 
}	


void SearchFileOfName(uint32 TargetStartSector,uint8 *File_Name)
{
    uint8	i;
    uint32	tem;	
	uint32  Index_tmp=0;
	    
	do{
    	SD_ReadBlock(TargetStartSector + Index_tmp/(BPB_BytesPerSec/32),Fat_Buffer);	// 重新读取目录表
		
    	tem=((Index_tmp)*32)%BPB_BytesPerSec;
    
    	if((Fat_Buffer[tem+11] & ATTR_LONG_FILENAME) != ATTR_LONG_FILENAME);	// 是否是长文件名
    	{
    		if((Fat_Buffer[tem] != 0xe5) && (Fat_Buffer[tem] != 0x05))			   //文件没有删除   
         	{
    			  for(i=0;i<8;i++)
    			  {
					 deName[i]=Fat_Buffer[tem+i];
				  }
		
				  if(FileName_Compare(File_Name,deName))
				  {
					  SearchFile_Clust = ((uint32)Fat_Buffer[tem+20]<<16) | ((uint32)Fat_Buffer[tem+21]<<24) | (Fat_Buffer[tem+26]) | (Fat_Buffer[tem+27]<<8);
					  Index_tmp++;
					  break;
				  }
			}
		}

		Index_tmp++;
		
		if(Fat_Buffer[tem] == 0)  								// 等所有文件都已经查询完了   
		{
    		Index_tmp=0;
    		break;
    	} 	
	}
	while(1);
} 


void SearchFileOfExt(uint32 TargetStartSector,uint8*Ext)
{
    uint8	i;
    uint32	tem;	    
	do{
    	SD_ReadBlock(TargetStartSector + Index/(BPB_BytesPerSec/32),Fat_Buffer);	// 重新读取目录表

    	tem=((Index)*0x20)%BPB_BytesPerSec;
    
    	if((Fat_Buffer[tem+11] & ATTR_LONG_FILENAME) != ATTR_LONG_FILENAME);	// 是否是长文件名
    	{
    		if((Fat_Buffer[tem] != 0xe5) && (Fat_Buffer[tem] != 0x05))			   //文件没有删除   
         	{
            	if((Fat_Buffer[tem+11]&ATTR_DIRECTORY) != ATTR_DIRECTORY)    // is it a directory ?
                {	
    			    for(i=0;i<8;i++)
    				{
						deName[i]=Fat_Buffer[tem+i];
					}
		    		for(i=0;i<3;i++)
    				{
		    			deExtension[i]=Fat_Buffer[tem+8+i];
		    		}
		
					if(FileExt_Compare(deExtension,Ext))
					{
						Clust=((uint32)Fat_Buffer[tem+20]<<16) | ((uint32)Fat_Buffer[tem+21]<<24) | (Fat_Buffer[tem+26]) | (Fat_Buffer[tem+27]<<8);
						FileSize=(Fat_Buffer[tem+28]) | (Fat_Buffer[tem+29]<<8)|((uint32)Fat_Buffer[tem+30]<<16)|((uint32)Fat_Buffer[tem+31]<<24);
						Index++;
						break;
					}
				}
			}
		}

		Index++;
		
		if(Fat_Buffer[tem] == 0)  								// 等所有文件都已经查询完了   
		{
    		Index=0;
    		break;
    	} 	
	}
	while(1);
}  


uint32 ReadBlockforCluster(uint32 Sector,uint32 offset)
{
	uint32  tmp;

   	SD_ReadBlock(Sector,Fat_Buffer);

	tmp=Fat_Buffer[offset] |(Fat_Buffer[offset+1]<<8) |((uint32)Fat_Buffer[offset+2]<<16) |((uint32)Fat_Buffer[offset+3]<<24);

	return tmp;
}



uint32 FatNextCluster(uint32 cluster)
{
    uint32 nextCluster=0;
    uint32 fatOffset=0;
    uint32 sector=0;
    uint16 offset=0;

    fatOffset = cluster << 2;
    sector = FAT1Sec + (fatOffset>>9);				// 计算FAT扇区号
    offset = fatOffset % BPB_BytesPerSec;            					// 计算FAT扇区号中表项的偏移地址
    nextCluster = ReadBlockforCluster(sector,offset); 			// 读取下一个簇号	

    if (nextCluster >= (CLUST_EOFS & FAT_MASK))				// 是否文件的结束簇
    {
        nextCluster = CLUST_EOFE;
    }
    return nextCluster;
}  


void GetMusicFile(void)
  {
    fcount=0;
	SearchFileOfName(FirstDataSector,"音乐");
	Music_Dir=FirstDataSector+(SearchFile_Clust - 2)*8;
    while(1)
    {
      SearchFileOfExt(Music_Dir,"MP3");
      if(Index==0) break;
      fclust[fcount]=Clust;
	  fsize[fcount]=FileSize;
      fcount++;
    }
  }

⌨️ 快捷键说明

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