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

📄 fat16.c

📁 用LPC2103(ARM7)操作SD卡代码。
💻 C
📖 第 1 页 / 共 3 页
字号:
/*************************************************************/
/*                   FAT16操作函数库                         */
/*  环境WinAVR 20060421                                      */
/*  作者:Bozai(章其波)                                    */
/*  E-mail:sudazqb@163.com                                  */
/*  2006年11月26日                                           */
/*************************************************************/

#include "FAT16.h"
#include "uart.h"
U16 FirstDataSector;	// The first sector number of data
U16 BytesPerSector;	// Bytes per sector
U16 FATsectors;		// The amount sector a FAT occupied
U16 SectorsPerClust;	// Sector per cluster
U16 FirstFATSector;	// The first FAT sector
U16 FirstDirSector;	// The first Dir sector
U16 RootDirSectors;	// The sector number a Root dir occupied 
U16 RootDirCount;		// The count of directory in root dir


U8 (* FAT16_ReadSector)(U32,U8 *);
U8 (* FAT16_WriteSector)(U32,U8 *);

//函数指针指向sd卡的读写函数
U8 (* FAT16_ReadSector)(U32 sector, U8 * buffer)=MMC_SD_ReadSingleBlock;//device read
U8 (* FAT16_WriteSector)(U32 sector, U8 * buffer)=MMC_SD_WriteSingleBlock;//device write

struct FileInfoStruct FileInfo;//temporarily buffer for file information

//FAT16初始化,不含SD的初始化,用之前应先调用sd的初始化
unsigned char FAT16_Init()//Initialize of FAT16
{
	struct bootsector50 *bs  = 0;
	struct bpb50        *bpb = 0;
	U16 hidsec;

	U8 buffer[512];
	//有的sd卡BPB不在0扇区
	for(hidsec=0;hidsec<0x1000;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==0x1000)return 1; //error maybe the card hasn't been formated
	bs = (struct bootsector50 *)buffer;
	if(bs->bsJump[0]!=0xE9 && bs->bsJump[0]!=0xEB)return 1;
	bpb = (struct bpb50 *)bs->bsBPB;
	BytesPerSector	= bpb->bpbBytesPerSec;//每扇区字节数
	FATsectors	= bpb->bpbFATsecs;//FAT占用的扇区数
	SectorsPerClust	= (U8)bpb->bpbSecPerClust;//每簇扇区数
	FirstFATSector	= bpb->bpbResSectors+hidsec;//第一个FAT表扇区
	RootDirCount	= bpb->bpbRootDirEnts;//根目录项数
	RootDirSectors	= (RootDirCount*32)>>9;//根目录占用的扇区数
	FirstDirSector	= FirstFATSector+bpb->bpbFATs*FATsectors;//第一个目录扇区
	FirstDataSector	= FirstDirSector+RootDirSectors;//第一个数据扇区
	return 0;
}

//读一个簇中的一个扇区
unsigned char FAT16_LoadPartCluster(U16 cluster,unsigned part,U8 * buffer)
{
	U32 sector;
	sector=FirstDataSector+(U32)(cluster-2)*(U32)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(U16 cluster,U8 * buffer)
{
	U32 sector;
	unsigned char i;
	sector=FirstDataSector+(U32)(cluster-2)*(U32)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
U16 FAT16_NextCluster(U16 cluster)
{
	U8 buffer[512];
	U32 sector;
	U32 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=((U16 *)buffer)[offset];
	return (U16)sector;//return the cluste number
}

//在FAT表内找空簇
//Find a free cluster return the cluster number
U16 FAT16_FindFreeCluster()
{
	U8 buffer[512];
	//U32 sector;
	U16 i;
	U16 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(((U16 *)buffer)[i]==0x0000)break;//an unused cluster
		}
		if(i!=256)
		{
			cnt=cnt*512+i;
			return cnt;//return the free cluster number
		}
	}
	return 1;//error
}

//在cluster指向的目录下找一个空位置记录文件
//find a position to place a item withe the given directory, the parameter is FileInfo who brought the message
U16 FAT16_FindFreeItem(U16 cluster, struct FileInfoStruct *FileInfo)
{
	U8 *buffer;
	U32 tempclust;
	U32 sector;
	unsigned char cnt;
	U16 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
		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;
}

//显示给定路径下的文件
//display the content of a foler , 0 as root directory
unsigned char FAT16_DisDir(U8 *dir)
{
	U8 *buffer;
	U32 sector;
	U16 cluster;
	U32 tempclust;
	unsigned char cnt;
	U16 offset;
	unsigned char i;
	struct direntry *item = 0;
	cluster = FAT16_OpenDir(dir);
	if(cluster == 1)return 1;
	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;}
			for(offset=0;offset<512;offset+=32)
			{
				item=(struct direntry *)(&buffer[offset]);//pointer convert
				//find a valid item and display it
				if((item->deName[0] != '.') & (item->deName[0] != 0x00) & (item->deName[0] != 0xe5) & (item->deAttributes != 0x0f))
				{
					USART_putchar(0x0d);
					USART_putchar(0x0a);
					for(i=0;i<8;i++)//name
					{
						USART_putchar(item->deName[i]);	
					}
					if((item->deAttributes & 0x10)==0)USART_putchar('.');
					for(i=0;i<3;i++)//extention
					{
						USART_putchar(item->deExtension[i]);
					}
				}
			}
		}
		free(buffer);//release
	}
	else//other folders
	{
		tempclust=cluster;
		while(1)
		{
			sector=FirstDataSector+(U32)(tempclust-2)*(U32)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] != '.') & (item->deName[0] != 0x00) & (item->deName[0] != 0xe5) & (item->deAttributes != 0x0f))
					{
						USART_putchar(0x0d);
						USART_putchar(0x0a);
						for(i=0;i<8;i++)
						{
							USART_putchar(item->deName[i]);	
						}
						if((item->deAttributes & 0x10)==0)USART_putchar('.');
						for(i=0;i<3;i++)
						{
							USART_putchar(item->deExtension[i]);
						}
					}
				}
			}
			free(buffer);//release
			tempclust=FAT16_NextCluster(tempclust);//next cluster
			if(tempclust == 0xffff)break;
		}
	}
	return 0;
}

//在给定目录下查找文件
//Find a item in the directory which specify by the parameter "cluster"
//Return the start cluster number
U16 FAT16_FindItem(U16 cluster, U8 *name, struct FileInfoStruct *FileInfo)
{
	U8 *buffer;
	U32 tempclust;
	U32 sector;
	unsigned char cnt;
	U16 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
		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;
						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+(U32)(tempclust-2)*(U32)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;
}

//挑选一个未使用的记录项
//select the first unsed item in the given cluster
//for delete a foler or a file
unsigned char FAT16_SelectOneItem(U16 cluster,struct FileInfoStruct *FileInfo)
{
	U8 *buffer;
	U32 tempclust;
	U32 sector;
	unsigned char cnt;
	U16 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
		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))
				{
					//return the parameter of the item
					FileInfo->StartCluster = item->deStartCluster;
					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

⌨️ 快捷键说明

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