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

📄 fat16.c

📁 FAT32文件系统的存储机制及其在单片机上的实现,已通过
💻 C
📖 第 1 页 / 共 3 页
字号:
#include "uart.h"
#include "sd.h"

#include "FAT16.h"

unsigned int FirstDataSector;	// The first sector number of data
unsigned int BytesPerSector;	// unsigned chars per sector
unsigned int FATsectors;		// The amount sector a FAT occupied
unsigned int SectorsPerClust;	// Sector per cluster
unsigned int FirstFATSector;	// The first FAT sector
unsigned int FirstDirSector;	// The first Dir sector
unsigned int RootDirSectors;	// The sector number a Root dir occupied 
unsigned int RootDirCount;		// The count of directory in root dir
struct FileInfoStruct FileInfo;//temporarily buffer for file information
unsigned char xdata buffer[512];

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*=256;
 }
 return temp;
}

unsigned char FAT16_ReadSector(unsigned long lba,unsigned char *buf)
{
 MMC_get_data_LBA(lba,512,buf);
 return 0;
}

unsigned char FAT16_WriteSector(unsigned long lba,unsigned char *buf)
{
 return MMC_write_sector(lba,buf);
}

//unsigned char (* FAT16_ReadSector)(unsigned long,unsigned char *);
//unsigned char (* FAT16_WriteSector)(unsigned long,unsigned char *);

//unsigned char (* FAT16_ReadSector)(unsigned long sector, unsigned char * buffer)=MMC_SD_ReadSingleBlock;//device read
//unsigned char (* FAT16_WriteSector)(unsigned long sector, unsigned char * buffer)=MMC_SD_WriteSingleBlock;//device write





void free(unsigned char *b)
{
 unsigned int i=0;
 for(i=0;i<512;i++)
 { 
  b[i]=0;
 }
}

unsigned char FAT16_Init()//Initialize of FAT16
{
	struct bootsector50 *bs;
	struct bpb50        *bpb;
	unsigned int hidsec;
	
	for(hidsec=100;hidsec<200;hidsec++)//Some card the BPB is not locat at secter 0
	{
		if(FAT16_ReadSector(hidsec,buffer))
		 return 1;
		if(buffer[0]==0xeb || buffer[0]==0xe9) 
		 break;
	}
	if(hidsec==200)
	 return 1; //error maybe the card hasn't been formated
	bs=(struct bootsector50 *)buffer;
	bs->bsOemName[7]=0;
	send_s(bs->bsOemName);
	if(bs->bsJump[0]!=0xE9 && bs->bsJump[0]!=0xEB)
	 return 1;
	bpb=(struct bpb50 *)bs->bsBPB;
	BytesPerSector  =lb2bb((unsigned char *)(&(bpb->bpbBytesPerSec)),2);
	Printf("BytesPerSector",BytesPerSector);
	FATsectors		= lb2bb((unsigned char *)(&(bpb->bpbFATsecs)),2);
	Printf("FATsectors=",FATsectors);
	SectorsPerClust	= (unsigned char)bpb->bpbSecPerClust;
	Printf("SectorsPerClust=",SectorsPerClust);
	FirstFATSector	= lb2bb((unsigned char *)(&(bpb->bpbResSectors)),2)+hidsec;
	Printf("FirstFATSector=",FirstFATSector);
	RootDirCount	= lb2bb((unsigned char *)(&(bpb->bpbRootDirEnts)),2);
	Printf("RootDirCount=",RootDirCount);
	RootDirSectors	= (RootDirCount*32)>>9;
	Printf("RootDirSectors=",RootDirSectors);
	FirstDirSector	= FirstFATSector+bpb->bpbFATs*FATsectors;
	Printf("FirstDirSector=",FirstDirSector);
	FirstDataSector	= FirstDirSector+RootDirSectors;
	Printf("FirstDataSector=",FirstDataSector);
	return 0;
}


unsigned char FAT16_LoadPartCluster(unsigned int cluster,unsigned long part,unsigned char * buffer)
{
	unsigned long sector;
	sector=FirstDataSector+(unsigned long)(cluster-2)*(unsigned long)SectorsPerClust;//calculate the actual sector number
	if(FAT16_ReadSector(sector+part,buffer))
	 return 1;
	else 
	 return 0;
}
//Read the a cluster
//Not suitable for system which has few data RAM  
unsigned char FAT16_LoadCluster(unsigned int cluster,unsigned char * buffer)
{
	unsigned long sector;
	unsigned char i;
	sector=FirstDataSector+(unsigned long)(cluster-2)*(unsigned long)SectorsPerClust;//calculate the actual sector number
	for(i=0;i<SectorsPerClust;i++)
	{
		if(FAT16_ReadSector(sector+i,buffer+(i<<9)))
		 break;
	}
	if(i==SectorsPerClust)
	 return 0;
	else 
	 return 1;
}

//Return the cluster number of next cluster of file
//Suitable for system which has limited RAM
unsigned int FAT16_NextCluster(unsigned int cluster)
{
	//unsigned char buffer[512];
	unsigned long sector;
	unsigned long offset=cluster/256;
	if(cluster<2)return 0xfff8;
	sector=FirstFATSector+offset;//calculate the actual sector
	if(FAT16_ReadSector(sector,buffer))return 0xfff8;//read fat table / return 0xfff8 when error occured

	offset=cluster%256;//find the position
	//offset<<=1;
	//sector=buffer[offset+1];
//	sector<<=8;
	//sector+=buffer[offset];
	sector=((unsigned int *)buffer)[offset];
	return (unsigned int)sector;//return the cluste number
}

//Find a free cluster return the cluster number
unsigned int FAT16_FindFreeCluster()
{
	//unsigned char buffer[512];
	//unsigned long sector;
	unsigned int i;
	unsigned int cnt;
//	sector=FirstFATSector+offset;//calculate the actual sector
	//sector=FirstFATSector;
	for(cnt=0;cnt<FATsectors;cnt++)//find in the FAT table
	{
		if(FAT16_ReadSector(FirstFATSector+cnt,buffer))
		 return 1;//error
		for(i=0;i<256;i++)
		{
			if(((unsigned int *)buffer)[i]==0x0000)
			 break;//an unused cluster
		}
		if(i!=256)
		{
			cnt=cnt*512+i;
			return cnt;//return the free cluster number
		}
	}
	return 1;//error
}

//find a position to place a item withe the given directory, the parameter is FileInfo who brought the message
unsigned int FAT16_FindFreeItem(unsigned int cluster, struct FileInfoStruct *FileInfo)
{
	//unsigned char *buffer;
	unsigned long tempclust;
	unsigned long sector;
	unsigned char cnt;
	unsigned int offset;
//	unsigned char i;
	struct direntry *item;
	if(cluster==0)// root directory
	{
		//buffer=malloc(512);//apply memory
		//if(buffer==0)return 1;//if failed
		for(cnt=0;cnt<RootDirSectors;cnt++)
		{
			if(FAT16_ReadSector(FirstDirSector+cnt,buffer))
			 {
			  free(buffer);
			  return 1;
			 }//read sector
			for(offset=0;offset<512;offset+=32)
			{
				item=(struct direntry *)(&buffer[offset]);
				//used item
				if((item->deName[0] != 0x00) & (item->deName[0] != 0xe5) & (item->deAttributes != 0x0f));
				//unused item
				else
				{

					FileInfo->StartCluster = item->deStartCluster;//don't care
					FileInfo->Size         = item->deFileSize;//don't care
					FileInfo->Attr         = item->deAttributes;//don't care
					FileInfo->Sector       = FirstDirSector+cnt;//The key parameter record the secoter nuber which the item stored
					FileInfo->Offset       = offset;			//The key parameter record the offset in the sector
					free(buffer);//realease
					return 0;//done
				}
			}
		}
		free(buffer);//release
	}
	else//other folders
	{
		tempclust=cluster;
		while(1)
		{
			sector=FirstDataSector+(tempclust-2)*SectorsPerClust;//calculate the actual sector number
			//buffer=malloc(512);//apply memory
			//if(buffer==0)return 1;//if failed
			for(cnt=0;cnt<SectorsPerClust;cnt++)
			{
				if(FAT16_ReadSector(sector+cnt,buffer))
				 {
				  free(buffer);
				  return 1;
				 }
				for(offset=0;offset<512;offset+=32)
				{
					item=(struct direntry *)(&buffer[offset]);
					if((item->deName[0] != 0x2e) & (item->deName[0] != 0x00) & (item->deName[0] != 0xe5) & (item->deAttributes != 0x0f));
					else
					{
						FileInfo->StartCluster = item->deStartCluster;
						FileInfo->Size         = item->deFileSize;
						FileInfo->Attr         = item->deAttributes;
						FileInfo->Sector       = sector+cnt;
						FileInfo->Offset       = offset;
						free(buffer);
						return 0;
					}
				}
			}
			free(buffer);//release
			tempclust=FAT16_NextCluster(tempclust);//next cluster
			if(tempclust == 0xffff || tempclust == 0xfff8)
			 return 1;
		}
	}
	return 1;
}

//Find a item in the directory which specify by the parameter "cluster"
//Return the start cluster number
unsigned int FAT16_FindItem(unsigned int cluster, unsigned char *name, struct FileInfoStruct *FileInfo)
{
	//unsigned char *buffer;
	unsigned long tempclust;
	unsigned long sector;
	unsigned char cnt;
	unsigned int offset;
	unsigned char i;
	struct direntry *item = 0;
	if(cluster==0)// root directory
	{
		//buffer=malloc(512);//apply memory
		//if(buffer==0)return 1;//if failed
		Printf("enter the fat16_finditem  file name is ",0);
		Printf(name,0);
		for(cnt=0;cnt<RootDirSectors;cnt++)
		{
			if(FAT16_ReadSector(FirstDirSector+cnt,buffer)){free(buffer);return 1;}
			for(offset=0;offset<512;offset+=32)
			{
				item=(struct direntry *)(&buffer[offset]);
				if((item->deName[0] != 0x00) & (item->deName[0] != 0xe5) & (item->deAttributes != 0x0f))
				{
					for(i=0;i<11;i++)
					{
						if(buffer[offset+i]!=name[i])
						 break;
					}
					if(i==11)
					{
						//return the parameter of the item
						FileInfo->StartCluster = item->deStartCluster;
						Printf("StartCluster",FileInfo->StartCluster);
						FileInfo->Size         = item->deFileSize;
						FileInfo->Attr         = item->deAttributes;
						FileInfo->Sector       = FirstDirSector+cnt;
						FileInfo->Offset       = offset;
						free(buffer);
						return 0;
					}
				}
			}
		}
		free(buffer);//release
	}
	else//other folders
	{
		tempclust=cluster;
		while(1)
		{
			sector=FirstDataSector+(unsigned long)(tempclust-2)*(unsigned long)SectorsPerClust;//calculate the actual sector number
			//buffer=malloc(512);//apply memory
			//if(buffer==0)return 1;//if failed
			for(cnt=0;cnt<SectorsPerClust;cnt++)
			{
				if(FAT16_ReadSector(sector+cnt,buffer))
				 {
				  free(buffer);
				  return 1;
				 }
				for(offset=0;offset<512;offset+=32)
				{
					item=(struct direntry *)(&buffer[offset]);
					if((item->deName[0] != 0x00) & (item->deName[0] != 0xe5) & (item->deAttributes != 0x0f))
					{
						for(i=0;i<11;i++)
						{
							if(buffer[offset+i]!=name[i])
							 break;
						}
						if(i==11)
						{
							FileInfo->StartCluster = item->deStartCluster;
							FileInfo->Size         = item->deFileSize;
							FileInfo->Attr         = item->deAttributes;
							FileInfo->Sector       = sector+cnt;
							FileInfo->Offset       = offset;
							free(buffer);
							return 0;
						}
					}
				}
			}
			free(buffer);//release
			tempclust=FAT16_NextCluster(tempclust);//next cluster
			if(tempclust == 0xffff || tempclust == 0xfff8)break;
		}
	}
	return 1;
}

// find the location with the given path
unsigned int FAT16_Open(unsigned char * dir)
{
	unsigned char name[13];
	unsigned char *p=dir;
	unsigned char deep=0;
	unsigned char i,j;
	unsigned long cluster=0;
	Printf("Fat16 open!!",0);
	if(*p != '\\')return 1;//invalid path
	while(*p)
	{
		if(*p == '\\')
		{
			deep++;		
		}
		p++;
	}
	p=dir;
	for(i=0;i<deep-1;i++)
	{
		p++;
		for(j=0;j<11;j++)name[j]=0x20;
		j=0;
		while(*p != '\\')
		{
			if((*p) >= 'a' && (*p) <= 'z')name[j] = (*p++)-0x20;
			else name[j] = *p++;
			j++;
		}
		name[j]=0;
		Printf(name,0);
		if(FAT16_FindItem(cluster,name, &FileInfo))
		 return 1;//find the directory
		cluster = FileInfo.StartCluster;
	}
	p++;
	for(j=0;j<11;j++)name[j]=0x20;
	j=0;
	while(*p != '.')//file must have a extention
	{
		if(*p>='a' && *p<='z')name[j]=(*p++)-0x20;
		else name[j]=*p++;
		j++;
	}
	j=8;
	p++;
	while(*p)
	{
		if(*p>='a' && *p<='z')name[j]=(*p++)-0x20;
		else name[j]=*p++;
		j++;
	}
	if(FAT16_FindItem(cluster,name, &FileInfo))
	 return 1;//find the file
	cluster = FileInfo.StartCluster;
	return cluster;
}

// find a directory with the given path
unsigned int FAT16_OpenDir(unsigned char * dir)
{
	unsigned char name[11];
	unsigned char *p=dir;
	unsigned char deep=0;
	unsigned char i,j;
	unsigned long cluster=0;
	if(*p != '\\')
	{
	 return 1;//invalid path
	 }
    Printf("FAT 16 OPENDIR ,it is valid path!!",0);
	while(*p)
	{
		if(*p == '\\')
		{
			deep++;
		}
		p++;
	}
	p=dir;
	for(i=0;i<deep-1;i++)
	{
		p++;
		for(j=0;j<11;j++)name[j]=0x20;
		j=0;
		while(*p != '\\')
		{
			if((*p) >= 'a' && (*p) <= 'z')name[j] = (*p++)-0x20;
			else name[j] = *p++;
			j++;
		}
		if(FAT16_FindItem(cluster,name, &FileInfo))
		 return 1;//find the directory
		cluster = FileInfo.StartCluster;
	}
	p++;
	for(j=0;j<11;j++)name[j]=0x20;
	j=0;
	while(*p)
	{
		if(*p>='a' && *p<='z')name[j]=(*p++)-0x20;
		else name[j]=*p++;
		j++;
	}
	if(j == 0)return 0;
	if(FAT16_FindItem(cluster,name, &FileInfo))
	 return 1;//find the final directory
	cluster = FileInfo.StartCluster;
	return cluster;

⌨️ 快捷键说明

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