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

📄 fat.c

📁 用atmega64+vs1003(音频解码芯片)+SD制成的板子
💻 C
📖 第 1 页 / 共 2 页
字号:
/************************************************************/
/*		         	FAT 			 					    */
/*				  											*/
/************************************************************/
#include <avr/io.h>
#include <string.h>
#include <avr/eeprom.h>
#include "sd.h"
#include "fat.h"
#include "lcd.h"
extern uchar BUFFER[512];
extern uchar WorkFlag;
unsigned char FatType;  //0:FAT12  1:FAT16   2:FAT32
unsigned long FAT_MASK;
unsigned int  RootDirEnts;       //根目录总的项数(FAT12&FAT16)
unsigned long FirstDataSector;   //数据区
unsigned int  BytesPerSector;
unsigned int  SectorsPerCluster;
unsigned long FirstFATSector;
ROOTDIR_INF   RootDir;  //目录区FIND_FILE_INFO	FindInfo;
//********************************************************************************************
//读一个扇区
void ReadBlock(unsigned long LBA)
//********************************************************************************************
{   unsigned long temp;
    temp=LBA<<9;
    SD_Read_Block(temp);
}  
void ReadBlockToBuff(unsigned long LBA,unsigned char *pbuff)
{
		unsigned long temp;
    temp=LBA<<9;
    SD_Read_Block2(temp,pbuff);
}
unsigned long  fatGetRootSector(void)
{
	if(FatType == FAT32)
		return ((RootDir.Clust-2)* SectorsPerCluster) +FirstDataSector;
	 return  RootDir.Sector;
}
unsigned long fatGetRootClust(void)
{
	  if(FatType==FAT32)  return RootDir.Clust;
	  	                  return 0x00000000;
	
}

/*-----------------------------------------------------------------------
 查询数据区一个簇开始扇区号
-----------------------------------------------------------------------*/
unsigned long fatClustToSect(unsigned long clust)
{
	return ((clust-2) * SectorsPerCluster) + FirstDataSector;
}
/*-----------------------------------------------------------------------
 查询一个簇所占扇区数
-----------------------------------------------------------------------*/
unsigned int fatClusterSize(void)
{
	// return the number of sectors in a disk cluster
	return SectorsPerCluster;
}

//文件系统初始化
unsigned char fatInit()
{ 
	PARTRECORD PartInfo;
	BPB710 *bpb=0;
 	ReadBlock(0);      // 读取分区表信息  
	PartInfo = *((PARTRECORD *) ((PARTSECTOR *)BUFFER)->psPart);
	// 引导扇区号在PartInfo.prStartLBA中
 	ReadBlock(PartInfo.prStartLBA);  //ataReadSectors( DRIVE0, PartInfo.prStartLBA, 1, SectorBuffer );
	bpb = (BPB710 *) &((BOOTSECTOR710 *) BUFFER)->bsBPB;
	FirstDataSector	= PartInfo.prStartLBA;
	if(bpb->bpbFATsecs)
	{
		// bpbFATsecs非0,为FAT16,FAT表所占的扇区数在bpbFATsecs里
		FirstDataSector	+= bpb->bpbResSectors + bpb->bpbFATs * bpb->bpbFATsecs; 
	}
	else
	{
		// bpbFATsecs是0,为FAT32,FAT表所占的扇区数在bpbBigFATsecs里
		FirstDataSector	+= bpb->bpbResSectors + bpb->bpbFATs * bpb->bpbBigFATsecs;
	}
	SectorsPerCluster	= bpb->bpbSecPerClust;
	BytesPerSector		= bpb->bpbBytesPerSec;
	FirstFATSector		= bpb->bpbResSectors + PartInfo.prStartLBA;
	switch (PartInfo.prPartType)
	{
		case PART_TYPE_FAT12:   
		 	RootDir.Sector=    FirstDataSector;
		 	FirstDataSector += ((bpb->bpbRootDirEnts*32)/BytesPerSector);
		 	RootDirEnts = bpb->bpbRootDirEnts;
			FatType = FAT12;  
			FAT_MASK=FAT12_MASK;
			break;
		case PART_TYPE_DOSFAT16:
		case PART_TYPE_FAT16: 
		case PART_TYPE_FAT16LBA:
		 	RootDir.Sector =   FirstDataSector;
			FirstDataSector += (bpb->bpbRootDirEnts*32)/BytesPerSector;
			RootDirEnts = bpb->bpbRootDirEnts;
			FatType = FAT16; 
			FAT_MASK=FAT16_MASK;	
			break;
		case PART_TYPE_FAT32LBA:
		case PART_TYPE_FAT32:
			RootDir.Clust = bpb->bpbRootClust;
			FAT_MASK=FAT32_MASK;
			FatType = FAT32; 
			break;
		default:
			return 0;
	}  
	return 1;	
}

#define MP3_TYPE   0
#define WMA_TYPE   1
#define MID_TYPE   2
#define LRC_TYPE   3
unsigned char filetype[][3] PROGMEM ={ {"MP3"},{"WMA"},{"MID"},{"LRC"}};
unsigned char hzk12[][11] PROGMEM =
{{"HZK12      "},
 {"UNITOGB BIN"},
 {".          "},
 {"..         "}
};
unsigned char IsHzk12File(unsigned char *pbuf)
{ 
	unsigned char i;
	for(i=0;i<11;i++){
		if(pgm_read_byte(hzk12[0]+i)!=pbuf[i]) break;
	}
   if(i==11)    return 1;  //find ok    
   return 0;
}
unsigned char IsUnitogbFile(unsigned char *pbuf)
{ 
	unsigned char i;
	for(i=0;i<11;i++){
		if(pgm_read_byte(hzk12[1]+i)!=pbuf[i]) break;
	}
   if(i==11)    return 1;  //find ok    
   return 0;
}
unsigned char IsFatherDir(unsigned char *strName)
{
	unsigned char i;
	for(i=0;i<3;i++){
		if(pgm_read_byte(hzk12[3]+i)!=strName[i]) break;
	}
	if(i==3)    return 1;  //是上层目录
	return 0;	
	
}

unsigned char IsCurDir(unsigned char *strName)
{
	unsigned char i;
	for(i=0;i<3;i++){
		if(pgm_read_byte(hzk12[2]+i)!=strName[i]) break;
	}
	if(i==3)    return 1;  //是当前目录
	return 0;	
	
}
unsigned char IsMusicFile(unsigned char *strName)
{
	unsigned char i;
	for(i=0;i<3;i++){
		if(pgm_read_byte(filetype[MP3_TYPE]+i)!=strName[i]) break;
	}
	if(i==3)    return 1;  //是MP3文件
	for(i=0;i<3;i++){
		if(pgm_read_byte(filetype[WMA_TYPE]+i)!=strName[i]) break;
	}
	if(i==3)    return 2; //是WMA文件
/*
	for(i=0;i<3;i++){
		if(pgm_read_byte(filetype[MID_TYPE]+i)!=strName[i]) break;
	}
	if(i==3)    return 3; //是MIDI文件
*/
	return 0; 
}		
/*-----------------------------------------------------------------------
 在FAT表中查询下一个簇号
-----------------------------------------------------------------------*/
unsigned long fatNextCluster(unsigned long cluster)
{
	unsigned long nextCluster=0;
	unsigned long fatOffset;
	unsigned long sector;
	unsigned int offset;
	if(FatType==FAT32 )	// 一个表项为4bytes(32 bits)
	{
		fatOffset = cluster << 2;
		sector = FirstFATSector + (fatOffset / BytesPerSector);	//计算FAT扇区号
		offset = fatOffset % BytesPerSector; //计算FAT扇区号中表项的偏移地址
		nextCluster=SD_Read_Dword(sector,offset);
		//ReadBlock(sector);  // 读取下一个簇号	
		//nextCluster = (*((unsigned long*) &((char*)BUFFER)[offset])) ;
	}else if(FatType==FAT16){    // 一个表项为2bytes(16 bits)
		fatOffset = cluster << 1; 	//计算FAT扇区号
	  	sector = FirstFATSector + (fatOffset / BytesPerSector);
	  	offset = fatOffset % BytesPerSector;//计算FAT扇区号中表项的偏移地址
	  	nextCluster=SD_Read_Word(sector,offset);
//  	ReadBlock(sector);	
//		nextCluster = (*((unsigned int*) &((char*)BUFFER)[offset])) ;
	}else if(FatType==FAT12){	// 一个表项为1.5bytes(12 bits)
		fatOffset = cluster+(cluster>>1);
		sector = FirstFATSector + (fatOffset / BytesPerSector);
		offset = fatOffset % BytesPerSector;
//	ReadBlock(sector);
		if(offset==(BytesPerSector-1)){
			nextCluster=SD_Read_Word(sector,offset-1)>>8;
	//	nextCluster=(unsigned long)BUFFER[offset];	//低位
	//		ReadBlock(sector+1);
			nextCluster|=((SD_Read_Word(sector+1,0)<<8)&0x0000ffff);
//		nextCluster|=(BUFFER[0]<<8)&0x0000ffff;  //高位,必须与,否则会出现错误
		}else{
		nextCluster=SD_Read_Word(sector,offset);
//	  	nextCluster =(*((unsigned int*) &((char*)BUFFER)[offset])) ;
		}
		if(cluster&0X00000001){   //取低12位地址
		  	nextCluster>>=4;
		}else{  //取高12位地址
		  	nextCluster&=0x00000fff;
		}
	}
	// 是否文件的结束簇
	if (nextCluster >= (CLUST_EOFS & FAT_MASK))
	 nextCluster = CLUST_EOFE;
	return nextCluster;
} 
 
//在根目录中查找汉字库文件的首簇号及UNITCODE码转换表文件的首簇号---
// 
void GetSysFileClust(unsigned long *hzk,unsigned long *unit)
{
	DIRENTRY *de=0;	   
	FIND_FILE_INFO	fp;  

	InitSetPath(&fp,fatGetRootClust());
	ReadBlock(fp.Sector);     //重新读取目录表
	(*hzk)=(*unit)=0;
	do{
		if(!ReadNextDirEntry(&fp))  break;
		de = (DIRENTRY *)BUFFER;
		de+=fp.Index;
		if(*de->deName != 0xe5){
			if((de->deAttributes&ATTR_LONG_FILENAME)!=ATTR_LONG_FILENAME){
			if((de->deAttributes&ATTR_DIRECTORY)!= ATTR_DIRECTORY)// is it a directory ?
			if(*hzk==0){
				if(IsHzk12File(de->deName))
					*hzk= (unsigned long) ((unsigned long)de->deHighClust << 16) + de->deStartCluster;
			}
			if(*unit==0){
				if(IsUnitogbFile(de->deName))
				   *unit= (unsigned long) ((unsigned long)de->deHighClust << 16) + de->deStartCluster;	
		 	} 
		 	if((*hzk!=0)&&(*unit!=0))   break;
		  }
		}
		de++;
	    fp.Index++;
	 if(de->deName[0]==0)   break;
	}while (1);
}  
void InitSetPath(FIND_FILE_INFO *fp,unsigned long dircluster)
{
	fp->Nums=0x8000;      //高位为1表示不是FAT12&fat16的根目录
	fp->Clust=dircluster;
		if(dircluster==0x00000000){  //根目录区
			if(FatType==FAT32){
				    fp->Sector= fatClustToSect(RootDir.Clust);
					fp->Clust = RootDir.Clust;
				}else{
					fp->Sector = RootDir.Sector;   //得到目录区的扇区号
					fp->Nums = RootDirEnts;
				}                                  //此时根目录项数是确定大小的	
		}else{
				 fp->Sector=fatClustToSect(dircluster);
		}		
    fp->Index = 0;
	fp->NumSector=0;
}

//在当前的目录中查找歌词文件,找到置相关数据至lyric中
//入口: 1.dircluster    当前目录的首簇号,若是FAT12或FAT16的根目录则为0
void FindLrcFile(unsigned long dircluster,unsigned char *strName)
{
	FIND_FILE_INFO	fp;
	DIRENTRY *de=0;	

⌨️ 快捷键说明

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