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

📄 fat16.c

📁 用LPC2103(ARM7)操作SD卡代码。
💻 C
📖 第 1 页 / 共 3 页
字号:
	{
		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] != 0x2e) & (item->deName[0] != 0x00) & (item->deName[0] != 0xe5) & (item->deAttributes != 0x0f))
					{
						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;
}

//修改FAT表中响应的项
//modify the fat table item with "val","cluster" specify the location
unsigned char FAT16_ModifyFAT(U16 cluster,U16 val)
{
	U8 buffer[512];
	U32 sector;
	U32 offset=cluster/256;

	sector=FirstFATSector+offset;//calculate the actual sector
	if(FAT16_ReadSector(sector,buffer))return 1;//read fat table

	offset=cluster%256;//find the position
	offset<<=1;
	//sector=buffer[offset+1];
//	sector<<=8;
	//sector+=buffer[offset];
	buffer[offset+1] = val>>8;
	buffer[offset]   = val;
	if(FAT16_WriteSector(sector,buffer))return 1;//write the first fat table
	if(FAT16_WriteSector(sector+FATsectors,buffer))return 1;//write the second fat table
	return 0;//return the value
}

// make a dir
unsigned char FAT16_MkDir(U8 * dir)
{
	U8 name[11];
	U8 *p=dir;
	U8 deep=0;
	U16 i,j;
	U32 cluster=0;
	U32 lastcluster;//cluster number of last directory
	U8 *buffer;
	U16 sector;
	struct direntry *item;
	if(*p != '\\')return 1;//invalid path
	while(*p)
	{
		if(*p == '\\')
		{
			deep++;//the deepth of the path
		}
		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 location of each directory
		cluster = FileInfo.StartCluster;//point to next directory
	}
	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++;
	}
	lastcluster=cluster;//save as last directory
	cluster=FAT16_FindFreeCluster();//find a unused cluster
	if(cluster==1)return 1;//error
	if(FAT16_FindFreeItem(lastcluster,&FileInfo))return 1;//find a unused item
	buffer=malloc(512);
	if(buffer==0)return 1;
	if(FAT16_ReadSector(FileInfo.Sector,buffer)){free(buffer);return 1;}//read the sector which the item is in
	item=(struct direntry *)(&buffer[FileInfo.Offset]);//pointer convert

	for(j=0;j<8;j++)item->deName[j] = name[j];
	for(j=0;j<3;j++)item->deExtension[j] = 0x20;
	item->deAttributes = ATTR_DIRECTORY;
	item->deLowerCase = LCASE_BASE | LCASE_EXT;
	item->deCHundredth = 0;
	item->deCTime[0] = 0;
	item->deCTime[1] = 0;
	item->deCDate[0] = 0;
	item->deCDate[1] = 0;
	item->deADate[0] = 0;
	item->deADate[1] = 0;
	item->deHighClust = 0;
	item->deMTime[0] = 0;
	item->deMTime[1] = 0;
	item->deMDate[0] = 0;
	item->deMDate[1] = 0;
	item->deStartCluster = cluster;
	item->deFileSize = 0;
	if(FAT16_WriteSector(FileInfo.Sector,buffer)){free(buffer);return 1;}//write the item

	for(j=0;j<512;j++)buffer[j]=0x00;
	sector=FirstDataSector+(U32)(cluster-2)*(U32)SectorsPerClust;
	for(i=0;i<SectorsPerClust;i++)
	{
		if(FAT16_WriteSector(sector+i,buffer)){free(buffer);return 1;}//clear the data in the directory
	}

	//create "." directory
	item=(struct direntry *)(&buffer[0]);
	item->deName[0] = '.';
	for(j=1;j<8;j++)item->deName[j] = 0x20;
	for(j=0;j<3;j++)item->deExtension[j] = 0x20;
	item->deAttributes = ATTR_DIRECTORY;
	item->deLowerCase = LCASE_BASE | LCASE_EXT;
	item->deCHundredth = 0;
	item->deCTime[0] = 0;
	item->deCTime[1] = 0;
	item->deCDate[0] = 0;
	item->deCDate[1] = 0;
	item->deADate[0] = 0;
	item->deADate[1] = 0;
	item->deHighClust = 0;
	item->deMTime[0] = 0;
	item->deMTime[1] = 0;
	item->deMDate[0] = 0;
	item->deMDate[1] = 0;
	item->deStartCluster = cluster;//the directory itself
	item->deFileSize = 0;

	//creat ".." directory
	item=(struct direntry *)(&buffer[32]);
	item->deName[0] = '.';
	item->deName[1] = '.';
	for(j=2;j<8;j++)item->deName[j] = 0x20;
	for(j=0;j<3;j++)item->deExtension[j] = 0x20;//no extention
	item->deAttributes = ATTR_DIRECTORY;//directory
	item->deLowerCase = LCASE_BASE | LCASE_EXT;
	item->deCHundredth = 0;
	item->deCTime[0] = 0;
	item->deCTime[1] = 0;
	item->deCDate[0] = 0;
	item->deCDate[1] = 0;
	item->deADate[0] = 0;
	item->deADate[1] = 0;
	item->deHighClust = 0;
	item->deMTime[0] = 0;
	item->deMTime[1] = 0;
	item->deMDate[0] = 0;
	item->deMDate[1] = 0;
	item->deStartCluster = lastcluster;//last directory
	item->deFileSize = 0;

	if(FAT16_WriteSector(sector,buffer)){free(buffer);return 1;}//write the data
	free(buffer);
	if(FAT16_ModifyFAT(cluster,0xffff))return 1;//modify the fat table to sign that the cluster was used 
	return 0;//done
}

// remove a directory
unsigned char FAT16_RmDir(U8 * dir)
{
	if(FAT16_OpenDir(dir)==0)return 1;//find the directory
	if(FAT16_DelItem(&FileInfo))return 1;//delete it
	return 0;
}

// creat a file, for convenience we designate the size
// return the start sector of the new file
U16 FAT16_Create(U8 * dir,U32 size)
{
	U8 name[11];
	U8 *p=dir;
	U8 deep=0;
	U8 i,j;
	U32 cluster=0;
	U8 *buffer;
	//U16 sector;
	struct direntry *item;
	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++;
		}
		if(FAT16_FindItem(cluster,name, &FileInfo))return 1;
		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++;
	}
	j=8;
	p++;
	while(*p)
	{
		if(*p>='a' && *p<='z')name[j]=(*p++)-0x20;
		else name[j]=*p++;
		j++;
	}


	if(FAT16_FindFreeItem(cluster,&FileInfo))return 1;
	cluster = FAT16_FindFreeCluster();
	if(cluster==1)return 1;
	buffer=malloc(512);
	if(buffer==0)return 1;
	if(FAT16_ReadSector(FileInfo.Sector,buffer)){free(buffer);return 1;}
	item=(struct direntry *)(&buffer[FileInfo.Offset]);

	for(j=0;j<8;j++)item->deName[j] = name[j];
	for(j=0;j<3;j++)item->deExtension[j] = name[8+j];
	item->deAttributes = ATTR_ARCHIVE;//file
	item->deLowerCase = LCASE_BASE | LCASE_EXT;
	item->deCHundredth = 0;
	item->deCTime[0] = 0;
	item->deCTime[1] = 0;
	item->deCDate[0] = 0;
	item->deCDate[1] = 0;
	item->deADate[0] = 0;
	item->deADate[1] = 0;
	item->deHighClust = 0;
	item->deMTime[0] = 0;
	item->deMTime[1] = 0;
	item->deMDate[0] = 0;
	item->deMDate[1] = 0;
	item->deStartCluster = cluster;//the cluster number the file was stored
	item->deFileSize = size;//the file size
	if(FAT16_WriteSector(FileInfo.Sector,buffer)){free(buffer);return 1;}//write the item
	free(buffer);
	if(FAT16_ModifyFAT(cluster,0xffff))return 1;//modify the fat table
	return cluster;//reutn the first cluster number
}

// find the location with the given path
U16 FAT16_Open(U8 * dir)
{
	U8 name[11];
	U8 *p=dir;
	U8 deep=0;
	U8 i,j;
	U32 cluster=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++;
		}
		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
U16 FAT16_OpenDir(U8 * dir)
{
	U8 name[11];
	U8 *p=dir;
	U8 deep=0;
	U8 i,j;
	U32 cluster=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++;
		}
		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;
}

U16 FAT16_Close(U16 * p)
{
	*p=1;
	return 0;
}

// Output the data of a file
// size 0 means read all of the file
unsigned char FAT16_Read(U16 pointer, U32 size)
{
	U32 sector;
	U32 tempclust=pointer;
	U8 *buffer;
	U16 i=0,j=0;
	sector=FirstDataSector+(U32)(tempclust-2)*(U32)SectorsPerClust;
	if(size==0)size = FileInfo.Size;//whether need to read all
	USART_putchar(0x0d);
	USART_putchar(0x0a);//new line
	while(size)
	{
		buffer=malloc(512);
		if(FAT16_ReadSector(sector+j,buffer)){free(buffer);return 1;}
		if(size<=512)
		{

⌨️ 快捷键说明

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