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

📄 fat.c

📁 基于LPC2136的TFT真彩 液晶程序
💻 C
字号:
#include "fat.h"

INT8U  fname[20][8];
INT8U  fext[20][3];
INT32U fclust[20];
INT8U  fcount;
INT32U fsize[20];





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


////////////////////////////////////////////////////////////////////////////////
//磁盘分区信息
////////////////////////////////////////////////////////////////////////////////
INT8U	Partition_Active;				// 0x80代表该分区为缺省分区
INT8U	Partition_StartHead;			// 该分区入口的磁头地址
INT16U	Partition_StartCylSect;			// 该分区入口的扇区地址和柱面地址
INT8U	Partition_PartType;				// 该分区类型
INT8U	Partition_EndHead;				// 该分区结束的扇区地址
INT16U	Partition_EndCylSect;			// 该分区结束的柱面地址
INT32U	Partition_StartLBA;				// 该分区内第一个扇区地址
INT32U	Partition_Size;					// 该分区所包含的扇区总数



////////////////////////////////////////////////////////////////////////////////
//fat32 BPB结构,包括扩展BPB
////////////////////////////////////////////////////////////////////////////////
INT8U	BS_jmpBoot[3];					//jmp code
INT8U	BS_OEMName[8];					//oem and os like dos5.0

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

INT8U	BS_drvNum;					    //物理驱动器号
INT8U	BS_Reservd1;					//保留
INT8U	BS_BootSig;						//扩展引导标签
INT32U	BS_VolID;						//分区序号
INT8U	BS_VolLab[11];					//卷标
INT8U	BS_FilSysType[8];				//系统ID



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


////////////////////////////////////////////////////////////////////////////////
//文件信息
////////////////////////////////////////////////////////////////////////////////
INT8U	DIR_Name[11];					//文件名,没有.
INT8U	DIR_Attr;         				//文件属性,自低至高,只读、隐藏、系统、卷标、子目录、归档
INT8U	DIR_NTRes;        				//系统保留
INT8U	DIR_CrtTimeTenth;  				//创建时间的10毫秒位
INT16U	DIR_CrtTime;      				//创建时间
INT16U	DIR_CrtDate;      				//创建日期
INT16U	DIR_LastAccDate;  				//最后访问日期
INT16U	DIR_FstClusHI;    				//文件起始簇号高16位               
INT16U	DIR_WrtTime;      				//最近修改时间
INT16U	DIR_WrtDate;      				//最近修改日期
INT16U	DIR_FstClusLO;    				//文件起始簇号的低16位               
INT32U	DIR_FileSize;     				//文件长度



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

INT8U   BUFFER[512]; 

INT8U MP3_BUFFER[512];
INT8U  TEXT[512];

INT8U filetype[][3] ={ {"MP3"},{"WMA"},{"MID"},{"LRC"}};



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


INT8U Fat_Init(void)
{   
	
	uint32 j;
	SD_ReadBlock(0,BUFFER);		
	
	for(j=0;j<512;j++)
	{
		TEXT[j]=BUFFER[j];
	}													
		//read partion message															
			// 读MBR结构//struct bpb710 *bpb;
	Partition_PartType=0X55;																				
			// 读取分区表信息// 读引导扇区// 引导扇区号在PartInfo.prStartLBA中
    Partition_PartType= BUFFER[450];													
		//分区信息 FAT32 0x0B				
	Partition_Size	= BUFFER[458]+(BUFFER[459]<<8)+(BUFFER[460]<<16)+(BUFFER[461]<<24);
    Partition_StartLBA = BUFFER[454]+(BUFFER[455]<<8)+(BUFFER[456]<<16)+(BUFFER[457]<<24);	
	//0xF9*512=127488		
		
	
	SD_ReadBlock(Partition_StartLBA,BUFFER);     				//FAT32 read BPB

	BS_OEMName[0]   = BUFFER[3];
	BS_OEMName[1]   = BUFFER[4];
	BS_OEMName[2]   = BUFFER[5];
	BS_OEMName[3]   = BUFFER[6];
	BS_OEMName[4]   = BUFFER[7];
	BS_OEMName[5]   = BUFFER[8];
	BS_OEMName[6]   = BUFFER[9];
	BS_OEMName[7]   = BUFFER[10];
	BPB_BytesPerSec	= BUFFER[11] |(BUFFER[12] << 8);			//0x0200			//每个扇区字节数
	BPB_SecPerClus	= BUFFER[13];								//0x08      		//每个簇的扇区数
	BPB_RsvdSecCnt  = BUFFER[14] |(BUFFER[15] << 8);			//0x20 				//保留扇区数
	BPB_NumFATs     = BUFFER[16];								//0x02 				//FAT 表数目
	BPB_RootEntCnt	= BUFFER[17] | (BUFFER[18] << 8);
	BPB_TotSec16    = BUFFER[19] | (BUFFER[20] << 8);
	BPB_Media		= BUFFER[21];
	BPB_FATSz16		= BUFFER[22] | (BUFFER[23] << 8); 
    BPB_SecPerTrk	= BUFFER[24] | (BUFFER[25] << 8);
    BPB_NumHeads	= BUFFER[26] | (BUFFER[27] << 8); 
    BPB_HiddSec 	= BUFFER[28] | (BUFFER[29] << 8) | (BUFFER[30] << 16) | (BUFFER[31] << 24);  
    BPB_TotSec32	= BUFFER[32] | (BUFFER[33] << 8) | (BUFFER[34] << 16) | (BUFFER[35] << 24);  
	BPB_FATSz32 	= BUFFER[36] | (BUFFER[37] << 8) | (BUFFER[38] << 16) | (BUFFER[39] << 24);
    BPB_ExtFlags	= BUFFER[40] | (BUFFER[41] << 8);  
    BPB_FSVer	    = BUFFER[42] | (BUFFER[43] << 8);
    BPB_RootClus	= BUFFER[44] | (BUFFER[45] << 8) | (BUFFER[46] << 16) | (BUFFER[47] << 24);
    BPB_FSInfo 	    = BUFFER[48] | (BUFFER[49] << 8); 
    BPB_BKBootSec   = BUFFER[50] | (BUFFER[51] << 8); 						
	//BPB_Reserved    = BUFFER[52]; 

	BS_drvNum		= BUFFER[64];
	BS_Reservd1		= BUFFER[65];
	BS_BootSig		= BUFFER[66];
	BS_VolID		= BUFFER[67] | (BUFFER[68] << 8) | (BUFFER[69] << 16) | (BUFFER[70] << 24);
	//BS_VolLab[0]	= BUFFER[71];
	//BS_FilSysType[0] = BUFFER[82];
 
			FAT_MASK		= FAT32_MASK;	//0x0fffffff
			Clust 			= BPB_RootClus;
            FAT1Sec			= BPB_RsvdSecCnt+Partition_StartLBA;
			FAT2Sec			= FAT1Sec+BPB_FATSz32;
			FirstDataSector	= FAT2Sec+BPB_FATSz32;

  
       	return 1;	
}


INT8U IsMusicFile(INT8U *strName)
{
    INT8U i;
	
    for(i=0; i<3; i++)
    {
        if(filetype[MP3_TYPE][i]!= strName[i]) break;
    }
    if(i == 3)    return 1;   // 是MP3文件
	    
    for(i=0; i<3; i++)
    {
        if(filetype[WMA_TYPE][i]!= strName[i]) break;
    }
    if(i == 3)    return 2;   // 是WMA文件
/*
    for(i=0;i<3;i++)
    {
        if(filetype[MID_TYPE][i]!=strName[i]) break;
    }
    if(i == 3)    return 3;   // 是MIDI文件
*/
	return 0; 
}		


void GetFileClust(void)
{
   INT8U	i;
    INT32U	tem;	    
	do{
    	SD_ReadBlock(FirstDataSector+Index/(BPB_BytesPerSec/32),BUFFER);	// 重新读取目录表
    	

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

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


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

   	SD_ReadBlock(Sector,BUFFER);

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

	return tmp;
}



INT32U fatNextCluster(INT32U cluster)
{
    INT32U nextCluster=0;
    INT32U fatOffset=0;
    INT32U sector=0;
    INT16U offset=0;

   // if(Partition_PartType == PART_TYPE_FAT32)	        			// 一个表项为 4bytes(32 bits)
    //{
        fatOffset = cluster << 2;
        sector = FAT1Sec + (fatOffset>>9);				// 计算FAT扇区号
        offset = fatOffset % BPB_BytesPerSec;            					// 计算FAT扇区号中表项的偏移地址
        nextCluster = ReadBlockforCluster(sector,offset); 			// 读取下一个簇号	
   // }
    /*
    else if(Partition_PartType == PART_TYPE_FAT16)       				// 一个表项为 2bytes(16 bits)
    {    
        fatOffset = cluster << 1; 	                        // 计算FAT扇区号
        //sector = FirstFATSector + (fatOffset / BPB_BytesPerSec);
        offset = fatOffset % BPB_BytesPerSec;     			// 计算FAT扇区号中表项的偏移地址
		nextCluster = ReadBlockforCluster(sector,offset);
    } 
   */
    if (nextCluster >= (CLUST_EOFS & FAT_MASK))				// 是否文件的结束簇
    {
        nextCluster = CLUST_EOFE;
    }
    return nextCluster;
}  


void GetMusicFile(void)
  {
    uint8 i;
     fcount=0;
    while(1)
    {
      GetFileClust();	
      
      if(Index==0) break;
      
      for(i=0;i<8;i++)
       {
        fname[fcount][i]=deName[i];
        }
        
      for(i=0;i<3;i++)
        {
         if(deExtension[i]>=65)  fext[fcount][i]=deExtension[i]+0x20;
         
         else fext[fcount][i]=deExtension[i];
         }
         
      fclust[fcount]=Clust;
      
      fsize[fcount]=FileSize;
      
      fcount++;
      
      }
    }

⌨️ 快捷键说明

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